Träd
Träd Rot Förgrening Löv
Exempel: Organisationsschema Rot Överkucku Förgrening Underhuggare Underhuggare Administativ chef Kanslichef Knegare Knegare Knegare Byråchef Löv Intendent Avd. chef Intendent Avd. chef Intendent Pappersvändare Pappersvändare Pappersvändare
Exempel: Innehållsförteckning Mastering Algorithms with C I Preliminaries Introduction Pointer Manipulation Pointer fundamentals Storage allocation Aggregates... etc Recursion Analysis of Algorithms II Data Structures III Algorithms Löv Förgrening Rot
Exempel: Filkatalogstruktur Rot Förgrening Löv
Exempel: Programrepresentation Rot Program Förgrening foo() bar() baz() while () return; return; return; if Löv x = ; then y = ; else z =; 42 x 13
Trädexempel... Fönster på skärmen Widgets i fönstren Släktträd etc.
Binära träd En speciell kategori av träd Varje förgrening går till högst två noder Lite enklare då det är en specialisering Vi sätter fokus på binära träd...
ADT:n Binärt träd
Några begrepp Rutorna kallas noder (nodes), de innehåller något slags data som är av intressen för användningen Direkt uder en nod finns högst två noder, barn (child, kid). Specifikt: Left child, right child. Direkt över en nod finns högst en nod, dess förälder (parent) Noden som inte har någon annan över sig är rot (root) Anfäder (ancestors) alla över Ättlingar (descendants) alla under En noder som saknar barn är ett löv (leaf) Skog (forest) Trädhöjd
ADT:n Binärt träd Rot A: B: C: D: E: F: Children(A) = {B, C} Children(C) = {D} Children(E) = { }
ADT:n Binärt träd A: B: C: D: E: F: Parent(C) = A Parent(A) = finns ej
ADT:n Binärt träd A: B: C: D: E: F: Ancestors(D) = {C, A} Ancestors(A) = { }
ADT:n Binärt träd A: B: C: D: E: F: Descendants(C) = {D, E, F} Descendants(A) = {B, C, D, E, F}
ADT:n Binärt träd A: B: C: D: E: F: C utgör roten i ett delträd
Definition Ett binärt träd kan definieras genom följande rekursiva definition: Ingen nod är ett binärt träd (ett tomt binärt träd) En nod med två barnträd, ett vänster barnträd och ett höger barnträd, är ett binärt träd Grafiskt kan vi illustrera detta på följande sätt:
ADT:n Binärt träd A: B: C: D: E: F: Det tjänar dock inget syfte att rita ut dessa
ADT:n Binärt träd A: B: C: D: E: F: Man kan visa med stopmarkeringar istället - motsvarar NULL-pekare i C.
Övning Precis som i fallet med listor, stackar och köer vill göra en generell implementation av ADT:n BTree. Typen på data som kan lagras i noderna måste därför vara av typen voidpekare i C. Skriv en lämplig structdefinition för BTree. Deklarationen i h-filen ser ut så här: typedef struct BTree BTree; Detta är samtidigt typen på noderna.
ADT:ns operationer Sätta in en ny nod till vänster/höger Skapa nytt träd av två delträd Ta bort vänster/höger barnträd Tala om antalet noder Tala om höjden på trädet Svara på om nod är löv/rot Returnera data Returnera vänster/höger barnnod
Interfacet i C Btree *BtreeCreate(void *data); void BtreeDestroy(Btree *node); void *BTreeData(BTree *node); void BTreeInsertLeft(BTree *node, BTree *left); BTreeInsertRight BTree *BTreeLeft(BTree *node); BtreeRight void BTreeUnlinkLeft(BTree *node); BTreeUnlinkRight int BTreeSize(BTree *node); int BTreeHeight(BTree *node); int BTreeIsLeaf(BTree *node); int BTreeIsRoot(BTree *node);
Övningar (1) Implementera funktionen BTreeInsertLeft. Tänk på vilka fall som finns. Om du behöver anpassa deklarationen så gör det. Skriv slutligen den kommentar som måste finnas i h-filen. void BTreeInsertLeft(BTree *BTree, void *data); (2) Skriv koden som använder denna ADT för att bygga ett nytt träd givet två delträd (som kommer att bli barnträd till det nya). Skriv det som en funktion som tar lämpliga parametrar. Tycker du att detta skulle kunna vara en funktion som istället är en del av ADT:n.
Traversering av binära träd Travesrering (att klättra omkring i trädet och besöka noderna) sker oftast från vänster till höger.
Traversering A: B: C: D: E: F: Syftet med klättringen är att göra något med data i noderna som passeras. Ordningen mellan det man i en nod behandlar data relativt besöken av barnträden påverkar i allmänhet resultatet.
Traversering A: B: C: D: E: F: Antag att behandla data är att skriva ut data Antag att data är den bokstav som står intill noden Antag att behandling av data sker innan barnträden besöks Resulat? Skriv på ett papper!
Traversering A: B: C: D: E: F: Vi byter: Antag att behandling av data sker efter att barnträden besöks Resulat?
Traversering De metoder som brukar användas kallas Preorder: behandla data före barnträden Inorder: behandla data mellan barnträden Postorder: behandla data efter barnträden
Övning Skriv en funktion som tar ett binärt träd som input och som använder ADT:n BTree för att skriva ut alla trädnoder enligt postorder traversering. Anta att det data som finns i noderna är pekare till strängar. Från interfacet till BTree: Btree *BtreeCreate(void *data); void *BTreeData(BTree *node); void BTreeInsertLeft(BTree *node, BTree *left); BTree *BTreeLeft(BTree *node); void BTreeUnlinkLeft(BTree *node); int BTreeIsLeaf(BTree *node); int BTreeIsRoot(BTree *node);