B-Δένδρα Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: 2-3 Δένδρα, Υλοποίηση και πράξεις Β-δένδρα ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-1
2-3 Δένδρα Γενίκευση των δυαδικών δένδρων αναζήτησης. Ορισµός: Κάθε κόµβος περιέχει ένα ή δύο κλειδιά. Ένας εσωτερικός κόµβος u µε ένα κλειδί, k 1 έχει δύο παιδιά (υπόδενδρα): το αριστερό, u.left, το οποίο περιέχει κλειδιά < k 1, και το µεσαίο, u.center, το οποίο περιέχει κλειδιά > k 1. Ένας εσωτερικός κόµβος u µε δύο κλειδιά, k 1 < k 2, έχει τρία παιδιά, το αριστερό, u.left, το µεσαίο, u.center, και το δεξί, u.right. Όλα τα κλειδιά του υποδένδρου u.left είναι < k 1, όλα τα κλειδιά του u.center είναι > k 1 και < k 2 και όλα τα κλειδιά του u.right είναι > k 2. Όλα τα φύλλα βρίσκονται στο ίδιο επίπεδο. k 1 < k 1 > k 1 k 1 k 2 > k < k 2 1 k 1 < x< k 2 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-2
Παράδειγµα 2-3 Δένδρου 18 33 12 23 30 48 10 15 45 47 50 52 20 21 24 31 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-3
Υλοποίηση 2-3 Δένδρων Ένας κόµβος 2-3 Δένδρου µπορεί να παρασταθεί ως µια εγγραφή µε 6 πεδία: 1. numkeys, τύπου int, που δηλώνει τον αριθµό των κλειδιών που περιέχει ο κόµβος, 2. key1, όπου αποθηκεύεται το πρώτο κλειδί, 3. key2, όπου αποθηκεύεται το δεύτερο κλειδί, αν υπάρχει, 4. left, τύπου δείκτη, που δείχνει στο αριστερό παιδί του κόµβου, 5. center, τύπου δείκτη, που δείχνει στο µεσαίο παιδί του κόµβου, 6. right, τύπου δείκτη, που δείχνει στο δεξί παιδί του κόµβου αν υπάρχει. Ένα δένδρο αναπαρίσταται ως ένας δείκτης σε κόµβο 2-3 δένδρου (που δείχνει στη ρίζα) και επιτρέπει τις πράξεις εισαγωγής, διαγραφή και αναζήτησης. ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-4
Ιδιότητες 2-3 δένδρου Αν Ν(h) είναι ο µικρότερος αριθµός κλειδιών ενός 2-3 δένδρου ύψους h, τότε Ν(0) = 1, Ν(h) = 1 + 2 N(h-1) Αν M(h) είναι ο µεγαλύτερος αριθµός κλειδιών ενός 2-3 δένδρου ύψους h, τότε M(0) = 2, M(h) = 2 + 3 M(h-1) Ο αριθµός κλειδιών ενός 2-3 δένδρου ύψους h είναι το πολύ 3 h+1 1 και το λιγότερο 2 h+1 1. Εποµένως, το ύψος ενός 2-3 δένδρου µε n κόµβους είναι O(log n). Η διαδικασία εύρεσης στοιχείου σε ένα 2-3 δένδρο είναι εύκολη (παρόµοια µε αυτή ενός ΔΔΑ). Ο χρόνος εκτέλεσης της είναι τάξης. O(lg n) ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-5
Εισαγωγή κόµβου σε ένα 2-3 δένδρο Η εισαγωγή κάποιου κλειδιού k σε ένα 2-3 Δένδρο µπορεί να χωριστεί στις ακόλουθες 3 λογικές φάσεις 1. Καθοδική Φάση (Downward Phase) Σε αυτή την φάση διανύουµε αναδροµικά το δένδρο µέχρι να φθάσουµε σε τερµατικό κόµβο (δηλαδή κάποιο φύλλο). Δηλαδή: αν k<u.key1 τότε προχώρα στον κόµβο u.left αν k>u.key2 τότε προχώρα στον κόµβο u.right αν u.key1 < k < u.key2 τότε προχώρα στον κόµβο u.center. 2. Τερµατική Φάση (Terminal Phase) Όταν φτάσουµε σε φύλλο τότε προσπαθούµε να κάνουµε την εισαγωγή Αν δεν έχει αρκετό χώρο τότε διασπάτε το φύλλο και «ανασηκώνουµε» (kick up) αναδροµικά το µεσαίο στοιχείο στον πατέρα) 3. Ανοδική Φάση (Upward Phase) Σε αυτή την φάση κάνουµε την εισαγωγή αν δεν πετύχαµε εισαγωγή στην τερµατική φάση.
Περιγραφή Κάποιων Συµβολισµών Στις επόµενες διαφάνειες θα χρησιµοποιήσουµε τους ακόλουθους συµβολισµούς Το στοιχείο το οποίο θέλουµε να εισάγουµε Ο κόµβος Χ Το υπόδενδρο r Τερµατικός Κόµβος µε 2 κενούς δείκτες
1) Καθοδική Φάση (Downward Phase) Εισαγωγή του στοιχείου v Η ρίζα περιέχει 1 στοιχείο insert insert Εισαγωγή του στοιχείου v η ρίζα περιέχει 2 στοιχεία Προσοχή: Σε αυτή την φάση απλά ζητάµε σε ένα από τα υποδένδρα να χειριστεί την εισαγωγή αλλα δεν κανουµε την εισαγωγη
2) Τερµατική Φάση (Terminal Phase) Όταν φτάσουµε σε τερµατικό κόµβο και υπάρχει χώρος τότε µπορούµε να κάνουµε την εισαγωγή κατευθείαν. Δηλαδή: Αν δεν υπάρχει χώρος τότε διασπάτε (split) ο τερµατικός κόµβος και προάγετε (kick-up) το µεσαίο στοιχείο στον πατέρα (δες επόµενη διαφάνεια)
2) Τερµατική Φάση (Terminal Phase) συνέχεια Αναλυτικά οι υπό-φάσεις της Διάσπασης (Split) και Προαγωγής (Kick-up) Kick up insert Kick up split split Kick up insert split
3: Ανοδική Φάση (Upward Phase) Όταν φτάσουµε στον πατέρα και υπάρχει χώρος τότε µπορούµε να κάνουµε την εισαγωγή κατευθείαν. Δηλαδή: Kick up Kick up Αν δεν υπάρχει χώρος τότε πρέπει να διασπαστεί ο πατέρας και να προαχθεί (kick-up) το µεσαίο στοιχείο στον πατέρα του πατέρα (δες επόµενη διαφάνεια)
3: Ανοδική Φάση (Upward Phase) συνέχεια Όταν φτάσουµε στον πατέρα και δεν υπάρχει χώρος τότε αναδροµικά διασπάµε τον πατέρα µέχρι να εισαχθεί το στοιχείο. Αν διασπαστεί η ρίζα τότε αυξάνεται και το ύψος του δένδρου κατά 1! : w <= X < Y X <= w < Y X <= Y < w
Ολοκληρωµένο Παράδειγµα Εισαγωγής Παράδειγµα εισαγωγής της λέξης A L G O R I T H M S (γράµµαγράµµα) σε ένα κενό 2-3 δένδρο. συνέχεια στην επόµενη διαφάνεια
Ολοκληρωµένο Παράδειγµα Εισαγωγής (συνέχεια)
Εισαγωγή κόµβου Για την εισαγωγή κλειδιού k σε ένα 2-3 Δένδρο ακολουθούµε το µονοπάτι από τη ρίζα του δένδρου µέχρι το κατάλληλο φύλλο u. Υπάρχουν δύο περιπτώσεις 1. Αν ο u περιέχει µόνο 1 κλειδί, τότε προσθέτουµε το k στον u. 2. Αν ο u περιέχει 2 κλειδιά έστω k 1 και k 2, τότε δηµιουργούµε ένα καινούριο κόµβο v, και διαµοιράζουµε τα κλειδιά του u, και το καινούριο κλειδί k έτσι ώστε: ο u να πάρει το µικρότερο των κλειδιών και ο v το µεγαλύτερο. Ο δείκτης προς τον v και το µεσαίο κλειδί, m, µεταβιβάζεται στον πατέρα w του u. Αν ο w έχει µόνο ένα κλειδί, τότε προσθέτουµε το ζεύγος (m,v) στον κόµβο w. Διαφορετικά, δηµιουργούµε ένα καινούριο κόµβο και επαναλαµβάνουµε το βήµα 2. Αυτή η διαδικασία µπορεί να συνεχιστεί µέχρι τη ρίζα του δένδρου µε αποτέλεσµα τη διάσπαση της ρίζας και την αύξηση του ύψους του δένδρου κατά 1. ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-15
Αναλυτική Περιγραφή Φάση 1 Ξεκινώντας από τη ρίζα, εφάρµοσε τον πιο κάτω αλγόριθµο σε κάθε κόµβο u µέχρι να φτάσεις σε κάποιο φύλλο, καταγράφοντας τη διαδροµή που ακολούθησες: Αν u.numkeys = 1, τότε αν k<u.key1 τότε προχώρα στον κόµβο u.left αν k>u.key1 τότε προχώρα στον κόµβο u.center αν k=u.key1 τότε σταµάτα. Αν u.numkeys = 2, τότε αν k<u.key1 τότε προχώρα στον κόµβο u.left αν k>u.key2 τότε προχώρα στον κόµβο u.right αν u.key1 < k < u.key2 τότε προχώρα στον κόµβο u.center. διαφορετικά, σταµάτα. ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-16
Τρέχον παράδειγµα εισαγωγή του 19 (1) Ξεκινώντας από τη ρίζα, p 0, ακολουθούµε και καταγράφουµε τη διαδροµή p 0, p 2, p 4. 18 33 p 0 p 1 p 2 p 3 12 23 30 48 p 4 p5 p 6 10 15 45 47 50 52 20 21 24 31 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-17
Φάση 2(α) Περίπτωση Φύλλου Έστω ότι προσθέτουµε το κλειδί k στο φύλλο u. Αν u.numkeys = 1, k 1 = u.key1, τότε u.key1 = min (k 1, k), u.key2 = max (k 1, k), u.numkeys = 2 Αν u.numkeys = 2, k 1 = u.key1, k 2 =u.key2, τότε u.key1 = min (k 1, k 2, k), u.numkeys = 1, p = (NODE *)malloc(sizeof(node)), p.numkeys = 1, p.key1 = max(k 1, k 2,k). προχώρα στη φάση 2(β) µε παραµέτρους p, mid(k 1, k 2,k) ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-18
Τρέχον παράδειγµα εισαγωγή του 19 (2) 18 33 p 0 p 1 p 2 p 3 12 23 30 48 p 4 p5 p 6 10 15 (20, q 1 ) 45 47 50 52 q 1 24 31 20 19 21 21 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-19
Φάση 2(β) Περίπτωση Εσωτερικού κόµβου Έστω ότι προσθέτουµε το κλειδί k και τον δείκτη p στον κόµβο u. Αν u.numkeys = 1, k 1 = u.key1, τότε αν k > k 1, u.key2 = k, u.right = p, αν k < k 1, u.key1 = k, u.key2 = k 1, u.right = u.center, u.center = p. u.nunkeys = 2. Αν u.numkeys = 2, k 1 = u.key1, k 2 = u.key2, u.left = p 1, u.center = p 2, u.right = p 3, τότε υπάρχουν 3 περιπτώσεις που εξαρτώνται από τη σχέση των κλειδιών k, k 1, k 2. Aς ασχοληθούµε µε την περίπτωση k < k 1 (οι άλλες δύο είναι παρόµοιες). Τότε u.key1 = k, u.center = p, u.numkeys = 1, q= (NODE *)malloc(sizeof(node)), q.numkeys = 1, q.key1 = k 2, q.left = p2, q.center = p3. αν ο u είναι η ρίζα τότε προχώρα στη φάση 3, διαφορετικά επανάλαβε τη φάση 2(β) µε παραµέτρους (q, k 1 ) στον πατέρα του u. ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-20
Τρέχον παράδειγµα εισαγωγή του 19 (3) Eισαγωγή του ζεύγους (20,q 1 ) στον κόµβο p 2. 18 33 p 0 p 1 p 2 p 3 (23, q 2 ) q 2 12 20 23 30 30 48 (20, q 1 ) p 4 p 5 p 6 10 15 q 1 45 47 50 52 q 1 24 31 19 21 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-21
Τρέχον παράδειγµα εισαγωγή του 19 (4) Eισαγωγή του ζεύγους (23,q 2 ) στον κόµβο p 0. p 0 18 33 (23, q 3 ) 33 q 3 (23, q 2 ) p 1 p 2 q 2 p 3 q 2 12 20 30 48 p 4 p 5 p 6 10 15 q 1 45 47 50 52 24 31 19 21 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-22
Φάση 3: Νέα ρίζα Αν η ρίζα r διασπαστεί και ζητήσει την εισαγωγή ζεύγους (p,k) στον ανύπαρκτο πρόγονο της στο δένδρο, τότε Δηµιούργησε ένα καινούριο κόµβο v µε ένα κλειδί k και v.left = r, v.center = p. O καινούριος κόµβος v θα είναι η νέα ρίζα του δένδρου. Έτσι, στο παράδειγµα, εισαγωγή του (q 3, 23) έχει σαν αποτέλεσµα: Root 23 p 0 18 (23,q 3 ) q 3 33 p 1 p 2 q 2 p 3 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-23
Εισαγωγή του κλειδιού 14 14 18 33 12 23 30 48 14 10 15 14 15 45 47 50 52 20 21 24 31 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-24
Εισαγωγή του κλειδιού 55 18 33 55 12 23 30 48 52 55 10 14 15 45 47 50 52 55 20 21 24 31 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-25
Εισαγωγή του κλειδιού 19 23 18 18 33 33 19 12 20 23 30 30 48 52 10 14 15 19 45 47 50 55 19 20 21 21 24 31 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-26
Διαδικασία Εισαγωγής Κόµβου Η αναδροµική διαδικασία εισαγωγής κόµβου, παίρνει παραµέτρους: 1. το δείκτη στον κόµβο όπου θα γίνει η εισαγωγή, 2. το κλειδί που θέλουµε να προσθέσουµε (κατά την κάθοδο στο δένδρο), 3. το ζεύγος (δείκτη σε παιδί, κλειδί) που θέλουµε να προσθέσουµε (κατά την άνοδο στο δένδρο). Η διαδικασία εξαγωγής κλειδιών χρησιµοποιεί παρόµοιες ιδέες. Σ αυτή όµως την περίπτωση, αντί διάσπαση κόµβου έχουµε συγχώνευση κόµβων. Όλες οι διαδικασίες έχουν χρόνο εκτέλεσης ανάλογο µε το ύψος του δένδρου. Άρα είναι τάξης Θ(log n). ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-27
Παραλλαγή Οι πληροφορίες αποθηκεύονται µόνο στα φύλλα. Τα κλειδιά εσωτερικών κόµβων χρησιµεύουν µόνο για την αναζήτηση στο δένδρο. Δηλαδή, για κάποιο κόµβο u, το u.key1 δηλώνει το µικρότερο κλειδί σε φύλλο του u.center, και το u.key2 (αν υπάρχει) δηλώνει το µικρότερο κλειδί σε φύλλο του u.right. 18 16 25 32 9 12 16 17 18 22 25 27 32 39 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-28
Β-δένδρα Γενίκευση του 2-3 δένδρου: µπορεί να αποθηκεύει περισσότερα από 2 κλειδιά σε κάθε κόµβο. Ένα δένδρο τάξης m ικανοποιεί τις πιο κάτω ιδιότητες: Έχει µια ρίζα η οποία είτε είναι φύλλο, είτε έχει 2 µέχρι m παιδιά. Όλοι οι εσωτερικοί κόµβοι (εκτός τη ρίζα) έχουν από m/2 µέχρι m παιδιά. Όλα τα φύλλα βρίσκονται στο ίδιο επίπεδο. Τα δεδοµένα φυλάσσονται στα φύλλα. Κάθε φύλλο περιέχει από m/2-1 µέχρι m 1 κλειδιά. Ένας εσωτερικός κόµβός µε δείκτες p 0, p 1,, p n, έχει κλειδιά k 1,,k n, όπου k i είναι το µικρότερο κλειδί του υποδένδρου που δείχνεται από τον δείκτη p i. Ένα 2-3 δένδρο, είναι Β-δένδρο, τάξης 3. ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-29
Παράδειγµα Β-δένδρου τάξης 4 18 3 8 25 32 43 1 2 3 4 5 8 12 18 22 23 25 27 32 39 43 47 ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-30
τάξης m µε n κλειδιά έχει ύψος Ένα Β-δένδρο Έχει διαδικασίες παρόµοιες µε αυτές ενός 2-3 δένδρου, οι οποίες επίσης µπορεί να προκαλέσουν διάσπαση ή συγχώνευση της ρίζας. Έχει το πλεονέκτηµα έναντι των 2-3 δένδρων Έχει το µειονέκτηµα Το κόστος των διαδικασιών είναι ανάλογο του (ύψος του δένδρου) (κόστος επεξεργασίας ενός κόµβου) Το κόστος επεξεργασίας ενός κόµβου Ο(m) µπορεί να γίνει O(log m) αν κάθε κόµβος οργανωθεί ως AVL-δένδρο. Σε βάσεις δεδοµένων οι κόµβοι αποθηκεύονται σε δευτερεύουσα µνήµη του υπολογιστή. Το κόστος πρόσβασης ενός κόµβου είναι πολύ µεγαλύτερο απ αυτό της επεξεργασίας του. Η τιµή του m επιλέγεται βάσει του πόσα κλειδιά µπορούν να αποθηκευτούν σε ένα καταχώρηµα (block) µνήµης. ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-31