Godkjent oblig 1? Les e-post til din UiO-adresse Svar på e-post fra lablærer Ingen godkjenning før avholdt møte med lablærer Godkjentlistene brukes ikke til å informere om status for obligene Ta vare på all e-post om obliger
Dagens forelesning Eks 1: Binærtre Motivasjon for eksemplet Klassestruktur Java datastruktur Binærtretraversering Gjøre noe i hele treet = kalle på samme metode i alle objekten Eks 2: Binærtre og stakk Idé Java datastruktur Klassestruktur
Motivasjon for eksemplet I det følgende eksempel, er motivet å vise et eksempel på bruk av grenesnitt, subklasser, abstrakte klasser og generiske typer i en pekerkjedestruktur, et binærtre. Eksemplet må av pedagogiske grunner være kort, og vil framstå som unødig «overlesset». Hovedideen er å bruke grensnitt og subklasser for å skille ut det som har med binærtrestrukturen å gjøre. Generisk type brukes for å definere selve binærtreet, slik at det kan brukes på alle objekter som har de rette strukturelementene (kan spille rollen «inngå i et binærtre»).
Klassestruktur Et grensesnitt som beskriver rollen BTelemRolle En (abstrakt) klasse BTelem som implementer BTelemRolle En klasse som utvider BTelem og beskriver objektene (personene) En generisk klasse BTre som kan lage binære trær av objekter som er subklasser av BTelem (og indirekte implementerer BTelemRolle)
Klassestruktur Klassestruktur 1 interface BTelemRolle {... } 2 abstract class BTelem implements BTelemRolle {... } 3 class INF1010Person extends BTelem {... } 4 class BTre <T extends BTelem> {... } 5 class GBTeksempel { 6 public static void main( String [ ] args ) { 7 BTre <INF1010Person> INF1010PersonTre = 8 new BTre <INF1010Person >(); 9 } 10 }
Klassestruktur Rollen binærtreelement 1 interface BTelemRolle { 2 public Object hentvsubtrepeker ( ) ; 3 public Object henthsubtrepeker ( ) ; 4 public void setthsubtrepeker( Object o ) ; 5 public void settvsubtrepeker ( Object o ) ; 6 public void leggtilbtre ( Object o ) ; 7 }
Klassestruktur Klassen som beskriver et objekt som kan spille binærtreelementrollen 1 abstract class BTelem implements BTelemRolle { 2 private BTelem venstre, høyre ; 3 abstract int sammenlign( Object o ) ; 4 abstract void skrivut ( ) ; 5 public BTelem hentvsubtrepeker ( ) { return venstre ; } 6 public BTelem henthsubtrepeker ( ) { return høyre ; } 7 public void setthsubtrepeker( Object o) { høyre = ( BTelem) o; } 8 public void settvsubtrepeker ( Object o) { venstre = ( BTelem) o; 9 public void leggtilbtre ( Object inn ) {... } 10 }
Klassestruktur Klassen som beskriver objektene som skal inn i treet 1 class INF1010Person extends BTelem { 2 private String navn; 3 INF1010Person ( String n) { navn = n; } 4 int sammenlign( Object bte ) { 5 return navn.comparetoignorecase ( ( ( INF1010Person ) bte ).navn 6 } 7 String hentnavn ( ) { return navn; } 8 void skrivut ( ) { } 9 }
Java datastruktur BTelem hentvsubtrepeker BTelem henthsubtrepeker void settvsubtrepeker void setthsubtrepeker void leggtilbtre venstre BTelem INF1010Person høyre BTelem void skrivut String hentnavn int sammenlign navn Et INF1010Personobjekt String
Java datastruktur navn String INF1010Person void skrivut String hentnavn int sammenlign BTelem hentvsubtrepeker BTelem henthsubtrepeker void settvsubtrepeker void setthsubtrepeker void leggtilbtre Vi flytter litt på innholdet venstre BTelem høyre BTelem
Java datastruktur Vi forminsker og forenkler objektet navn INF1010Person String void skrivut String hentnavn int sammenlign BTelem hentvsubtrepeker BTelem henthsubtrepeker void settvsubtrepeker void setthsubtrepeker void leggtilbtre venstre høyre BTelem BTelem
Java datastruktur Klassen som beskriver objektet som inneholder binærtreet 1 class BTre <T extends BTelem> { 2 private T rot ; 3 4 public void settinn (T inn ) { 5 if ( rot == null ) rot = inn ; 6 else rot. leggtilbtre ( inn ) ; 7 } 8 9 public void skrivut ( ) { 10 if ( rot!= null ) rot. skrivut ( ) ; 11 } 12 }
Java datastruktur Hvor langt har main-metoden kjørt? kristhk haavand nikolark andrepar
Java datastruktur rot kristhk INF1010person INF1010PersonTre BTre haavand niko andrepar
Java datastruktur kristhk rot haavand nikolark andrepar
Java datastruktur Koden i main som skaper datastrukturen i skissen på forrige lysark 1 public class GBTeksempel{ 2 public static void main( String [ ] args ) { 3 BTre <INF1010Person> INF1010PersonTre = 4 new BTre <INF1010Person >(); 5 INF1010PersonTre. settinn (new INF1010Person ( kristhk ) ) ; 6 INF1010PersonTre. settinn (new INF1010Person ( haavaand ) ) 7 INF1010PersonTre. settinn (new INF1010Person ( andrepar ) ) 8 INF1010PersonTre. settinn (new INF1010Person ( nikolark ) ) 9 <Se struktur bygget opp så langt på forrige lysark>
Java datastruktur Sette inn det første objektet Vi lager objektet ved å utføre konstruktøren i INF1010Person: 1 new INF1010Person ( kristhk ) Dette objektet gis som parameter til et kall på settinn i BTre-objektet INF1010PersonTre: 1 INF1010PersonTre. settinn (new INF1010Person ( kristhk ) ) ; 2 3 4 public void settinn ( INF1010Person inn ) { 5 if ( rot == null ) rot = inn ; 6 else rot. leggtilbtre ( inn ) ; 7 } Vi får satt rot til å peke på objektet med navn lik kristhk.
Java datastruktur Sette inn det andre objektet Objektet blir laget på samme måte som det første. Men rot er ikke lenger null og vi får et kall på leggtilbtre i objektet som rot peker på. I denne metoden blir «kristhk» sammenlignet med «haavaand». Resultatet blir større enn null og metoden sjekker om venstrepekeren peker til noe. Det gjør det ikke og objektet «haavaand» blir satt inn der. Så gjentas dette for hvert nytt objekt som skal settes inn. Vi starter hver gang i rota (kaller på leggtilbtre), finner ut «hvilken vei vi skall» og kaller på leggtilbtre i riktig subtrerot.
Java datastruktur Innsettingsmetoden er inne i objektet Alle objektene i treet har en metode som kan sette inn innparameterobjektet. Når vi kaller innsettingsmetoden inne i et objekt med personen som som skal settes inn som parameter, vil denne først sjekke om innobjektet skal settes inn til venstre eller til høyre. Deretter settes objektet inn der ved å sette høyre- eller venstrepekeren til å peke på objektet som skal inn, dersom det ikke er noe der fra før. Hvis det er et objekt der fra før sendes parameteren videre ved å kalle på dette objektets settinnmetode.
Java datastruktur Slik sendes parameteren fra metode til metode nedover i treet til vi kommer til en peker som er null. Da settes denne til å peke på innobjektet. 1 public void leggtilbtre ( Object inn ) { 2 int smnlgn = this. sammenlign( inn ) ; 3 if ( smnlgn < 0 ) 4 i f ( henthsubtrepeker ( ) == null ) 5 setthsubtrepeker( inn ) ; 6 else henthsubtrepeker ( ). leggtilbtre ( inn ) ; 7 else 8 i f ( hentvsubtrepeker ( ) == null ) 9 settvsubtrepeker ( inn ) ; 10 else hentvsubtrepeker ( ). leggtilbtre ( inn ) ; 11 }
Java datastruktur Drøft disse spørsmålene Hva gjør settinnmetoden i objektet som blir satt inn? Hvorfor kan vi ikke sette objektet der det er ledig hvis pekeren der det skal ikke er det? Hva skjer hvis vi setter inn to objekter med samme navn?
Gjøre noe i hele treet = kalle på samme metode i alle objektene Gjøre noe i alle objektene For å gjøre en konkret oppgave (sette en variabel til en bestemt verdi) i alle objektene kan vi: Utfør oppgaven i rotobjektet Utfør oppgaven i venstre subtre Utfør oppgaven i høyre subtre Disse tre operasjonene kan vi gjøre i vilkårlig rekkefølge. Oppgaven vil bli gjort i alle objektene, men i forskjellig rekkefølge.
Gjøre noe i hele treet = kalle på samme metode i alle objektene Skrive ut alle objektene I personklassen: 1 void skrivut ( ) { 2 BTelem p = hentvsubtrepeker ( ) ; 3 if (p!= null ) p. skrivut ( ) ; 4 5 System. out. print (hentnavn ()+ ) ; 6 7 if (henthsubtrepeker ( )!= null ) 8 henthsubtrepeker ( ). skrivut ( ) ; 9 }
Idé Bruk av indre klasser I dette eksemplet er ideen at vi bruker indre klasser til strukturelementene. (Både for binærtre- og og listeobjektene). Fra strukturelementene går det en peker (generisk (T) eller generell (Object)) til dataobjektet. Med en slik organisering av dataene, er det naturlig å tegne objekter av den indre klassen inne i et objekt av den ytre klassen.
Java datastruktur toppelement rot ListeNode skrivut tilstakk leggtilbtre skrivut BTreNode C lifo Objekter av klassen Bil frabtretilstakk BTre
Klassestruktur Klassestruktur 1 interface Skrivbar { } 2 3 class BTre <T extends Skrivbar & Comparable <T>> { 4 BTreNode rot ; 5 class BTreNode { } 6 } 7 class Stakk { 8 ListeNode toppelement ; 9 class ListeNode { } 10 } 11 class B i l implements Comparable <Bil >, Skrivbar { } 12 13 public class TreStakkEksempel{ 14 BTre <Bil > biltre = new BTre <Bil >(); 15 Stakk lifo = new Stakk ( ) ; 16 }
Klassestruktur Rollen Skrivbar og klassen BTre 1 interface Skrivbar { 2 void skrivut ( ) ; 3 } 4 class BTre <T extends Skrivbar & Comparable <T>> { 5 BTreNode rot ; 6 void leggtilbtre (T t ) { } 7 void skrivut ( ) { } 8 void frabtretilstakk ( Stakk liste ) { } 9 10 class BTreNode { 11 BTreNode venstre, høyre ; 12 T denne; 13 BTreNode(T t ) { denne = t ; } 14 void leggtilbtre ( BTreNode inn ) { } 15 void frabtretilstakk ( Stakk liste ) { } 16 void skrivut ( ) { } 17 18 }
Klassestruktur Listeklassen 1 class Stakk { 2 ListeNode toppelement ; 3 4 class ListeNode { } 5 6 void skrivut ( ) { } 7 8 void tilstakk ( Object o ) { } 9 }
Klassestruktur Klassen som beskriver selve dataobjektet (Bil) 1 class B i l implements Comparable <Bil >, Skrivbar { 2 private String navn; 3 Bil ( String n) { navn = n; } 4 5 public int compareto( Bil b) { 6 return navn.comparetoignorecase (b.navn ) ; 7 } 8 10 9 String hentnavn ( ) { return navn; } 11 public void skrivut ( ) { } 12 }
Klassestruktur Klassen som beskriver eksemplet (main) 1 public class TreStakkEksempel{ 2 public static void main( String [ ] args ) { 3 BTre <Bil > biltre = new BTre <Bil >(); 4 5 Stakk lifo = new Stakk ( ) ; 6 7 biltre. leggtilbtre (new Bil ( kristhk ) ) ; 8 // <.... mange utelatt > 9 biltre. skrivut ( ) ; 10 System. out. println( ========== ) ; 11 biltre. frabtretilstakk ( lifo ) ; 12 lifo. skrivut ( ) ; 13 } 14 }
Klassestruktur Metoden som legger et objekt til LIFO-lista 1 class Stakk { 2 ListeNode toppelement ; 3 4 class ListeNode { 5 ListeNode neste ; Object denne; 6 ListeNode( Object objekt ) {denne = objekt ; } 7 } 8 9 void tilstakk ( Object o ) { 10 ListeNode ln = new ListeNode(o ) ; 11 ln. neste = toppelement ; 12 toppelement = ln ; 13 } 14 }
Klassestruktur Metodene som gjør om fra binærtre til liste 1 class BTre <T extends Skrivbar & Comparable <T>> { 2 BTreNode rot ; 3 void frabtretilstakk ( Stakk liste ) 4 { if ( rot!= null ) rot. frabtretilstakk ( liste ) ; } 5 6 class BTreNode { 7 BTreNode venstre, høyre ; 8 T denne; 9 BTreNode(T t ) { denne = t ; } 10 11 void frabtretilstakk ( Stakk liste ) { 12 if ( venstre!= null ) venstre. frabtretilstakk ( liste ) ; 13 liste. tilstakk (denne) ; 14 if (høyre!= null ) høyre. frabtretilstakk ( liste ) ; 15 } 16 } 17 }