INF1010 Binære søketrær ++ Programeksempler med insetting, gjenfinning av noder i et binært søketre samt eksempler på hvordan lage en liste av et binærtre.
Hva må du kunne om binære søketrær i INF1010 Lage programmer som 1. bygger opp et binært søketre (sette inn objekter) 2. finner igjen et objekt i et binært søketre 3. traverserer hele treet (f.eks. skriver ut alle objektene) 4. gjør om et binært søketre til en sortert liste 5. gjør om en usortert liste til et binært søketre (samme som 1.) Du skal også kunne gjøre rede for tilstandspåstandene som ligger til grunn for at en datastruktur skal være et binært søketre. Vil du vite mer om binære søketrær, kan denne wikipediaartikkelen være et greit utgangspunkt: http://en.wikipedia.org/wiki/binary_search_tree michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 2
Tilstandspåstander et binært søketre (BST) består av 0 til n knuter (noder) For alle knuter i et BST gjelder: en knute har en konstant verdi og en compareto-metode som er veldefinert når knuten sammenlignes med andre knuter en knute har pekere til to BST (subtrær), v og h. alle knutene i venstre subtre (hvis ikke tomt) har verdier som er mindre enn eller lik knutens verdi basert på returverdien til knutens compareto-metode. alle knutene i høyre subtre har verdier som er større enn eller lik knutens verdi basert på returverdien til knutens compareto-metode. michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 3
Programeksempel klassestruktur interface BTNodeRolle <T>{ int compareto(t e ) ; void skrivut ( ) ; } class Node <T extends BTNodeRolle <T>> { Node<T> venstre, høyre ; T denne; Node (T t ) { denne = t ; } } void leggtiltre (Node <T> inn ) Node<T> finnidenneellerunder (Node <T> likdenne ) void skrivut ( ) michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 4
class Ord implements BTNodeRolle <Ord> { private String ordet ; Ord ( String s ) { ordet = s ; } } public int compareto( Ord o) public void skrivut ( ) public class Eksempel1 { public static void main( String [ ] args ) { Node<Ord> = new Node<Ord> (new Ord( ) ) ; } michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 5
Klassen Ord class Ord implements BTNodeRolle <Ord> { private String ordet ; Ord ( String s ) { ordet = s ; } public int compareto( Ord o ) { return ordet. comparetoignorecase ( o. ordet ) ; } } public void skrivut ( ) { System. out. print ( ordet+" " ) ; } michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 6
Klassen Node<T> class Node <T extends BTNodeRolle <T>> { Node<T> venstre, høyre ; T denne; Node (T t ) { denne = t ; } } void leggtiltre (Node <T> inn ) Node<T> finnidenneellerunder (Node <T> likdenne ) void skrivut ( ) michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 7
Et Node<Ord>-objekt Tilstand i programmet etter setningen Node<Ord> = new Node<Ord> (new Ord( )); void leggtiltre(node<ord> inn) Node<Ord> finnidenneellerunder(node<ord> likdenne) Node<Ord> void skrivut() Sterkt forenklet: Node<Ord> venstre Ord denne Node<Ord> høyre int compareto(ord o) void skrivut() String ordet Konstruktører: Ord (String s) {ordet = s;} Node (T t) {denne = t;} michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 8
Fra main-metoden Node<Ord> = new Node<Ord> (new Ord( " " ) ) ;. leggtiltre (new Node<Ord> (new Ord( "" ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ;. leggtiltre (new Node<Ord> (new Ord( " " ) ) ) ; michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 9
Settinnmetoden i Node<T> void leggtiltre (Node <T> inn ) { int smnlgn = denne. compareto( inn. denne ) ; i f ( smnlgn < 0 ) i f ( høyre == null ) høyre = inn ; else høyre. leggtiltre ( inn ) ; else i f ( venstre == null ) venstre = inn ; else venstre. leggtiltre ( inn ) ; } michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 10
Datastruktur ved kall på settinn-metoden (over) og resultat (under) Node<Ord> michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 11
void leggtiltre (Node <T> inn ) { int smnlgn = denne. compareto( inn. denne ) ; i f ( smnlgn < 0 ) i f ( høyre == null ) høyre = inn ; else høyre. leggtiltre ( inn ) ; else i f ( venstre == null ) venstre = inn ; else venstre. leggtiltre ( inn ) ; } michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 12
void leggtiltre (Node <T> inn ) { int smnlgn = denne. compareto( inn. denne ) ; i f ( smnlgn < 0 ) i f ( høyre == null ) høyre = inn ; else høyre. leggtiltre ( inn ) ; else i f ( venstre == null ) venstre = inn ; else venstre. leggtiltre ( inn ) ; } michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 13
void leggtiltre (Node <T> inn ) { int smnlgn = denne. compareto( inn. denne ) ; i f ( smnlgn < 0 ) i f ( høyre == null ) høyre = inn ; else høyre. leggtiltre ( inn ) ; else i f ( venstre == null ) venstre = inn ; else venstre. leggtiltre ( inn ) ; } michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 14
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 15
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 16
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 17
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 18
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 19
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 20
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 21
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 22
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 23
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 24
Finnmetoden i Node<T> Node<T> finnidenneellerunder (Node <T> likdenne ) { Node<T> fantdette ; int smnlgn = denne. compareto( likdenne. denne ) ; i f ( smnlgn < 0 ) i f ( høyre == null ) fantdette = null ; else fantdette = høyre. finnidenneellerunder ( likdenne ) ; else i f ( smnlgn > 0 ) i f ( venstre == null ) fantdette = null ; else fantdette = venstre. finnidenneellerunder ( likdenne ) ; else // smnlgn == 0, dvs. dette er noden det l e t e s etter fantdette = this ; } return fantdette ; michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 25
Node<Ord> funnet =. finnidenneellerunder (new Node<Ord> (new Ord( " " ) ) ) ; michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 26
funnet. skrivut ( ) ; michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 27
Skrivutmetoden i Node<T> void skrivut ( ) { i f ( venstre!= null ) venstre. skrivut ( ) ; denne. skrivut ( ) ; i f ( høyre!= null ) høyre. skrivut ( ) ; } NB! Rekkefølgen på skrivut-kallene vil forandre rekkefølgen. Metoden som er vist skriver ut objektene i alfabetisk stigende rekkefølge. Hvorfor? michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 28
Fra binærtre til liste Node<Ord> Liste er en enklere struktur å lage en iterator over. michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 29
michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 30
Node<Ord> liste michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 31
Et objekt av klassen Tre<Ord> Svarte nodeobjekter er av den indre klassen Node i Tre Et objekt av klassen Liste<Ord> Grønne objekter er av klassen Ord Røde nodeobjekter er objekter av den indre nodeklassen i Liste michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 32
Oppgaver 1. Snu ulikhetstegnet i settinnmetoden. Hva blir resultatet? Gjør endringer i skrivut, slik at ordningen fortsatt blir alfabetisk. 2. Gjør endringer i innsettingsrekkefølgen. Får dette konsekvenser for utkriften? 3. Hvor mange forskjellige utskrifter kan vi få ved å endre rekkefølgen på de tre skrivkallene i skrivut? 4. Gjør endringer i klassestrukturen, ved å innføre en ny klasse BTre med metodene som manipulerer treet. La Node være en indre klasse uten metoder, men med pekere. (Vanskelig). 5. Hvor mange forskjellige rekkefølger kan vi sette inn de ti ordene i eksemplet og få det samme treet? 6. Hvor mange forskjellige trær kan vi få ved å endre innsettingsrekkefølgen? michael@ifi.uio.no INF1010 3. mai 2012 (uke 18) 33