ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. ΑΣΚΗΣΗ 3 Δέντρα

Σχετικά έγγραφα
Εργασία 3 Σκελετοί Λύσεων

Κατ οίκον Εργασία 2 Σκελετοί Λύσεων

Κατ οίκον Εργασία 3 Σκελετοί Λύσεων

Αναδροµή. Σε αυτήν την (βοηθητική) ενότητα θα µελετηθούν τα εξής : Η έννοια της αναδροµής Υλοποίηση και αποδοτικότητα Αφαίρεση της αναδροµής

Δένδρα. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα:

Διάλεξη 22: Δυαδικά Δέντρα. Διδάσκων: Παναγιώτης Ανδρέου

Διάλεξη 17: Δυαδικά Δέντρα. Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Διδάσκων: Παναγιώτης Ανδρέου

Διδάσκων: Κωνσταντίνος Κώστα

Διάλεξη 12: Δέντρα ΙΙ Δυαδικά Δέντρα

οµές εδοµένων 3 ο Εξάµηνο ΕΝΟΤΗΤΑ 4 ΕΝ ΡΑ

Ενότητες 3 & 4: Δένδρα, Σύνολα & Λεξικά Ασκήσεις και Λύσεις

Κατ οίκον Εργασία 3 Σκελετοί Λύσεων

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Πανεπιστήμιο Πειραιώς Σχολή Τεχνολογιών Πληροφορικής και Επικοινωνιών Τμήμα Ψηφιακών Συστημάτων ομές εδομένων

Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις

Διάλεξη 13: Δέντρα ΙΙΙ - Ισοζυγισμένα Δέντρα, AVL Δέντρα

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 10 Δυαδικά Δένδρα Αναζήτησης

Διάλεξη 14: Δέντρα IV B Δένδρα. Διδάσκων: Παναγιώτης Ανδρέου

Εργαστήριο 8: Αναδρομική διεργασία εισαγωγής καινούριου κόμβου σε ΔΔΑ

ΟΙΚΟΝΟΜΙΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. Δοµές Δεδοµένων

Διάλεξη 26: Σωροί. Διδάσκων: Παναγιώτης Ανδρέου

Διάλεξη 13: Δέντρα ΙΙΙ Ισοζυγισμένα Δέντρα, AVL Δέντρα. Διδάσκων: Παναγιώτης Ανδρέου

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ

Εργαστήριο 5 Αναδρομική διεργασία εισαγωγής καινούριου κόμβου σε ΔΔΑ με αλφαβητική σειρά

Διδάσκων: Παναγιώτης Ανδρέου

Δομές Δεδομένων. Καθηγήτρια Μαρία Σατρατζέμη. Τμήμα Εφαρμοσμένης Πληροφορικής. Δομές Δεδομένων. Τμήμα Εφαρμοσμένης Πληροφορικής

Διάλεξη 13: Δέντρα ΙΙΙ Ισοζυγισμένα Δέντρα, AVL Δέντρα

υαδικά έντρα Αναζήτησης

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ EPL035: ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΚΑΙ ΑΛΓΟΡΙΘΜΟΙ

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. ΘΕΩΡΗΤΙΚΗ ΑΣΚΗΣΗ 2 ΛΥΣΕΙΣ Γραμμικές Δομές Δεδομένων, Ταξινόμηση

Διάλεξη 17: O Αλγόριθμος Ταξινόμησης HeapSort

Διάλεξη 15: Αναδρομή (Recursion) Διδάσκων: Παναγιώτης Ανδρέου

Δοµές Δεδοµένων. 11η Διάλεξη Ταξινόµηση Quicksort και Ιδιότητες Δέντρων. Ε. Μαρκάκης

Ισορροπημένα Δένδρα. για κάθε λειτουργία; Ισορροπημένο δένδρο : Διατηρεί ύψος κάθε εισαγωγή ή διαγραφή

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Βασικές Ιδιότητες και Διάσχιση Κεφάλαιο 5 ( και ) Ε. Μαρκάκης Επίκουρος Καθηγητής

Δυαδικά Δένδρα Αναζήτησης, Δένδρα AVL

ΑΛΓΟΡΙΘΜΟΙ ΜΕ C. ΝΙΚΟΛΑΟΣ ΣΑΜΑΡΑΣ Αναπληρωτής Καθηγητής. CMOR Lab. Computational Methodologies and Operations Research

Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις

Υλοποίηση Λιστών. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα:

ΕΠΛ 231 Δοµές Δεδοµένων και Αλγόριθµοι 8-1

Αλγόριθμοι και Δομές Δεδομένων (IΙ) (γράφοι και δένδρα)

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. ΑΣΚΗΣΗ 4 Σωροί, Γράφοι

Δένδρα Αναζήτησης Πολλαπλής Διακλάδωσης

Προγραμματισμός Ι (ΗΥ120)

Διδάσκων: Παναγιώτης Ανδρέου

Δομές Αναζήτησης. κλειδί από ολικά διατεταγμένο σύνολο. Θέλουμε να υποστηρίξουμε δύο βασικές λειτουργίες: Εισαγωγή ενός νέου στοιχείου

Διάλεξη 18: B-Δένδρα

Δομές Αναζήτησης. κλειδί από ολικά διατεταγμένο σύνολο. Θέλουμε να υποστηρίξουμε δύο βασικές λειτουργίες: Εισαγωγή ενός νέου στοιχείου

Δημιουργία Δυαδικών Δέντρων Αναζήτησης

Δένδρα. Μαθηματικά (συνδυαστικά) αντικείμενα. Έχουν κεντρικό ρόλο στην επιστήμη των υπολογιστών :

Δομές Δεδομένων και Αλγόριθμοι

Διασυνδεδεμένες Δομές. Δυαδικά Δέντρα. Προγραμματισμός II 1

ΕΠΛ 231 οµές εδοµένων και Αλγόριθµοι Άννα Φιλίππου,

ένδρα (tail, head) Γονέας Παιδί (ancestor, descendant) Φύλλο Εσωτερικός Κόµβος (leaf, non-leaf) που αποτελεί το γονέα του v.

Κατ οίκον Εργασία 2 Σκελετοί Λύσεων

Δομές Δεδομένων & Αλγόριθμοι

Διάλεξη 14: Δέντρα IV - B-Δένδρα

Διάλεξη 06: Συνδεδεμένες Λίστες & Εφαρμογές Στοιβών και Ουρών

Ενότητα 7 Ουρές Προτεραιότητας

ΠΛΗ111. Ανοιξη Μάθηµα 7 ο. έντρο. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Δομές Δεδομένων (Data Structures)

Φροντιστήριο 4 Σκελετοί Λύσεων

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Διάλεξη 11: Φροντιστήριο για Στοίβες. Διδάσκων: Παναγιώτης Ανδρέου. ΕΠΛ035 Δομές Δεδομένων και Αλγόριθμοι για Ηλ. Μηχ. Και Μηχ. Υπολ.

Ισορροπημένα Δένδρα. για κάθε λειτουργία; Ισορροπημένο δένδρο : Διατηρεί ύψος κάθε εισαγωγή ή διαγραφή

Κεφάλαιο 6 Ουρές Προτεραιότητας

Εισαγωγή ενός νέου στοιχείου. Επιλογή i-οστoύ στοιχείου : Εύρεση στοιχείου με το i-οστό μικρότερο κλειδί

Οντοκεντρικός Προγραμματισμός

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ. Δομές δεδομένων. Ενότητα 7η: Ουρές Προτεραιότητας Παναγιώτα Φατούρου Τμήμα Επιστήμης Υπολογιστών

Μάθημα 22: Δυαδικά δέντρα (Binary Trees)

ένδρα u o Κόµβοι (nodes) o Ακµές (edges) o Ουρά και κεφαλή ακµής (tail, head) o Γονέας Παιδί Αδελφικός κόµβος (parent, child, sibling) o Μονοπάτι (pat

h/2. Άρα, n 2 h/2-1 h 2log(n+1). Πως υλοποιούµε τη LookUp()? Πολυπλοκότητα?

Κατ οίκον Εργασία 4 Σκελετοί Λύσεων

Δομές Δεδομένων. Δημήτρης Μιχαήλ. Δέντρα Αναζήτησης. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Ουρά Προτεραιότητας (priority queue)

ΕΝΟΤΗΤΑ 4 ΕΝ ΡΑ. ΗΥ240 - Παναγιώτα Φατούρου 1

Ισορροπημένα Δένδρα. για κάθε λειτουργία; Ισορροπημένο δένδρο : Διατηρεί ύψος κάθε εισαγωγή ή διαγραφή

Ενότητα 9 Ξένα Σύνολα που υποστηρίζουν τη λειτουργία της Ένωσης (Union-Find)

Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις

Διάλεξη 21η: Απλά Συνδεδεμένες Λίστες

Διδάσκων: Παναγιώτης Ανδρέου

Κατηγορίες Συμπίεσης. Συμπίεση με απώλειες δεδομένων (lossy compression) π.χ. συμπίεση εικόνας και ήχου

Κεφάλαιο 7 Λεξικά και Δυαδικά Δένδρα Αναζήτησης

Εργαστήριο 2 Δυναμικές Δομές Δεδομένων Διδάσκοντες: Δρ. Γεώργιος Δημητρίου Δρ. Άχμεντ Μάχντι

Διάλεξη 11: Δέντρα Ι Εισαγωγή σε Δενδρικές Δομές Δεδομένων

Δομές Δεδομένων Ενότητα 5

ΗΥ240: Δομές Δεδομένων Εαρινό Εξάμηνο Ακαδημαϊκό Έτος 2017 Διδάσκουσα: Παναγιώτα Φατούρου Προγραμματιστική Εργασία - 2o Μέρος

Δοµές Δεδοµένων. 14η Διάλεξη Δέντρα Δυαδικής Αναζήτησης. Ε. Μαρκάκης

ΠΑΡΑΡΤΗΜΑ: QUIZ ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ

Ειδικά θέματα Αλγορίθμων και Δομών Δεδομένων (ΠΛΕ073) Απαντήσεις 1 ου Σετ Ασκήσεων

Κεφάλαιο 8 Ισορροπημένα Δένδρα Αναζήτησης

Ενότητα 7 Ουρές Προτεραιότητας

Δηµοσθένης Σταµάτης Τµήµα Πληροφορικής ΑΤΕΙ ΘΕΣΣΑΛΟΝΙΚΗΣ ΔΕΝΤΡΑ (TREES) B C D E F G H I J K L M

Δέντρα (Trees) - Ιεραρχική Δομή

AVL-trees C++ implementation

Άσκηση 3 (ανακοινώθηκε στις 24 Απριλίου 2017, προθεσμία παράδοσης: 2 Ιουνίου 2017, 12 τα μεσάνυχτα).

Διδάσκων: Παναγιώτης Ανδρέου

Κεφάλαιο 10 Ψηφιακά Λεξικά

Διάλεξη 24: B-Δένδρα. Διδάσκων: Παναγιώτης Ανδρέου

Transcript:

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ ΕΠΛ 231: Δομές Δεδομένων και Αλγόριθμοι Εαρινό Εξάμηνο 2013 ΑΣΚΗΣΗ 3 Δέντρα Διδάσκων Καθηγητής: Παναγιώτης Ανδρέου Ημερομηνία Υποβολής: 19/03/2013 Ημερομηνία Παράδοσης: 02/04/2013 ΠΕΡΙΓΡΑΦΗ Σε αυτή την άσκηση καλείστε να αναλύσετε και να δημιουργήσετε δομές δεδομένων και αλγόριθμους για κάποια προβλήματα. Επιπλέον καλείστε να υπολογίσετε το χρόνο εκτέλεσης των αλγορίθμων που θα δημιουργήσετε. Άσκηση 1 (15 μονάδες) Δείξτε το αποτέλεσμα εισαγωγής των αριθμών: 5, 8, 15, 3, 2, 4, 9, 7, 6 σε ένα άδειο AVL δέντρο αναφέροντας και το είδος της περιστροφής που απαιτείται σε κάθε βήμα (για τις περιπτώσεις που απαιτείται κάποια περιστροφή).

Άσκηση 2 (15 μονάδες) Δύο δυαδικά δέντρα είναι όμοια μεταξύ τους αν είτε είναι και τα δύο κενά ή και τα δύο δεν είναι κενά και έχουν όμοια αριστερά και δεξιά υπόδενδρα. Να δώσετε ένα παράδειγμα ζεύγους όμοιων δένδρων. Να ορίσετε μια μηαναδρομική διαδικασία η οποία αποφασίζει κατά πόσο δύο δένδρα είναι όμοια μεταξύ τους. Τέλος, να αναλύσετε τη χρονική πολυπλοκότητα της διαδικασίας. Η μη αναδρομική εκδοχή της διαδικασίας απαιτεί τη χρήση βοηθητικής δομής στην οποία θα αποθηκεύουμε ζεύγη κατευθύνσεων προς τα οποία θα πρέπει να κινηθούμε σε μεταγενέστερο στάδιο. Ο τύπος της βοηθητικής δομής δεν έχει σημασία αφού η επεξεργασία των ζευγών μπορεί να γίνει σε τυχαία σειρά. Στη λύση αυτή χρησιμοποιείται στοίβα. Η βασική ιδέα του αλγόριθμου είναι η εξής: 1. Δημιουργούμε μια κενή στοίβα. 2. Εφόσον τα δύο δένδρα που μελετούμε δεν είναι κενά και η στοίβα δεν είναι άδεια (δηλ. υπάρχουν ακόμη ζεύγη προς επεξεργασία) προχωρούμε στο βήμα 3. Διαφορετικά πάμε στο βήμα 5. 3. Αν το ένα από τα δύο δένδρα είναι κενά, επιστρέφουμε 0 δηλώνοντας έτσι ότι τα δένδρα είναι ανόμοια και τερματίζουμε. Διαφορετικά τοποθετούμε δείκτες προς τα δεξιά παιδιά των δύο κόμβων και προχωρούμε στα αριστερά παιδιά, επιστρέφοντας στο βήμα 2. 4. Αν και τα δύο δένδρα είναι κενά (null δείκτες) συμπεραίνουμε ότι μέχρι στιγμής δεν έχουμε αντιμετωπίσει ανόμοια δένδρα και ανασύρουμε από τη στοίβα κάποιο από τα ζεύγη που αναμένει επεξεργασία. Επαναλαμβάνουμε από το βήμα 2. 5. Επιστρέφουμε την τιμή 1 που υπονοεί ότι τα αρχικά δένδρα είναι όμοια και τερματίζουμε. int SimilarNR(node p, node q){ Stack S = new Stack(); while (p!= null OR q!= null OR

!S.IsEmpty()){ if (p!= null AND q == null) (p == null AND q!= null) return 0; if (p!= null AND q!= null) S.Push((p.right, q.right)); p = p.left; q = q.left; (p,q) = S.Pop(); return 1; Η διαδικασία επισκέπτεται και πάλι κάθε κόμβο ακριβώς μια φορά, επομένως ο χρόνος εκτέλεσής της είναι Θ(n) όπου n είναι ο αριθμός των κόμβων του δένδρου. Άσκηση 3 (40 μονάδες) Ένα δυαδικό δένδρο αναζήτησης με n κόμβους έχει n+1 null δείκτες. Αυτό σημαίνει ότι η μισή μνήμη που χρησιμοποιείται για την αποθήκευση του δένδρου σπαταλείται άσκοπα. Η άσκηση αυτή σας προτείνει να χρησιμοποιήσετε τη μνήμη των null δεικτών ως εξής: Αν κάποιος κόμβος του δένδρου δεν έχει αριστερό παιδί, να φυλάγεται στο πεδίο left του κόμβου δείκτης προς τον κόμβο του δένδρου με το αμέσως μικρότερο κλειδί. Αντίστοιχα, αν κάποιος κόμβος του δένδρου δεν έχει δεξιό παιδί, να φυλάγεται στο πεδίο right του κόμβου δείκτης προς τον κόμβο του δένδρου με το αμέσως μεγαλύτερο κλειδί. Ένα τέτοιο δένδρο ονομάζεται νηματώδες δένδρο και οι επιπλέον δείκτες ονομάζονται νήματα. Α. Να επιδείξετε τη νηματώδη μορφή του πιο κάτω ΔΔΑ.

5 2 7 6 9 23 Β. Πως μπορούμε να διαχωρίζουμε ανάμεσα στους δείκτες νήματα και στους πραγματικούς δείκτες προς τα παιδιά ενός κόμβου σε ένα νηματώδες δένδρο; Γ. Να γράψετε διαδικασίες εισαγωγής και διαγραφής κόμβων σε ένα νηματώδες δένδρο που να διατηρούν τις προδιαγραφές του. Δ. Ποια τα πλεονεκτήματα ενός νηματώδους δένδρου; 3.A. Να επιδείξετε τη νηματώδη μορφή του πιο κάτω ΔΔΑ. 5 2 7 null 6 9 23 null 3.B. Πως μπορούμε να διαχωρίζουμε ανάμεσα στους δείκτες νήματα και στους πραγματικούς δείκτες προς τα παιδιά ενός κόμβου σε ένα νηματώδες δένδρο; Για διαχωρισμό ανάμεσα στους δείκτες παιδιά και τους δείκτες νήματα ενός κόμβου χρησιμοποιούμε ένα χαρακτήρα σε κάθε κόμβο ο οποίος παίρνει την

τιμή n αν κανένα από τα παιδιά του κόμβου δεν είναι νήμα, l αν το αριστερό παιδί είναι νήμα, r αν το δεξί παιδί είναι νήμα και b αν και τα δύο παιδιά είναι νήματα. Χρησιμοποιούμε τις δομές: class ΤΝode{ int key; TNode left; TNode right; char threads; class Τree{ TNode root; και υποθέτουμε πως ένα νηματώδες δένδρο είναι υλοποιημένο ως δείκτης σε κόμβο τύπου *tree. 3.Γ. Να γράψετε διαδικασίες εισαγωγής και διαγραφής κόμβων σε ένα νηματώδες δένδρο που να διατηρούν τις προδιαγραφές του. Εισαγωγή σε νηματώδες δένδρο γίνεται παρόμοια με ένα ΔΔΑ. Η επέκταση η οποία καλούμαστε να κάνουμε είναι η απόδοση νημάτων στους κόμβους/φύλλα του δένδρου που δημιουργούνται λόγω των εισαγωγών. Η απόδοση γίνεται ως εξής. Αν ο νέος κόμβος δεν έχει πατέρα, τότε τα παιδιά/νήματα έχουν και τα δύο την τιμή null. Αν ο νέος κόμβος είναι αριστερό παιδί του πατέρα του, τότε κληρονομεί από αυτόν το αριστερό του νήμα, ενώ το δεξί του νήμα δείχνει στον πατέρα. Αν ο νέος κόμβος είναι δεξί παιδί του πατέρα του, τότε κληρονομεί από αυτόν το δεξί του νήμα, ενώ το αριστερό του νήμα δείχνει στον πατέρα. Και στις δύο τελευταίες περιπτώσεις, ο πατέρας πρέπει να ενημερωθεί κατάλληλα τόσο για την απόκτηση νέου παιδιού όσο και για την απώλεια κάποιου νήματος. TNode InsertNode(TNode *root, int n){ TNode p=new TNode(); p.val = n; p.left = p.right = null; p.threads = b ; TNode r = root; if (r == null) { p.threads = b return p;

while (1) { if (n == r.val) report n already in tree and exit if (n<r.val && r.threads!= b, l') r = r.left; if (n>r.val && r.threads!= b, r') r = r.right; break; if (n < r.val){ p.left = r.left; p.right = r; r.left = p; if r.threads == l r.threads == n ; if r.threads == b r.threads == r ; if (n > r.val)){ p.right = r.right; p.left = r; r.right = p; if r.threads == r r.threads == n if r.threads == b r.threads == l return root; Για τη διαδικασία εξαγωγής χρησιμοποιούμε βοηθητικά τις διαδικασίες DeleteRightMin(r) η οποία εξάγει το ελάχιστο στοιχείο στο δεξί υπόδενδρο του κόμβου r και DeleteLeftMax(r) η οποία εξάγει το μέγιστο στοιχείο στο αριστερό υπόδενδρο του κόμβου r. Πιο κάτω παρουσιάζεται η διαδικασία DeleteRightMin(r). Η διαδικασία αυτή είναι όμοια με την ανάλογη διαδικασία σε ΔΔΑ με κατάλληλες προσθήκες για ενημέρωση των νημάτων. Η σημαντικότερη αλλαγή αφορά το γεγονός ότι ο κόμβος με το ελάχιστο στοιχείο, έστω p, πιθανόν να αποτελεί αριστερό νήμα κάποιου άλλου κόμβου. Ο κόμβος αυτός, αν υπάρχει, είναι ο κόμβος/φύλλο με το αμέσως μεγαλύτερο στοιχείο. Υπάρχει, αν ο p έχει δεξιά υπόδενδρο. (Αν όχι, ο κόμβος με το αμέσως μεγαλύτερο στοιχείο είναι ο πατέρας του p ο οποίος δεν έχει αριστερό νήμα πριν από την εξαγωγή).

int deleterightmin(tnode r){ father = r; p = r = r.right; while (r.threads!= b, l ) { father = r; r = r.left; if (p == r) { father.right = r.right; if (r.threads == b ) if (father.threads == n ) r.threads == r if (father.threads == l ) father.threads == b father.left = r.left; if (r.threads == b ) if (father.threads == n ) r.threads == l ; if (father.threads == r ) if (r.right!= null) for(q=r.right; q.left!=null; q=q.left); q.left = r.left; val = r.val; return val; H διαδικασία εξαγωγής περιέχει εφαρμόζει κλήση της DeleteMin όπως και στα ΔΔΑ. Κά κάποια μικρή επιπρόσθετη πολυπλοκότητα έναντι αυτής σε ΔΔΑ εφόσον οι όποιες αναπροσαρμογές των νημάτων γίνονται κατά την κλήση της. void Delete(Tree t, int n){ r = t.root; if (r == null) return null; father = null; while (r!=null) if (n < r.val) father = r; r = r.left; if (n > r.val) father = r; r = r.right; if (n == r.val)

break; if r == null return; if (father == null) tree.root = null; if (r.threads = b ); if (r == father.left) father.left = r.left; if (father.threads = n ) father.threads = l if (father.threads = r ) father.threads = b if (r == father.right) father.right = r.right; if (father.threads = n ) father.threads = r if (father.threads = l ) father.threads = b if (r.right!= null) val = DeleteRightMin(r); val = DeleteLeftMax(r); r.val = val; 3.Δ. Το κύριο πλεονέκτημα ενός νηματώδους δένδρου είναι η ευκολότερη μετακίνηση μέσα στο δένδρο. Συγκεκριμένα, η ενδο διατεταγμένη και η μεταδιατεταγμένη διάσχιση δένδρων μπορεί να υλοποιηθεί εύκολα χωρίς αναδρομή και χωρίς τη χρήση στοίβας. Το ίδιο ισχύει (δηλαδή, εύκολη μετατροπή σε μη αναδρομικές διαδικασίες χωρίς τη χρήση βοηθητικών δομών) για αναδρομικές διαδικασίες που μιμούνται τις διασχίσεις αυτές. Μειονέκτημα είναι η χρήση περισσότερης μνήμης σε κάθε κόμβο του δένδρου και η αύξηση της πολυπλοκότητας των διαδικασιών εισαγωγής και διαγραφής. Άσκηση 4 (10 μονάδες) Θέλουμε να εισάγουμε τους αριθμούς 1, 4, 5, 7, 8, 28, 29, 72, σε ένα 2 3 δένδρο. Να βρείτε κάποια σειρά εισαγωγής των στοιχείων που να δημιουργεί 2 3 δένδρο με τον μικρότερο δυνατό αριθμό κόμβων και κάποια σειρά εισαγωγής που να δημιουργεί 2 3 δένδρο με τον μεγαλύτερο δυνατό αριθμό κόμβων. Να εφαρμόσετε τις δύο σειρές εισαγωγών των στοιχείων δείχνοντας όλα τα ενδιάμεσα αποτελέσματα.

Μία σειρά εισαγωγής των στοιχείων που έχει ως αποτέλεσμα την δημιουργία του δένδρου με τον μέγιστο αριθμό κόμβων είναι η 1, 4, 5, 7, 8, 28, 29, 72. (Υπάρχουν και άλλες σειρές εισαγωγής που δίνουν αυτό τον αριθμό κόμβων.) 7 4 28 1 5 8 29 72 Μια σειρά που παράγει δένδρο με τον μικρότερο αριθμό κόμβων είναι η 72, 4, 28, 29, 5, 8, 1, 7. Η σειρά αυτή δημιουργεί το πιο κάτω δένδρο με 4 κόμβους. (Υπάρχουν και άλλες σειρές εισαγωγής που δίνουν αυτό τον αριθμό κόμβων.) 5 28 1 4 7 8 29 72 Άσκηση 5 (20 μονάδες) Να εισηγηθείτε δενδρική δομή δεδομένων η οποία να υλοποιεί το γενεαλογικό δένδρο μιας οικογένειας. Συγκεκριμένα, για κάθε άτομο θέλουμε να αποθηκεύουμε τα εξής στοιχεία (α) ονοματεπώνυμο (β) χρονολογίες γεννήσεως και θανάτου (αν υπάρχει), (γ) όνομα συζύγου (αν υπάρχει) και (δ) δείκτες στα παιδιά του, αν έχει παιδιά. Η δομή θα πρέπει να υποστηρίζει τις πιο κάτω πράξεις: i. Children(name): η διαδικασία αυτή θα πρέπει να τυπώνει τα παιδιά του ατόμου με ονοματεπώνυμο name. ii. NewChild(child, year, parent) : η διαδικασία αυτή θα πρέπει εισάγει την πληροφορία της γέννησης του παιδιού child από το άτομο parent τη χρονολογία year. iii. Living(name): η διαδικασία αυτή θα πρέπει να τυπώνει τα ονοματεπώνυμα όλων των εν ζωή απογόνων του ατόμου name. Να υπολογίσετε τον χρόνο εκτέλεσης των διαδικασιών σας και να συζητήσετε την αποδοτικότητα της υλοποίησής σας από άποψης χρόνου και χώρου.

Προφανώς τα δένδρα τα οποία θα υλοποιήσουμε δεν έχουν κάποιο προκαθορισμένο βαθμό (δεν υπάρχει καθορισμένος μέγιστος βαθμός ενός κόμβου). Έτσι για εξοικονόμηση χώρου και για υλοποίηση λύσης χωρίς την επιβολή οποιωνδήποτε περιορισμών/υποθέσεων επιλέγουμε να υλοποιήσουμε το δένδρο φυλάγοντας για κάθε κόμβο το πρώτο του παιδί και τον επί δεξιά του αδελφό. Αυτό υλοποιείται μέσω των δομών: class person{ class ftnode { String name; person pers; int birth; ftnode firstchild; int death; ftnode rightsibling; String spouse; και υποθέτουμε πως ένα γενεαλογικό δένδρο είναι υλοποιημένο ως δείκτης στη ρίζα του δένδρου, δηλαδή, έχει τύπο ftnode. Αρχικά υλοποιούμε τη βοηθητική διαδικασία Find (name, ftree) η οποία εντοπίζει και επιστρέφει δείκτη στον κόμβο που αφορά το άτομο με όνομα name στο δένδρο που δείχνεται από το δείκτη p, αν υπάρχει. ftnode Find(String name, ftnode p) { if (p == null) return null; { if ((p.pers.name) == name) return p; { q = Find(name, p.firstchild); if (q!= null) return q; return Find(name,p.rightsibling); (i) Για να τυπώσουμε τα ονόματα των παιδιών ενός ατόμου με κάποιο όνομα, πρώτα εντοπίζουμε τον κόμβο που αντιστοιχεί στο συγκεκριμένο άτομο και μετά επισκεπτόμαστε τα παιδιά του μέσω του δείκτη firstchild του κόμβου και των δεικτών rightsibling των παιδιών: Children(String name, ftnode p) { q = Find(name, p); if (q!= null) {

q = p.firstchild; while (q!= null) { print q.pers.name; q = q.rightsibling; (ii) Για να εισαγάγουμε ένα νέο παιδί κάποιου ατόμου θα πρέπει πρώτα να εντοπίσουμε το άτομο αυτό, και στη συνέχεια να τοποθετήσουμε το νέο παιδί στη λίστα παιδιών που δείχνεται από το δείκτη firstchild: Newchild(String child, int year, String parent, ftnode p){ q = Find(parent, p); if (q!= null) { r = new ftnode(); r.pers.name = child; r.pers.birth = year; r.pers.death = 1; r.firstchild = null; r.rightsibling = q.firstchild; q.firstchild = r; (iii) H διαδικασία που προτείνεται αρχικά εντοπίζει τον ζητούμενο κόμβο και στη συνέχεια καλεί μια δεύτερη, αναδρομική διαδικασία στο πρώτο παιδί του κόμβου αυτού. Η αναδρομική διαδικασία δουλεύει ως εξής: αν το παιδί δεν είναι κενό, τότε: αν το άτομο στη ρίζα του δένδρου βρίσκεται εν ζωή, τότε το όνομα του ατόμου τυπώνεται στην οθόνη και η διαδικασία καλείται (1) στο πρώτο παιδί του κόμβου και (2) στον επί δεξιά αδελφό του κόμβου. Living(String name, ftnode p) { q = Find(name, p); if (q == null) return; if (q.firstchild!= null) RecLiving(q.firstchild); RecLiving (ftnode p){ if (p.death == 1) print(p.pers.name); if (p.firstchild!= null) RecLiving (p.firstchild);

if (p.rightsibling!= null) RecLive(p.righsibling); Ο χρόνος εκτέλεσης των διαδικασιών είναι Ο(n) όπου n είναι ο αριθμός των κόμβων του δένδρου.