Top Banner
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
23

Föreläsning 5

Mar 22, 2016

Download

Documents

idalee

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. Terminologi - träd. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Föreläsning 5

Föreläsning 5

TrädBinära trädBinärt sökträd som ADTImplementering av binärt sökträdTravestera binärt sökträdSökningInsättning/borttagning

Page 2: Föreläsning 5

Terminologi - träd

Ett träd i datalogi består av en rotnod och ett ändligt antal underträd(subtrees)Trädets höjd är antaletnivåer (4 i exemplet).

Ett träd är en graf där man kan ta sig mellan två noder på endast ett sätt. N noder ger N-1 bågar.

Vi kommer främst titta på binära träd.

nivå 0

nivå 1

nivå 2

nivå 3

Page 3: Föreläsning 5

Binära träd

Ett binärt träd är ett träd där varje nod har maximalt 2 barn

Definition:Ett binärt träd är antingen tomt eller så har rotnoden 2 underträd (subtree) som också är binära träd (vänster och höger underträd).

Page 4: Föreläsning 5

Binärt sökträd (BST)

Ett binärt sökträd är ett binärt träd som är ordnat efter nodernas nycklar

För godtycklig nod gäller alla nycklar i nodens vänstra underträdet är mindre än nodens

nyckel alla nycklar i nodens högra underträdet är större än nodens

nyckel vänster och höger underträd är också binära sökträd varje nod är unik (inga kopior)

Page 5: Föreläsning 5

Traversera

Att besöka alla noder i ett träd kallas att traversera trädet.

Tre traverseringsordningar: Inorder. Besök först trädets vänstra del, sedan noden

själv och sist trädets högra del. (1,2,3,4,5,6,7) Preorder. Besök först noden själv, sedan trädets

vänstra del och sist trädets högra del. (4,2,1,3,6,5,7) Postorder. Besök först trädets vänstra del, sedan

trädets högra del och sist noden själv. (1,3,2,5,7,6,4)

Normalt använder vi inorder.

Page 6: Föreläsning 5

Binärt sökträd som ADT

Är skapat för att lätt kunna söka och lägga till och ta ut (log n). För att det ska fungera måste trädet vara bra balanserat.

Operationer: searchTree(nyckel)insertTree(element)deleteTree(nyckel)

Page 7: Föreläsning 5

binarySearchTree.htypedef struct{ char key[WORDLENGTH];} Data;typedef struct treeNode TreeNode;struct treeNode{ Data element; TreeNode *left, *right;};typedef struct{ TreeNode *root;}BinaryTree;BinaryTree *initBinaryTree();void insertTree(BinaryTree *bp,Data e);void inOrder(BinaryTree *bp);Data *searchTree(BinaryTree *bp,char key[]);…

Page 8: Föreläsning 5

binarySearchTree.c - initiera

#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <string.h>#include "binarySearchTree.h"

BinaryTree *initBinaryTree(){ BinaryTree *bp = (BinaryTree*)malloc(sizeof(BinaryTree)); bp->root = NULL; return bp;}…

Page 9: Föreläsning 5

binarySearchTree.c - traverseravoid inOrder(BinaryTree *bp){ inOrderNode(bp->root);}

void inOrderNode(TreeNode *np){ if(np!=NULL) { inOrderNode(np->left); printf("%s,",(np->element).key); inOrderNode(np->right); }}

Det här extrasteget hade vi sluppit om vi inte använt en speciell datastrukturför att representera ett träd utan helt enkelt använt en pekare av typenTreeNode och kallat den root. Det steget kommer nu behövas på alla funktionervi väljer att lösa rekursivt.

Page 10: Föreläsning 5

binarySearchTree.c – sätta in

void insertTree(BinaryTree *bp,Data e){ TreeNode *newNode = (TreeNode*)malloc(sizeof(TreeNode)); newNode->element = e; newNode->left=newNode->right=NULL; if(bp->root==NULL) bp->root=newNode; else insertNodeInTree(bp->root,newNode);}

Page 11: Föreläsning 5

binarySearchTree.c sätta invoid insertNodeInTree(TreeNode *tree,TreeNode *newNode){ int komp=strcmp((tree->element).key,(newNode->element).key); assert(komp!=0); if(komp<0) { if(tree->right==NULL) tree->right=newNode; else insertNodeInTree(tree->right,newNode); } else { if(tree->left==NULL) tree->left=newNode; else insertNodeInTree(tree->left,newNode); }}

Page 12: Föreläsning 5

binarySearchTree.c - söka

Data *searchTree(BinaryTree *bp,char key[]){ if(bp->root==NULL) return NULL; else { TreeNode *found = searchTreeNode(bp->root, key); if(found!=NULL)

return &(found->element); else

return NULL; }}

Page 13: Föreläsning 5

binarySearchTree.c - söka

TreeNode *searchTreeNode(TreeNode *tree, char key[]){ int komp=strcmp((tree->element).key,key); if(komp==0) return tree; else if(komp<0){ if(tree->right==NULL) return NULL; else return searchTreeNode(tree->right,key); }else{ if(tree->left==NULL) return NULL; else return searchTreeNode(tree->left,key); }}

Page 14: Föreläsning 5

Ta bort från binärt sökträd

Det finns tre fall att ta hänsyn till när vi tar bort en nod:noden är ett lövnoden har bara ett subträdnoden har både vänster och höger subträd

Fall 1 är trivialt: vi sätter helt enkelt förälderns relevanta subträd till NULL

Page 15: Föreläsning 5

Noden har bara ett subträd

Också relativt enkelt. Vi ersätter helt enkelt noden med dess barn.

Ex: Vi ska ta bort 4:

8

4

6

9

75

8

6

9

75

Page 16: Föreläsning 5

Noden har både vänster och höger subträd

Vi måste nu lösa vad vi ska göra med de två barnen. Lösningen är att vi ersätter noden med den minsta noden i det högra underträdet. Denna kan inte ha något vänsterbarn (den är ju minst) och därmed lätta att ta bort (fall 2)

Ex: vi vill ta bort nod B.

H

B

E

N

FC

A

D

H

C

E

N

F

A

D

Page 17: Föreläsning 5

deleteNode

För att implementera deleteTree kommer vi att skapa en intern hjälpfunktion som tar som parameter en pekare till noden som ska tas bort och returnerar en pekare till rotnoden till det nya subträdet. I exemplet nedan skickar man in en pekare till B och funktionen returnerar en pekare till C med underträdet i den högra bilden:

H

B

E

N

FC

A

D

H

C

E

N

F

A

D

Page 18: Föreläsning 5

deleteNode - hjälpfunktionTreeNode *deleteNode(TreeNode *np){ TreeNode *newSubTree; if(np==NULL) return NULL; else if(np->right==NULL){ newSubTree=np->left; free(np); return newSubTree; }else if(np->left==NULL){ newSubTree=np->right; free(np); return newSubTree; }else{…

HB N

AH

B

E

N

Page 19: Föreläsning 5

hjälpfunktion forts.… TreeNode *parentToMin; TreeNode *minOfRightTree; minOfRightTree = np->right; if(minOfRightTree->left==NULL){ minOfRightTree->left=np->left; free(np); return minOfRightTree; } while(minOfRightTree->left!=NULL){ parentToMin = minOfRightTree; minOfRightTree = minOfRightTree->left; } parentToMin->left = minOfRightTree->right; minOfRightTree->left=np->left; minOfRightTree->right=np->right; free(np); return minOfRightTree; }}

HB

E

N

FA

HB

EN

FCA

Dparent

min

Page 20: Föreläsning 5

deleteNode -gränssnittsfunktion

Data deleteTree(BinaryTree *bp,char key[]){ Data d; bp->root=deleteNodeTree(bp->root,key,&d); return d;}

Observera hur deletNodeTree ska returnera en pekare till hela det nya trädet!Den kommer sedan rekursivt leta sig ner i trädet mot rätt nod och hela tiden returnera en pekare till trädet där den är tills den hittar rätt nod. Då skickar den denna till vår hjälpfunktion som returnerar en pekare till det nya trädet.

Page 21: Föreläsning 5

deleteNode –söker upp rätt nodTreeNode *deleteNodeTree(TreeNode *tree,char key[],Data *d){ int komp=strcmp((tree->element).key,key); if(komp==0){ *d = tree->element; return deleteNode(tree); }else if(komp<0){ if(tree->right==NULL) return tree;//fanns ej else{ tree->right = deleteNodeTree(tree->right,key,d); return tree; } }else{ if(tree->left==NULL) return tree;//fanns ej else{ tree->left = deleteNodeTree(tree->left,key,d); return tree; }}}

Page 22: Föreläsning 5

Inlämningsuppgifter

Följande uppgifter redovisas senast måndag den 6 februari och kan inte redovisas senare:5.5, 5.A, 5.B, 5.C/5.7, 5.D, 5.E

Dessa uppgifter bör göras nu för att ni ska kunna följa kursen på ett bra sätt. Övriga kan ni göra vid tillfälle för högre betyg.

Page 23: Föreläsning 5

Uppgifter ej i bokenUtgå från föreläsningens implementering av ett binärt sökträd när du löser nedanstående uppgifter 5.A

Skriv en main som läser in sju ord från användaren och placerar dessa i ett BST. Kör programmet och skriv in 7 ord så att trädet får minsta möjliga höjd. Kör programmet och skriv in 7 ord så att trädet får maximal höjd. (2p)

5.BSkriv funktioner som traverserar trädet med preOrder och inOrder.(1p)

5.CSkriv två funktioner numberOfLeaves och numberOfNodes till vår implementation från föreläsningen.(2p)

5.DSkriv om sökfunktionen så att den är iterativ istället för rekursiv.

(3p) 5.E

Skriv en funktion maximum som returnerar det största värdet i ett binärt sökträd. Skriv en rekursiv och en iterativ version.(2p)