Træer. Datastrukturer & Algoritmer, Datalogi C Forelæsning 9/

Relaterede dokumenter
Søgetræer: Generel repræsentation af (sorterede) mængder og funktioner Databasesystemer...

Binære søgetræer. Binære søgetræer. Nærmeste naboer. Nærmeste nabo

Binære søgetræer. Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb. Philip Bille

Binære søgetræer. Binære søgetræer. Nærmeste naboer. Nærmeste nabo

Skriftlig eksamen i Datalogi

Stakke, køer og lidt om hægtede lister

Stakke, køer og lidt om hægtede lister - kapitel 16 og 17

Om binære søgetræer i Java

Algoritmer og datastrukturer Course No Cheat Sheet May 15, 2012

Prioritetskøer og hobe. Philip Bille

Definition : Et træ er en sammenhængende ikke-orienteret graf uden simple kredse. Sætning : En ikke-orienteret graf er et træ hvis og kun hvis der er

02105 Eksamensnoter. Lasse Herskind S maj Sortering 3

Vejledende løsninger

Prioritetskøer. Prioritetskøer Træer og hobe Repræsentation af hobe Algoritmer på hobe Hobkonstruktion Hobsortering. Philip Bille

Datastrukturer (recap)

Danmarks Tekniske Universitet

Prioritetskøer. Prioritetskøer. Prioritetskøer. Prioritetskøer

Prioritetskøer. Prioritetskøer. Prioritetskøer. Prioritetskøer

Datastrukturer (recap) Datastruktur = data + operationer herpå

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Prioritetskøer ved»heap«, simulering

Skriftlig Eksamen Algoritmer og Datastrukturer 1. Datalogisk Institut Aarhus Universitet. Mandag den 22. marts 2004, kl

Skriftlig eksamen i Datalogi

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

Datastrukturer (recap)

Danmarks Tekniske Universitet

Intervalsøgning. Algoritmisk geometri. Motivation for intervaltræer. Intervalsøgning. Lad der være givet en database over ansatte i en virksomhed

Skriftlig eksamen i Datalogi

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: n 2 n (log n) 2. 3 n /n 2 n + (log n) 4

Algoritmisk geometri

Danmarks Tekniske Universitet

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 4 n n 3n n 2 /logn 5 n n (logn) 3n n 2 /logn 4 n n 5 n

1. Redegør for Lister, stakke og køer mht struktur og komplexitet af de relevante operationer

16 Træer. Noter. Definition af et træ. Definitioner i tilknytning til træer. Repræsentation af træer. Binære træer. Den abstrakte datatype.

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned.

Skriftlig eksamen i Datalogi

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Rekursion og dynamisk programmering

DM507 Algoritmer og datastrukturer

Skriftlig Eksamen Algoritmer og Datastrukturer 1. Datalogisk Institut Aarhus Universitet

Divide-and-Conquer algoritmer

DM507 Algoritmer og datastrukturer

Divide-and-Conquer algoritmer

DM507 Algoritmer og datastrukturer

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: n n (log n) 2. n 2 + log n 3 n. n n (log n)

Danmarks Tekniske Universitet

Divide-and-Conquer algoritmer

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

DATALOGISK INSTITUT, AARHUS UNIVERSITET

Divide-and-Conquer algoritmer

Danmarks Tekniske Universitet

DM507 Algoritmer og datastrukturer

Algoritmeanalyse. Øvre grænse for algoritme. Øvre grænse for problem. Nedre grænse for problem. Identificer essentiel(le) operation(er)

Datalogi OB, Efterår 2002 OH er, forelæsning 10/ Klasser og nedarvning

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

Skriftlig Eksamen Algoritmer og Datastrukturer (DM507)

Binære søgetræer. Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Algoritmer på træer og trægennemløb.

Binære søgetræer og skiplister

DM507 Algoritmer og datastrukturer

Orienterede grafer. Orienterede grafer. Orienterede grafer. Vejnetværk

Sortering. Eksempel: De n tal i sorteret orden

Sortering af information er en fundamental og central opgave.

DATALOGISK INSTITUT, AARHUS UNIVERSITET

Grådige algoritmer. Et algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Klasser og nedarvning

Sortering. Eksempel: De n tal i sorteret orden

Introduktion til datastrukturer. Introduktion til datastrukturer. Introduktion til datastrukturer. Datastrukturer

Danmarks Tekniske Universitet

DM507 Algoritmer og datastrukturer

Skriftlig Eksamen Algoritmer og Datastrukturer (dads)

Introduktion til datastrukturer. Introduktion til datastrukturer. Introduktion til datastrukturer. Datastrukturer

Danmarks Tekniske Universitet

Sortering af information er en fundamental og central opgave.

DM507 Algoritmer og datastrukturer

Sortering. De n tal i sorteret orden. Eksempel: Kommentarer:

BRP Tal. Om computer-repræsentation og -manipulation. Logaritmer

DANMARKS TEKNISKE UNIVERSITET

Opskriv følgende funktioner efter stigende orden med hensyn til O-notationen: 23n log n. 4 n (log n) log n

Introduktion til datastrukturer. Philip Bille

Skriftlig Eksamen Algoritmer og Datastrukturer (dads)

Syntaks og syntaksgenkendelse, særligt regulære udtryk og tilstandsmaskiner og lidt om anvendelser i bioinformatik

Introduktion til datastrukturer

Løsning af møntproblemet

DM507 Algoritmer og datastrukturer

BRP Kursusintroduktion og Java-oversigt

Tree klassen fra sidste forelæsning

Mindste udspændende træ. Mindste udspændende træ. Introduktion. Introduktion

Danmarks Tekniske Universitet

DM507 Algoritmer og datastrukturer

Grafer og graf-gennemløb

Orienterede grafer. Orienterede grafer. Orienterede grafer. Orienterede grafer

Orienterede grafer. Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer.

Transkript:

Datastrukturer & Algoritmer, Datalogi C Forelæsning 9/11-2004 Træer En meget vigtig datastruktur Repræsentation af sprog (i meget generel betydning), syntakstræer: Java (i en compiler), SQL (i et databasesystem), XML... Naturligt sprog Søgetræer: Generel repræsentation af (sorterede) mængder og funktioner Databasesystemer... Dagens program: Hvad er et træ (datalogisk set)? Eksempel på syntakstræer udtrykt vha. nedarvning NB: udenfor bogen; find Javafiler via kursets hjemmeside Java-stil implementation af generiske træer Traversering af træer vha. TreeIterator preorder, postorder, inorder, levelorder Binære søgetræer Princip og generisk implementation i Java Balancerede træer, AVL-træer (+ omtale af et par andre) (1)

Hvad er et træ? Matematikeren: Et specialtilfælde af en graf: En sammenhængende skov, hvor en skov er en orienteret, acyklisk graf, med højst én vej mellem to forskellige knuder Og så kan vi jo bare bruge kendte repræsentationer for grafer og grafalgoritmer... Datalogen udnytter naturlig rekursion: Et træ består af et stykke data samt nul eller flere træer kaldet deltræer Træalgoritmer Naturligt rekursive f.eks. summe træer med tal... Sum( t(k,t 1,...,T n ) ) = k + Sum(T 1 ) +... + Sum(T n ) En gang imellem benytte en stak (og sommetider en kø...) (2)

Eksempel på repræsentation af syntaktræer vha. nedarvning Træer for udtryk defineret ved følgende abstrakte grammatik <udtryk> ::= <tal> <udtryk> + <udtryk> <udtryk> * <udtryk> Et udtrykstræ er enten Et tal-træ, som indeholder en talkonstant (og 0 deltræer) Et plus-træ har to deltræer, som er udtrykstræer Et gange-træ har to deltræer, som er udtrykstræer + / \ 1 * / \ 2 3 (3)

Brug af Javas nedarvning til repræsentation af syntakstræer abstract class ExpressionTree { } class PlusTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public PlusTree(ExpressionTree f, ExpressionTree s) {first=f;second=s;} } class TimesTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public TimesTree(ExpressionTree f, ExpressionTree s) {first=f;second=s;} } class NumberTree extends ExpressionTree { int value; public NumberTree(int v) {value=v;}} (Alternativt: Definere klasse for binære operatorer, og så specialisere den...) Nedarving udnyttes til at definere et typehierarki modsat generiske træer i Java-stil. (4)

Syntakstræer kan bygges eksplicit ExpressionTree exp = new PlusTree ( new NumberTree(1), new TimesTree( new NumberTree(2), new NumberTree(3))); Eller i praksis ved en parser, som læser tegn ind fra fil og konstruerer træ efterhånden, enten top-down, eller bottom-up Rekursive metoder udnytter også nedarvning... (5)

abstract class ExpressionTree { public abstract void printstackcode(); } class PlusTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public void printstackcode() {first.printstackcode(); second.printstackcode(); System.out.println("PLUS");} } class TimesTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public void printstackcode() {first.printstackcode(); second.printstackcode(); System.out.println("TIMES");} } exp.printstackcode(); ==> PUSH 1 PUSH 2 PUSH 3 TIMES PLUS Analogt post-order traversal 1. gør noget ved deltræerne, 2. gør noget for denne knude class NumberTree extends ExpressionTree { int value; public void printstackcode() {System.out.println("PUSH "+value);} } (6)

abstract class ExpressionTree { public abstract void printexpression(); } class PlusTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public void printexpression() {System.out.print("("); first.printexpression(); System.out.print("+"); second.printexpression(); System.out.print(")");} } exp.printexpression(); ==> (1+(2*3)) Ser vi bort fra udskrift af parenteserne: Analogt in-order traversal 1 Gør noget ved venstre deltræ, 2 Gør noget for denne knude, 3 Gør noget ved højre deltræ class TimesTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public void printexpression() {System.out.print("("); first.printexpression(); System.out.print("*"); second.printexpression(); System.out.print(")");} } class NumberTree extends ExpressionTree { int value; public void printexpression() {System.out.print(value);} } (7)

abstract class ExpressionTree { public abstract void printlispcode(); } class PlusTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public void printlispcode() {System.out.print("(PLUS"); first.printlispcode(); second.printlispcode(); System.out.print(")");} } exp.printlispcode (); ==> (PLUS 1(TIMES 2 3)) Ser vi bort fra udskrift af parenteserne: Analogt pre-order traversal 1 Gør noget for denne knude, 2 Gør noget ved deltræerne class TimesTree extends ExpressionTree { ExpressionTree first; ExpressionTree second; public void printlispcode() {System.out.print("(TIMES"); first.printlispcode(); second.printlispcode(); System.out.print(")");} } class NumberTree extends ExpressionTree { int value; public void printlispcode() {System.out.print(" "+value);} } (8)

Repræsentation af Java-stil generiske binære træer public class BinaryNode { // konstruktorer og de metoder kan kan forvente private Object element; private BinaryNode left; private BinaryNode right; } public class BinaryTree { // konstruktorer og de metoder kan kan forvente private BinaryNode root; } abstract class TreeIterator { public TreeIterator( BinaryTree thetree ) {t=thetree;current=null;} // den slags metoder som hører til en iterator... // blandet abstract og def. vha. abstract protected BinaryTree t; protected BinaryNode current; } (9)

class PostOrder extends TreeIterator { //definition af abstrakte metoder fra TreeIterator... //internt snask: protected static class StNode { } protected Stack s; } class InOrder extends PostOrder { } // usmukt genbrug :( class PreOrder extends TreeIterator {... også noget med en stak } class LevelOrder extends TreeIterator {... noget med en kø} (10)

abstract class TreeIterator { public TreeIterator(BinaryTree thetree) {t = thetree; current = null;} abstract public void first( ); final public boolean isvalid( ) {return current!= null;} final public Object retrieve( ) { if( current == null ) throw... ; return current.getelement( ); } abstract public void advance( ); protected BinaryTree t; protected BinaryNode current; } (11)

class PostOrder extends TreeIterator {...} Hvis Java havde haft ægte co-rutiner kunne det implementeres ved rekursion Pseudokode: class PostOrder extends TreeIterator {...} public void first {postordertraverse(t.getroot());} private void postordertraverse(binarynode t); { if(t==null) return; postordertraverse(t.getleft()); postordertraverse(t.getright()); current=t; detach(); return;} public void advance( ); {resume()} } Primitiver a la Simula68 (ikke i Java) detach() læg metode til at sove indtil der kommer en resume() resume() start en detach et proces OBS: Preorder og inorder fås ved at bytte rundt linjerne i xxxordertraverse() Disse primitiver findes ikke i Java, så derfor programmeres med eksplicit stak. (12)

class PostOrder extends TreeIterator { // Intern stak i mangel på rekursion: protected static class StNode { BinaryNode node; int timespopped; StNode( BinaryNode n ) {node = n; timespopped = 0;}} protected Stack s;... } (13)

class PostOrder extends TreeIterator { // Intern stak i mangel på rekursion: protected static class StNode { BinaryNode node; int timespopped; StNode( BinaryNode n ) {node = n; timespopped = 0;}} protected Stack s; public PostOrder( BinaryTree thetree ) {super(thetree); s=new ArrayStack(); s.push(new StNode(t.getRoot()));} public void first( ) {s.makeempty( ); if( t.getroot( )!= null ) {s.push(new StNode(t.getRoot())); advance();}} (14)

public void advance( ) {if( s.isempty( ) ) {if( current == null ) throw...; current = null; return; } StNode cnode; for( ; ; ) {cnode = ( StNode ) s.topandpop( ); if( ++cnode.timespopped == 3 ) {current = cnode.node; return;} s.push( cnode ); if( cnode.timespopped == 1 ) { if(cnode.node.getleft()!=null) s.push(new StNode(cnode.node.getLeft()));} else // cnode.timespopped == 2 {if(cnode.node.getright()!=null) s.push(newstnode(cnode.node.getright()));}}} } //NB: der stilles ingen eksamensspørgsmål om hvordan den stak bruges // (læreren synes det er noget knoldkode) (15)

Binært søgetræ En måde at opbevare og vedligeholde en samling objekter på. objekterne holdes sorterede o dvs. at finde objekter log n indsættelse af nye objekter kræver ikke ny sortering eller flytning af n/2 elementer indsættelse med inkrementel sortering log n Definition: Et binært søgetræ er et binært træ hvor hver knude holder et element af en mængde udstyret med < og =, således at alle værdier i venstre deltræ < værdi på knude < alle værdier i højre deltræ Eksempel 7 / \ / \ 2 9 / \ 1 5 / 3 (16)

Eksempel 7 / \ / \ 2 9 / \ 1 5 / 3 Egenskab: Hvis et binært søgetræ udskrives in-order kommer elementerne ud i voksende rækkefølge Skitse af definition: En binært træ er balanceret hvis det er ca. lige dybt over det hele. Egenskab: Et balanceret, binært træ med n elementer har højde log n. Dvs. søgning i balanceret, binært søgetræ er O(log n). (17)

Repræsentation af Binære søgetræer i Java-stil Upraktisk at specialisere fra BinaryTree, da Object erne skal være Comparable + lukke for modifikationer. class BinaryNode { BinaryNode(Comparable theelement){element=theelement;left=right=null;} Comparable element; BinaryNode left; BinaryNode right; } public class BinarySearchTree { public BinarySearchTree( ) {root = null; } // diverse nyttige metoder, bl.a. public void insert (Comparable x) { halv-kompliceret stads } public Comparable find( Comparable x ) // returnerer x hvis den findes;ellers null { return elementat( find( x, root ) );} private Comparable elementat( BinaryNode t ) {return t == null? null : t.element;} private BinaryNode find( Comparable x, BinaryNode t ) { while( t!= null ) { if( x.compareto( t.element ) < 0 ) t = t.left; else if( x.compareto( t.element ) > 0 ) t = t.right; else return t; } return null; } protected BinaryNode root; } (18)

Indsættelse af element x At lede efter elementet x, og hvis det ikke findes, indsætte det, hvor det burde have været: I Java: Metode i BinarySearchTree: public void insert(comparable x) { root = insert(x, root); } BinaryNode insert(comparable x, BinaryNode t) { if (t == null) t = new BinaryNode(x, null, null); else if (x.compareto(t.element) < 0) t = insert(x, t.left); else if (x.compareto(t.element) > 0) t = insert(x, t.right); else throw new DuplicateItemException(x.toString()); return t; } (19)

Sletning af element x i binært søgetræ Bemærk: Problemet kan altid reduceres til at fjerne x i position som rod af et træ (det undertræ, som har x i toppen). Erstat roden med den knude, der er mindst i rodens højre undertræ. Denne knude befinder sig længst til venstre i rodens højre undertræ. Hvis det højre undertræ er tomt, fjernes roden blot fra træet. (20)

I Java: public void remove(comparable x) {root = remove(x, root);} protected BinaryNode remove( Comparable x, BinaryNode t ) {if( t == null ) throw new ItemNotFoundException( x.tostring( ) ); if( x.compareto( t.element ) < 0 ) t.left = remove( x, t.left ); else if( x.compareto( t.element ) > 0 ) t.right = remove( x, t.right ); else if( t.left!= null && t.right!= null ) // Two children { t.element = findmin( t.right ).element; t.right = removemin( t.right ); } else t = ( t.left!= null )? t.left : t.right; return t; } findmin søg til venstre removemin søg rekursivt til venstre, og da minimum element ikke har to undertræer, kan træet trækkes sammen (21)

Dette er altsammen meget godt, men det er kun interessant hvis indsættelser og sletninger ankommer således passende at træet forbliver balanceret. Eksempel: Værdier indsættes i voksende rækkefølge: 1 \ 2 \ 3 \ 4 \ 5 \... Træet degenererer til en hægtet liste. O(log n) ==> O(n) :( Altså: Indsættelse og sletning skal justere på træet så det er nogenlunde balanceret. Bogen omtaler forskellige strategier (og der er mange andre beskrevet i litteraturen) Vi nøjes med at skitsere AVL-træer! (22)

AVL-træer (Adelson-Velskii og Landis, 1962) For enhver knude i træet gælder, at højden af dens venstre undertræ og højden af dens højre undertræ højst afviger med 1. Eksempel på AVL-træ: Det kan bevises, at denne egenskab er tilstrækkelig for at sikre log n dybde. (23)

Skitse af metode for indsættelse i AVL-træ Indsættelse i X s venstre undertræ kan ødelægge AVL-egenskaben. I det følgende betegner X den dybeste knude, som er rod i et deltræ, der ikke længere opfylder AVLegenskaben. (24)

(25)

Tilfælde 1: En højrerotation genskaber balancen (26)

Tilfælde 2: En højrerotation genskaber ikke balancen Der skal en dobbeltrotation til: Først rotere til venstre i venstre deltræ; dernæst til højre i hele træet! Vi skåner tilhøreren (og læreren!) for implementationen i Java! (27)

Afslutning: Træer vigtig datastruktur til at repræsentere af natur træagtige ting syntakstræer katalogstrukturer procestræer i operativsystemer... (Binære) søgetræer: Vigtig datastrukturer til effektiv lagring og genfinding. Essentielt: At holde træerne balancerede! Databasesystemer er fyldt med træer og balanceringsalgoritmer... og hashing som vi kommer til senere... (28)