ΠΛΗ111 οµηµένος Προγραµµατισµός Ανοιξη 2005 Μάθηµα 7 ο έντρο Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης
έντρο Ορισµός Υλοποίηση µε Πίνακα Υλοποίηση µε είκτες υαδικό έντρο Αναζήτησης Εφαρµογή: Κώδικας Huffman Ανάλυση υαδικού έντρου Αναζήτησης Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 2
Ορισµός έντρου Ένα n-αδικό δέντρο ορίζεται αναδροµικά ως εξής: Ένας µοναδικός κόµβος που ονοµάζεται ρίζα και n, n >= 0, ξένα µεταξύ τους δέντρα Τ 1, Τ 2,..., Τ n που ονοµάζονται υποδέντρα της ρίζας 23 45 12 89 4 52 11 8 77 65 9 Βαθµοί Βαθµός κόµβου είναι το πλήθος των υποδέντρων του Βαθµός δέντρου είναι ο µέγιστος βαθµός των κόµβων του υαδικό είναι ένα δέντρο βαθµού 2 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 3
Ορισµός έντρου(2) Φύλλα είναι οι κόµβοι που έχουν βαθµό µηδέν Εσωτερικοί είναι κόµβοι που δεν είναι φύλλα Παιδιά ενός κόµβου είναι οι ρίζες των υποδέντρων του Πατέρας είναι ένας κόµβος για κάθε ένα παιδί του Το επίπεδο του κόµβου ορίζεται αναδροµικά Το επίπεδο της ρίζας είναι 1 Αν ένας κόµβος βρίσκεται στο επίπεδο i, τα παιδιά του βρίσκονται στο επίπεδο i+1 Ύψος ή βάθος δέντρου είναι το µέγιστο επίπεδο των κόµβων του άσος είναι ένα σύνολο από n, n>=0, δέντρα ξένα µεταξύ τους Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 4
Ιδιότητες έντρων Πρόταση: Ο µέγιστος αριθµός κόµβων στο επίπεδο i ενός δέντρου βαθµού d είναι d i-1, i>= 1. Απόδειξη: Επαγωγικά. Η πρόταση ισχύει για i=1, εφόσον υπάρχει µόνο µία ρίζα για d i-1 = d 0 = 1. Υποθέτουµε ότι η πρόταση ισχύει για i=k και έχουµε d k-1 το πολύ κόµβους στο επίπεδο k. Εφόσον κάθε κόµβος στο επίπεδο k έχει το πολύ d υποδέντρα, το µέγιστο πλήθος κόµβων στο επίπεδο k+1 είναι d x d k-1 = d k. Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 5
Ιδιότητες έντρων (2) Πρόταση: Ο µέγιστος αριθµός κόµβων ενός δέντρου βαθµού d και ύψους h είναι (d h -1)/(d-1). Απόδειξη: Ο µέγιστος αριθµός κόµβων σε ένα δυαδικό δέντρο h είναι: h i= 1 h i= 1 ( µέγιστος αριθµός κόµβων στο επίπεδο i) d i 1 = 1+ d + d 2 +... + d h 1 = d d h 1 1 = Άρα το ελάχιστο ύψος δυαδικού δέντρου µε n κόµβους 2 h 1 >= n ή h >= log 2 (n+1) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 6
Ιδιότητες υαδικών έντρων Πρόταση: Αν ένα µη κενό δυαδικό δέντρο έχει n0 φύλλα (κόµβους βαθµού 0) και n2 κόµβους βαθµού 2, τότε n0 = n2+1. Απόδειξη: Αν το δέντρο έχει n1 κόµβους βαθµού 1, τότε συνολικά έχει n κόµβους: n = n0 + n1 + n2. Επειδή κάθε κόµβος εκτός της ρίζας είναι παιδί κόµβου είτε βαθµού 1 ή βαθµού 2 έχουµε: n = 1 + n1 + 2n2. Άρα αφαιρώντας τις δύο ισότητες έχουµε: n0 = 1+n2. Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 7
Πράξεις υαδικών έντρων create(): δηµιουργία κενού δυαδικού δέντρου empty(): ελέγχει αν το δέντρο είναι κενό left(): επιστρέφει το αριστερό παιδί του κόµβου right(): επιστρέφει το δεξί παιδί του κόµβου 23 45 12 89 4 52 11 8 77 65 9 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 8
1η Υλοποίηση µε Πίνακα Θεωρούµε δυαδικό δέντρο µε n κόµβους Η ρίζα αποθηκεύεται στη θέση 1 ενός πίνακα Το αριστερό παιδί του κόµβου i αποθηκεύεται στη θέση 2i, αν 2i <= n, αλλιώς δεν υπάρχει αριστερό παιδί To δεξί παιδί του κόµβου i αποθηκεύεται στη θέση 2i+1, αν 2i+1 <= n, αλλιώς δεν υπάρχει δεξί παιδί εν αξιοποιεί όλη τη µνήµη του πίνακα! a 1 2 3 4 5 a b c d e b c 6 - d e f 7 f Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 9
2η Υλοποίηση µε Πίνακα Συνδεδεµένη αναπαράσταση #define N /* µέγεθος πίνακα */ typedef struct { data_t data; int left, right; 1 2 a b 2 3 4 5 } node_t; 3 c - 6 typedef node_t tree_t[n]; 4 d - - a 5 e - - b c 6 f - - d e f Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 10
Υλοποίηση µε είκτες typedef struct node *nodeptr_t; typedef struct node { data_t data; b nodeptr_t left, right; } node_t; nodeptr_t root; a c d e f a root #define empty(r) ((r) == NULL) void create(nodeptr_t *root) { *root = NULL; } d b e c f #define left(r) ((r)?((r)->left):null) #define right(r) ((r)?((r)->right):null) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 11
ιαδροµή υαδικών έντρων ιαδροµή δέντρου: Επίσκεψη κάθε κόµβου µόνον µια φορά Τρία βήµατα: 1. Επίσκεψη ρίζας (Κ) 2. ιαδροµή αριστερού υποδέντρου (Α) 3. ιαδροµή δεξιού υποδέντρου ( ) Προδιατεταγµένη διαδροµή: ΚΑ Ενδοδιατεταγµένη διαδροµή: ΑΚ Μεταδιατεταγµένη διαδροµή: Α Κ Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 12
Προδιατεταγµένη ιαδροµή preorder(r) if (!r) return; visit(r); preorder(left(r)) preorder(right(r)) b a c d e f g h i j Προδιατεταγµένη ιαδροµή: a b d g e h c f i j Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 13
Ενδοδιατεταγµένη ιαδροµή inorder(r) if (!r) return preorder(left(r)) visit(r) preorder(right(r)) b a c d e f g h i j Ενδοδιατεταγµένη ιαδροµή: d g b h e a c i f j Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 14
Μεταδιατεταγµένη ιαδροµή postorder(r) if (!r) return preorder(left(r)) preorder(right(r)) visit(r) b a c d e f g h i j Μεταδιατεταγµένη ιαδροµή: g d h e b i j f c a Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 15
υαδικό έντρο Αναζήτησης Ορισµός υαδικό δέντρο το οποίο είτε είναι κενό ή κάθε κόµβος του περιέχει δεδοµένα µε κλειδί Όλα τα κλειδιά στο αριστερό υποδέντρο του είναι µικρότερα από το κλειδί της ρίζας Όλα τα κλειδιά στο δεξί υποδέντρο είναι µεγαλύτερα από το κλειδί της ρίζας Το αριστερό και το δεξί υποδέντρο είναι επίσης δυαδικά δέντρα αναζήτησης x <x >x Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 16
Αναδροµική Αναζήτηση typedef struct node *nodeptr_t; typedef struct node { int key; nodeptr_t left, right; } node_t; key nodeptr_t search(nodeptr_t root, char *key) { if (!root) return NULL; if (key == root->key) return root; if (key < root->key) return search(root->left, key); else return search(root->right, key); } <key >key Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 17
Αναδροµική Εισαγωγή Στοιχείου void insert(nodeptr_t *root, int key) { if (!*root) { *root = (nodeptr_t) malloc(sizeof(node_t)); (*root)->key = key; (*root)->left = (*root)->right = NULL; return; } k root } if (key < (*root)->key) insert(&((*root)->left), key); else if (key > (*root)->key) insert(&((*root)->right), key); else printf( το κλειδί υπάρχει ήδη ); b d p r Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 18
Αναδροµική ιαγραφή Στοιχείου void delete(nodeptr_t *root, int key) { if (!*root) return; if (key == (*root)->key) if (!(*root)->left) { /* left NULL */ nodeptr_t temp = *root; *root = (*root)->right; free(temp); } else if (!(*root)->right) { /* right NULL */ nodeptr_t temp = *root; *root = (*root)->left; free(temp); } else { /* find next inorder */ nodeptr_t inext = (*root)->right; while (inext->left!= NULL) inext = inext->left; /* copy next inorder */ *root->key = inext->key; /* delete next inorder */ delete(&(*root)->right, (*root)->key); } else if (key < (*root)->key) delete(&((*root)->left), key) else delete(&((*root)->right), key); } b d k root p r Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 19
Κώδικες Μεταβλητού Μήκους Συνήθως αναπαριστούµε χαρακτήρες µε κώδικα µήκους 8 bit Για παράδειγµα σε ASCII ο χαρακτήρας Α γίνεται 01000001 Θα προτιµούσαµε να έχουµε κώδικα µεταβλητού µήκους Λιγότερα bits για συχνούς χαρακτήρες O κώδικας µεταβλητού µήκους πρέπει να είναι prefix-free Κανένας κώδικας χαρακτήρα δεν είναι πρόθεµα άλλου κώδικα Παράδειγµα διφορούµενου κώδικα! a 0 b 1 c 10 d 11 0 1 a b 0 1 c d Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 20
υαδικό έντρο Κώδικα Φυσική σχέση µεταξύ δυαδικών δέντρων και prefix-free κωδίκων Θέτουµε 0 και 1 στο αριστερό και δεξί παιδί κάθε κόµβου αντίστοιχα Για κάθε φύλλο λ διατρέχουµε το µονοπάτι ξεκινώντας από τη ρίζα Η συµβολοσειρά που προκύπτει αντιστοιχεί στον κώδικα του λ Πρόβληµα Πως αντιστοιχούµε πλήθος bits ανάλογα µε τη συχνότητα εµφάνισης Παράδειγµα prefix-free κώδικα a 00 e 01 i 10 o 110 u 111 0 1 0 1 0 1 a e i 0 1 o u Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 21
έντρο Huffman Αντιστοιχίζουµε βάρος w i στο χαρακτήρα του φύλλου λ i Το βάρος µετράει τη συχνότητα εµφάνισης του χαρακτήρα Ορίζουµε ως σταθµισµένο µήκος εξωτερικού µονοπατιού δέντρου λ φ ύλλο του Τ ι w i ( βάθος ( λ ) 1) ι Για δεδοµένο σύνολο από χαρακτήρες και βάρη, το δέντρο µε ελάχιστο σταθµισµένο µήκος εξωτερικού µονοπατιού είναι το δέντρο Huffman Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 22
Αλγόριθµος Huffman Βήµα προετοιµασίας δάσους 1. ηµιουργούµε δάσος δέντρων µε ένα κόµβο 2. Κάθε δέντρο περιέχει έναν χαρακτήρα 3. Το βάρος κάθε δέντρου είναι το βάρος του χαρακτήρα που περιέχει Βήµα δηµιουργίας δέντρου Ενόσω το δάσος περιέχει περισσότερα του ενός δέντρα 1. Αποµακρύνουµε δύο δέντρα ελάχιστου βάρους από το δάσος 2. ηµιουργούµε νέο κόµβο πατέρα των δύο δέντρων µε βάρος νέου κόµβου = άθροισµα βαρών των δύο δέντρων 3. Προσθέτουµε το νέο δέντρο στο δάσος Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 23
Παράδειγµα Κώδικα Huffman Παράδειγµα Kώδικα Huffman Βάρη a 0.2 b 0.1 c 0.3 d 0.25 e 0.15 Κώδικας a 0 1 b 0 0 0 c 1 1 d 1 0 e 0 0 1 1.00 0 0.45 1 0 0.25 1 0.55 0 1 0 1 0.10 0.15 0.20 0.25 0.30 b e a d c Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 24
Ανάλυση υαδικού έντρου Αναζήτησης Επεκτεταµένο δυαδικό δέντρο Σε δυαδικό δέντρο αντικαθιστούµε δείκτες NULL µε κόµβους Τα νέα φύλλα του δέντρου ονοµάζονται εξωτερικοί κόµβοι Οι αρχικοί κόµβοι του δέντρου ονοµάζονται εσωτερικοί Βαθµοί κόµβων Όλοι οι εσωτερικοί κόµβοι είναι βαθµού 2 Όλοι οι εξωτερικοί κόµβοι είναι βαθµού 0 εν υπάρχουν κόµβοι βαθµού 1(n 1 = 0) Άρα απο πρόταση που αποδείξαµε Αν n 0 =n οι εσωτερικοί κόµβοι, οι εξωτερικοί κόµβοι n 2 =n+1 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 25
Παράδειγµα Επεκτεταµένου έντρου εσωτερικός κόµβος F B G A E D C εξωτερικός κόµβος Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 26
Μήκος Μονοπατιών Σε ένα επεκτεταµένο δυαδικό δέντρο Το άθροισµα του µήκους µονοπατιών εξωτερικών κόµβων E = h + 1 i= 2 s i ( i 1) όπου s i είναι το πλήθος εξωτερικών κόµβων στο επίπεδο i Το άθροισµα του µήκους µονοπατιών εσωτερικών κόµβων I = h i= 1 n i ( i 1) όπου n i το πλήθος των εσωτερικών κόµβων στο επίπεδο i Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 27
Ιδιότητες Επεκτεταµένων έντρων Το επεκτεταµένο δέντρο Τ µε n εσωτερικούς κόµβους Έχει n+1 εξωτερικούς κόµβους Αποτελείται από τα υποδέντρα T l και T r Τα T l και T r έχουν n+1 εξωτερικούς κόµβους Η ρίζα αυξάνει κατά 1 το µήκος µονοπατιού τους E(T) = E(T l ) + E(T r ) + n + 1 Τα T l και T r έχουν n-1 εσωτερικούς κόµβους Η ρίζα αυξάνει κατά 1 το µήκος µονοπατιού τους I(T) = I(T l ) + I(T r ) + n 1 T T l T r Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 28
Ειδικές Περιπτώσεις Έστω D(T) = E(T) I(T) Από τις προηγούµενες ισότητες των Ε(Τ) και Ι(Τ) D(T) = D(T l ) + D(T r ) + 2 = 2n (επαγωγικά) Άρα Ε(Τ) = Ι(Τ) + 2n => min(e(t)) = min(i(t)) + 2n Το µέγιστο Ι(Τ) επιτυγχάνεται µε γραµµική λίστα Ι(Τ) = 0 + 1 +... + (n-1) [= n(n-1)/2] Το ελάχιστο Ι(Τ) επιτυγχάνεται µε πλήρες δυαδικό δέντρο Ι(Τ) = 0 + 2 x 1 + 4 x 2 +... + (2 log 2 (n+1)-1 ) x log 2 (n+1) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 29
Ανάλυση Αναζήτησης Θεωρούµε επεκτεταµένο δέντρο µε n εσωτερικούς κόµβους Κάθε επιτυχηµένη αναζήτηση καταλήγει σε εσωτερικό κόµβο Αν I το συνολικό µήκος µονοπατιού εσωτερικών κόµβων Το µέσο πλήθος των συγκρίσεων που απαιτούνται S(n) = 1 + Ι/n Κάθε αποτυχηµένη αναζήτηση καταλήγει σε εξωτερικό κόµβο Αν Ε το συνολικό µήκος µονοπατιού εξωτερικών κόµβων Το πλήθος των εξωτερικών κόµβων είναι n+1 Το µέσο πλήθος των συγκρίσεων που απαιτούνται U(n) = E/(n+1) Εφόσον Ε = Ι + 2n, προκύπτει ότι S(n) = (1 + 1/n) U(n) -1 (1) Κάθε επιτυχηµένη αναζήτηση αντιστοιχεί σε εισαγωγή ενός κόµβου µετά απο µία αποτυχηµένη αναζήτηση S(n) = 1 + (U(0) + + U(n-1))/n (2) Από τις (1) και (2): U(n) = 2[1/2 + 1/3 + 1/(n+1)] ~ 2ln(n) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 30