BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

Relevanta dokument
Föreläsning 5. Träd Binära träd Binärt sökträd som ADT Implementering av binärt sökträd Travestera binärt sökträd Sökning Insättning/borttagning

SORTERING OCH SÖKNING

Föreläsning 9 Datastrukturer (DAT037)

Tentamen, Algoritmer och datastrukturer

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Erik Nilsson, Institutionen för Datavetenskap, LiU

Datastrukturer, algoritmer och programkonstruktion (DVA104, HT 2014) Föreläsning 5

Symboliska konstanter const

Föreläsning 7. Träd och binära sökträd

Självbalanserande träd AVL-träd. Koffman & Wolfgang kapitel 9, avsnitt 1 2

Lösningsförslag till tentamen Datastrukturer, DAT037,

Träd. Rot. Förgrening. Löv

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Inom datalogin brukar man använda träd för att beskriva vissa typer av problem. Om man begränsar sig till träd där varje nod förgrenar sig högst två

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Jonas Lindgren, Institutionen för Datavetenskap, LiU

#include <stdio.h> #include <string.h>

2 Pekare och dynamiska variabler.

Självbalanserande AVL-träd Weiss, avsnitt 4.4

Skriv i mån av plats dina lösningar direkt i tentamen. Skriv ditt kodnummer längst upp på varje blad.

Föreläsning Datastrukturer (DAT036)

Föreläsning 9 Innehåll

Föreläsning 7. Träd och binära sökträd

Länkade listor kan ingå som en del av språket, dock ej i C Länkade listor är ett alternativ till:

Lösningsförslag till tentamen Datastrukturer, DAT037 (DAT036), Tiden det tar att utföra en iteration av loopen är oberoende av värdet på

Föreläsning 4. Kö Implementerad med array Implementerad med länkad lista Djup kontra bredd Bredden först mha kö

Abstrakta datastrukturer

Föreläsning 9 Innehåll

HI1024, Programmering, grundkurs, 8hp KTH STH TENTAMEN. HI1024:TEN2 - Praktisk tentamen Tid: Fredagen den 21 oktober 2011,

Innehåll. Föreläsning 12. Binärt sökträd. Binära sökträd. Flervägs sökträd. Balanserade binära sökträd. Sökträd Sökning. Sökning och Sökträd

Föreläsning 13 och 14: Binära träd

DAI2 (TIDAL) + I2 (TKIEK)

Binära sökträd. Seminarium 9 Binära sökträd Innehåll. Traversering av binära sökträd. Binära sökträd Definition. Exempel på vad du ska kunna

Trädstrukturer och grafer

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

13 Prioritetsköer, heapar

Datastrukturer. föreläsning 10. Maps 1

TDIU01 Programmering i C++

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tentamen Datastrukturer (DAT036)

Tentamen Datastrukturer D DAT 035/INN960

Lösningar Datastrukturer TDA

Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Specifikationer för tabellfunktionerna. Operationer på tabellen

DD1320 Tillämpad datalogi. Lösning (skiss) till tenta 20 okt 2011

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

Exempel ( )

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

TDIU01 - Programmering i C++, grundkurs

Föreläsning Datastrukturer (DAT036)

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Föreläsning 13. In- och utmatning

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

*Pekarvärden *Pekarvariabler & *

Pekare och arrayer. Indexering och avreferering

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 8 Om abstrakta datatyper och binära sökträd

Föreläsning 4 Datastrukturer (DAT037)

Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Implementering av tabellen. Operationer på tabellen

BMI = (vikt i kg) / (längd i m) 2. Lösningsförslag

Programmering, grundkurs, 8.0 hp HI1024, HI1900 etc., Tentamen TEN1. Måndagen den 10 januari 2011,

Ett generellt träd är. Antingen det tomma trädet, eller en rekursiv struktur: rot /. \ /... \ t1... tn

Tentamen Datastrukturer, DAT037 (DAT036)

Tentamen TEN1 HI

if (n==null) { return null; } else { return new Node(n.data, copy(n.next));

Tentamen *:58/ID100V Programmering i C Exempel 3

Övning från förra gången: readword

Tentamen i Algoritmer & Datastrukturer i Java

3 Listor. 3.1 Envägslistor

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

Föreläsning 4 Datastrukturer (DAT037)

Johan Karlsson Datavetenskap för teknisk kemi, 10p, moment 1 Datavetenskap Umeå Universitet. Tentamen

Uppgifter till praktiska tentan, del A. (7 / 27)

F5: Debriefing OU2, repetition av listor, träd och hashtabeller. Carl Nettelblad

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning 10 Innehåll. Diskutera. Inordertraversering av binära sökträd. Binära sökträd Definition

Föreläsning 3 Datastrukturer (DAT037)

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Tentamen TEN1 HI

Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

Träd. Ett träd kan se ut på detta sätt:

Rekursion och induktion för algoritmkonstruktion

Föreläsning 10 Innehåll

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4

Algoritmer och datastrukturer 2012, föreläsning 6

En kort text om programmering i C.

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

Föreläsning 11 Datastrukturer (DAT037)

Programmering i C++ EDA623 Mallar. EDA623 (Föreläsning 12) HT / 29

Deklarera en struct som kan användas för att representera en rät linje

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Algoritmer och datastrukturer

Tildatenta Lösningsskiss

Datastrukturer. föreläsning 9. Maps 1

Lösningsförslag till tentamen

Namn: (Ifylles av student) Personnummer: (Ifylles av student) Tentamensdatum: Tid: Hjälpmedel: Inga hjälpmedel

Sätt att skriva ut binärträd

Programkonstruktion och. Datastrukturer

Tentamen Datastrukturer, DAT037 (DAT036)

Föreläsning 6: Introduktion av listor

Transkript:

Algoritmer och Datastrukturer Kary FRÄMLING/Göran PULKKIS (v23) Kap. 7, Sid 1 BINÄRA TRÄD Träd används för att representera olika slags hierarkier som ordnats på något sätt. Den mest använda trädstrukturen är binära träd, i vilka varje nod kan ha noll, en eller två söner. Följande postdefinition kan användas för att lagra heltal i ett binärt träd: struct int_bt_node int i; struct int_bt_node struct int_bt_node ; *left; *right; Pekaren "left" pekar sålunda till det vänstra delträdet om ett sådant finns och "right" pekar till det högra delträdet om ett sådant finns. Träd kan användas för snabb lagring av och snabb sökning i sorterad data. Ett binärt träd av heltalen,,, -8, 6, 6 byggs upp så, att placeras i trädets rotnod och därefter insätts ett mindre tal till vänster om en nod och ett icke mindre tal till höger. Detta illustreras nedan ( = pekarvärdet NULL): struct int_bt_node *pivot, *ny; tomt träd lägg till lägg till lägg till 3

Algoritmer och Datastrukturer Kary FRÄMLING/Göran PULKKIS (v23) Kap. 7, Sid 2 lägg till 8-8 Lägg till 6-8 6 Lägg till 6-8 6 6 Insättning av ett talvärde (t.ex.) i det binära trädet kan programmeras med om funktionen add_tal är definierad som pivot = add_tal(,pivot);

Algoritmer och Datastrukturer Kary FRÄMLING/Göran PULKKIS (v23) Kap. 7, Sid 3 struct int_bt_node *add_tal(int tal, struct int_bt_node *trad) struct int_bt_node *ny; ny = (struct int_bt_node *)malloc(sizeof(struct int_bt_node)); ny->i = tal; ny->left = ny->right = NULL; return add_nod(ny,trad); och funktionen add_nod är rekursivt definierad som struct int_bt_node *add_nod(struct int_bt_node *nynod, struct int_bt_node *gamtrad) if (gamtrad == NULL) return nynod; if (nynod->i < gamtrad->i) gamtrad->left = add_nod(nynod,gamtrad->left); else gamtrad->right = add_nod(nynod,gamtrad->right); return gamtrad; Heltalen sparas sorterade i det binära trädet. Utskrift av varje heltal på egen rad börjande från det minsta heltalet sker med anrop av de rekursiva funktionen void visa(struct int_bt_nod *rot) if (rot!= NULL) visa(rot->left); printf( %d\n,rot->i); visa(rot->right); Exempel 1. Modulärt programmerat binärt träd för sortering av bokstäver (kompilerat och kört). /* BinTree.h */ typedef struct bt_node char c; struct bt_node *left; struct bt_node *right; BinTreeNode; typedef struct BinTreeNode *pivot; BinTree; BinTree *newbintree(void); int add(bintree *bt, char c); int removenode(bintree *bt, char c); void show(bintree *bt); void freebintree(bintree *bt);

Algoritmer och Datastrukturer Kary FRÄMLING/Göran PULKKIS (v23) Kap. 7, Sid 4 /* BTmain.c */ #include <stdio.h> #include <string.h> #include "BinTree.h" main() BinTree *bt; char inp_str[] = "hejsan allihopa!"; int i; /* Vi skapar en ny ko */ bt = newbintree(); /* Vi satter in hela teckenstrangen */ for ( i = ; i < strlen(inp_str) ; i++ ) add(bt, inp_str[i]); /* Visa tradets innehall */ show(bt); /* Frigor minnet */ freebintree(bt); /* BinTree.c */ #include <stdio.h> #include <stdlib.h> #include "BinTree.h" static void recadd(bintreenode **root, BinTreeNode *newnode); static void recshow(bintreenode *root); static void recfree(bintreenode *root); BinTree *newbintree(void) return (BinTree*) calloc(1, sizeof(bintree)); int add(bintree *bt, char c) BinTreeNode *new_node; new_node = (BinTreeNode*) calloc(1, sizeof(bintreenode)); new_node->c = c; if ( new_node == NULL ) return ; recadd(&bt->pivot, new_node); return 1; void show(bintree *bt) recshow(bt->pivot); printf("\n");

Algoritmer och Datastrukturer Kary FRÄMLING/Göran PULKKIS (v23) Kap. 7, Sid 5 void freebintree(bintree *bt) recfree(bt->pivot); bt->pivot = NULL; static void recadd(bintreenode **root, BinTreeNode *newnode) if ( *root == NULL ) *root = newnode; else if ( (*root)->c > newnode->c ) recadd(&(*root)->left, newnode); else recadd(&(*root)->right, newnode); static void recshow(bintreenode *root) if ( root!= NULL ) recshow(root->left); putchar(root->c); recshow(root->right); static void recfree(bintreenode *root) if ( root!= NULL ) recfree(root->left); recfree(root->right); free(root); Programmet körs:!aaaehhijllnops Programmet sorterar alltså tecknen i teckensträngen "hejsan allihopa!", vilket fungerar fint i och med att vi endast har små tecken som finns i det engelska alfabetet. Alla operationer på trädet görs rekusivt, vilket är typiskt för trädstrukturer. Den algoritm som systematiskt används här kallas för "depth-first" eftersom den alltid går till ändan på varje gren före den fortsätter med följande. En annan algoritm som kallas för "breadth-first" går igenom trädet en nivå i taget. Insättningen av en ny nod är en relativt enkel operation. Däremot är det mera komplicerat att plocka bort en nod, eftersom vi måste behandla tre specialfall skilt, d.v.s. om noden har noll, en eller två söner.

Algoritmer och Datastrukturer Kary FRÄMLING/Göran PULKKIS (v23) Kap. 7, Sid 6 För att implementera borttagandet av en nod börjar tilläggs följande funktionsdeklarationer i filen "BinTree.c": static BinTreeNode *recremove(bintreenode *node, char c); static BinTreeNode *findmin(bintreenode *node); Sedan modifieras "main"-funktionen så att två bokstäver plockas bort från trädet, varefter trädets innehåll visas pånytt: /* Plocka bort ett par noder och visa panytt. */ removenode(bt, 'a'); removenode(bt, 'i'); show(bt); Funktionsdefinitionerna ser ut enligt följande: int removenode(bintree *bt, char c) if ( bt == NULL bt->pivot == NULL ) return ; return ( recremove(bt->pivot, c) == NULL )? : 1; static BinTreeNode *recremove(bintreenode *node, char c) BinTreeNode *tmp, *child; if ( node == NULL ) return NULL; /* Icke hittad! */ else if ( c < node->c ) /* Vanster */ node->left = recremove(node->left, c); else if ( c > node->c ) /* Hoger */ node->right = recremove(node->right, c); else if ( node->left && node ->right ) /* Tva soner */ tmp = findmin(node->right); node->c = tmp->c; node->right = recremove(node->right, node->c); else /* En eller ingen son */ tmp = node; if ( node->left == NULL ) child = node->right; if ( node->right == NULL ) child = node->left; free(tmp); return child; return node; static BinTreeNode *findmin(bintreenode *node) while ( node->left!= NULL ) node = node->left; return node; Först granskas att trädet existerar och att det inte är tomt. Annars söks den nod som skall förstöras.

Algoritmer och Datastrukturer Kary FRÄMLING/Göran PULKKIS (v23) Kap. 7, Sid 7 I det här exemplet antas att noden hittas. Om noden inte hittas fungerar detta program inte alltid rätt! Principen för borttagning av en nod för de tre möjliga fallen är följande: 1. Inga söner: noden kan tas bort direkt och NULL returneras som nytt pekarvärde. 2. En son: noden kan tas bort direkt och pekaren till nodens son returneras. 3. Två söner: den minsta noden n min i det högra delträdet uppsökes, dess värde ersätter det gamla värdet för den nod som skall tas bort, varefter vi kan plocka bort noden n min. Andra mycket använda trädstrukturer är så kallade "B-trees", vars noder kan ha flera än två söner. Detta kan vara fördelaktigt för att göra det skapade trädet mera balanserat t.ex. för sökning. Sorteringen som utförs i föregående exempel ger ett välbalanserat träd om den första bokstaven råkar vara ungefär i mitten av alfabetet. I ett sådant träd blir framförallt sökning mycket effektivt. Om bokstäverna däremot är färdigt sorterade får vi ett helt obalanserat träd. För att undvika detta har algoritmer utvecklats för att balansera träd. Dessa behandlas dock inte i denna kurs.