Καθηγητής Πληροφορικής Απαγορεύεται η αναπαραγωγή των σημειώσεων χωρίς αναφορά στην πηγή Οι σημειώσεις, αν και βασίζονται στο διδακτικό πακέτο, αποτελούν προσωπική θεώρηση της σχετικής ύλης και όχι επίσημο υλικό. Οι δυναμικές δομές δεδομένων στην ΑΕΠΠ Εισαγωγή Οι Δομές Δεδομένων που χρησιμοποιούν δείκτες αποκαλούνται δυναμικές (dynamic), γιατί κατά την υλοποίησή τους δεν απαιτείται εκ των προτέρων καθορισμός του μέγιστου πλήθους κόμβων (στοιχείων) που θα χρησιμοποιηθούν. O κόμβος αποτελείται από δυο μέρη: τα δεδομένα και το δείκτη (διπλανή εικόνα). Η σύνδεση των κόμβων μεταξύ τους πραγματοποιείται με τη χρήση δεικτών. Ο δείκτης (pointer) είναι ένα πεδίο του κόμβου, το οποίο δεν περιέχει δεδομένα αλλά δηλώνει κάποια διεύθυνση στην κύρια μνήμη, όπου εντοπίζεται το επόμενο στοιχείο της δομής. Για τη λειτουργία τους αξιοποιούν την τεχνική της δυναμικής παραχώρησης μνήμης. Α. Λίστες Η λίστα είναι δυναμική δομή δεδομένων. Κάθε κόμβος περιέχει σύνδεση (με δείκτη) με επόμενο (ή επόμενους). Η λίστα του παραπάνω σχήματος αποκαλείται και συνδεδεμένη. Άλλα παραδείγματα συνδεμένης λίστας ακολουθούν στη συνέχεια. Στη βιβλιογραφία εντοπίζονται πολλές υλοποιήσεις της λίστας (ταξινομημένες, διπλά συνδεδεμένες κ.α.), αλλά ξεφεύγει από το σκοπό της ΑΕΠΠ η παρουσίασή τους. Με τη χρήση δεικτών διευκολύνονται οι λειτουργίες της εισαγωγής και της διαγραφής δεδομένων στις λίστες. Στην εικόνα παρουσιάζεται η εισαγωγή ενός νέου κόμβου στη δεύτερη θέση της λίστας. 1
Αντίστοιχα, στη διπλανή εικόνα παρουσιάζεται η εισαγωγή ενός νέου κόμβου (με όνομα q) μεταξύ του δεύτερου και τρίτου κόμβου της προηγούμενης λίστας (μετά τον κόμβο p). Θεωρούμε ότι αν p είναι ένας δείκτης προς κάποιον κόμβο, τότε p.δεδομένα είναι το περιεχόμενο (δεδομένα) του κόμβου και p.δείκτης είναι ο δείκτης του ίδιου κόμβου προς τον επόμενο κόμβο. Oι απαιτούμενες ενέργειες για την εισαγωγή νέου κόμβου είναι ο δείκτης του δεύτερου κόμβου (p) να δείχνει το νέο κόμβο (q) και ο δείκτης του νέου κόμβου να δείχνει τον τρίτο κόμβο (δηλαδή να πάρει την τιμή που είχε πριν την εισαγωγή ο δείκτης του κόμβου p). Έτσι οι κόμβοι της λίστας διατηρούν τη λογική τους σειρά, αλλά οι φυσικές θέσεις στη μνήμη είναι τελείως διαφορετικές. Αντίστοιχα για τη διαγραφή ενός κόμβου αρκεί ν' αλλάξει τιμή ο δείκτης του προηγούμενου κόμβου και να δείχνει πλέον τον επόμενο αυτού που διαγράφεται, όπως φαίνεται στα σχήματα. Ο κόμβος που διαγράφηκε αποτελεί "άχρηστο δεδομένο" και ο χώρος μνήμης που καταλάμβανε αποδεσμεύεται και παραχωρείται για άλλη χρήση. Για την πρόσβαση σε κάποιο κόμβο της λίστας πρέπει να σαρωθούν όλοι οι κόμβοι μέχρι αυτόν, λειτουργία που αποκαλείται και διάσχιση (σε αντίθεση με τον πίνακα που μπορεί να προσπελαστεί απευθείας το επιθυμητό κελί). Ωστόσο, η ευελιξία των δυναμικών δομών δεδομένων έναντι των στατικών είναι φανερή. Για την προσθήκη μιας τιμής σε στατικό πίνακα, θα έπρεπε να μεταφερθούν τα στοιχεία σε νέο πίνακα με μετατόπιση σε νέες θέσεις, όπως παρουσιάζεται στη διπλανή εικόνα. Οι λίστες μπορούν να υλοποιηθούν χωρίς τη χρήση δεικτών, αλλά με τη βοήθεια πινάκων που θα περιέχουν τις απαιτούμενες πληροφορίες δεικτοδότησης. 2
Η αλγοριθμική υλοποίηση της εισαγωγής/διαγραφής στοιχείου σε λίστα (κωδικοποίηση), δεν είναι στην ύλη (σχολικό έτος 2015 16). Παρ όλα αυτά παρουσιάζονται στη συνέχεια σε φυσική γλώσσα κατά βήματα. Αλγόριθμος Εισαγωγή στοιχείου σε (συνδεμένη) Λίστα Είσοδος: Δείκτης κόμβου που θα προηγείται του νέου στοιχείου: Πριν (p) Τιμή που θα εισαχθεί: τιμή Έξοδος: Βήμα 1 Δέσμευση μνήμης για νέο κόμβο: Νέος (q) Βήμα 2 Νέος.δεδομένα τιμή! αποθήκευσε τη νέα τιμή Βήμα 3 Νέος.δείκτης Πριν.δείκτης! ο κόμβος Νέος θα δείχνει ό,τι έδειχνε ο Πριν Βήμα 4 Πριν.δείκτης Νέος! Ο κόμβος Πριν θα δείχνει τον κόμβο Νέος Αλγόριθμος Διαγραφή στοιχείου από (συνδεμένη) Λίστα Είσοδος: Δείκτης κόμβου που θα προηγείται αυτού που θα διαγραφεί: Πριν (p) Έξοδος: Δεδομένα κόμβου που θα διαγραφεί (Διαγραφή): τιμή Βήμα 1 Διαγραφή Πριν.δείκτης Βήμα 2 τιμή Διαγραφή.δεδομένα! κράτα τιμή Βήμα 3 Πριν.δείκτης Διαγραφή.δείκτης! ο κόμβος Πριν θα δείχνει τον μεθεπόμενο κόμβο Βήμα 4 Αποδέσμευση μνήμης για κόμβο: Διαγραφή (q) Αλγόριθμος Διάσχιση, δηλαδή σάρωση, (συνδεμένης) Λίστας Είσοδος: Δείκτης πρώτου κόμβου: Πρώτος Έξοδος: Τιμές δεδομένων λίστας Βήμα 1 ενεργός Πρώτος Βήμα 2 Αν ο ενεργός κόμβος (ενεργός) δεν είναι ο τελευταίος (έχει επόμενο), τότε πήγαινε στο Βήμα 3, αλλιώς ολοκλήρωση διαδικασίας Βήμα 3 τιμή ενεργός.δεδομένα! επεξεργάσου τα δεδομένα του ενεργού κόμβου Βήμα 3 ενεργός ενεργός.δείκτης! ενεργός κόμβος θα γίνει ο επόμενος Βήμα 4 Πήγαινε στο Βήμα 2 Πολλές φορές για τη διαχείριση των λιστών, χρησιμοποιούνται βοηθητικές δομές που αποθηκεύουν χρήσιμες πληροφορίες, όπως τη διεύθυνση στη μνήμη του πρώτου κόμβου, του τελευταίου κόμβου, το πλήθος των στοιχείων της δομής κ.λπ. Με τη βοήθεια δεικτών μπορούν να υλοποιηθούν ως δυναμικές δομές δεδομένων και οι δομές στοίβα και ουρά. Η προσθήκη και διαγραφή νέων κόμβων πραγματοποιείται όπως περιγράφηκε παραπάνω, ωστόσο πρέπει να τηρούνται οι επεξεργασίες FIFO και LIFO αντίστοιχα. Μια άλλη υλοποίηση των λιστών είναι οι δυναμικοί πίνακες, που έχουν τη δυνατότητα αυξομείωσης του πλήθους των στοιχείων τους σε χρόνο εκτέλεσης προγράμματος. 3
Β. Δένδρα Τα δένδρα (trees) είναι δομές δεδομένων που στις σύγχρονες γλώσσες προγραμματισμού υλοποιούνται με τη βοήθεια δεικτών, όπως περιγράφηκε παραπάνω (δείτε σχήματα που ακολουθούν). Πρέπει να επισημανθεί ότι τα δένδρα, μπορούν να υλοποιηθούν και με στατικές δομές (πίνακες). Το κύριο χαρακτηριστικό των δένδρων είναι, ότι από έναν κόμβο δεν υπάρχει ένας μόνο επόμενος κόμβος, αλλά περισσότεροι. Ο αρχικός κόμβος, που αποκαλείται ρίζα, είναι εκείνος από τον οποίο ξεκινούν όλοι οι άλλοι. Από τη ρίζα ξεκινούν δύο ή περισσότεροι κόμβοι που ονομάζονται παιδιά της ρίζας. Με την ίδια λογική, από κάθε παιδί ξεκινούν άλλα παιδιά κ.ο.κ. Στη βιβλιογραφία αναφέρεται μία τεράστια ποικιλία δομών δένδρων (δυαδικά, διατεταγμένα κ.λπ.), που η αναφορά σε αυτές βρίσκεται εκτός των ορίων του μαθήματος. Οι λίστες που εξετάστηκαν στην πρώτη παράγραφο, χαρακτηρίζονται γραμμικές δομές δεδομένων, διότι διαθέτουν τη σχέση της συνεχόμενης λογικής γειτονικότητας των στοιχείων τους. Τα δένδρα και οι γράφοι (επόμενη παράγραφος) ανήκουν στις μη γραμμικές δομές. Η δομή του δένδρου σε γενικές γραμμές δεν είναι τίποτε άλλο παρά η σύνδεση κόμβων με τρόπο ανάλογο ενός πραγματικού δένδρου. Τα δένδρα είναι ειδικές μορφές γράφων (graphs). Ένας ορισμός των δένδρων είναι ο ακόλουθος: Δένδρο είναι ένα σύνολο κόμβων που συνδέονται με ακμές. Υπάρχει ένας μόνο κόμβος που ονομάζεται ρίζα (root) και στον οποίο δεν καταλήγουν, αλλά μόνο ξεκινούν ακμές. Από κάθε κόμβο μπορούν να ξεκινούν καμία, μία ή περισσότερες ακμές. Σε κάθε κόμβο (εκτός της ρίζας) καταλήγει μία μόνο ακμή. Τα δένδρα υλοποιούνται με τη χρήση δεικτών (όπως οι λίστες) αλλά και με πίνακες. 4
Γ. Γράφοι Ένας γράφος (graph) αποτελείται από ένα σύνολο κόμβων (ή σημείων ή κορυφών) και ένα σύνολο γραμμών (ή ακμών ή τόξων) που ενώνουν κάποιους ή όλους τους κόμβους. Ο γράφος αποτελεί την πιο γενική δομή δεδομένων, με την έννοια ότι όλες οι δομές που παρουσιάστηκαν παραπάνω μπορούν να θεωρηθούν περιπτώσεις γράφων. Οι γράφοι υλοποιούνται με τη χρήση δεικτών (όπως οι λίστες) αλλά και με πίνακες. Πολλά προβλήματα και καταστάσεις της καθημερινής μας ζωής μπορούν να περιγραφούν με τη βοήθεια διαγράμματος, που αποτελείται από ένα σύνολο σημείων και ένα σύνολο γραμμών που ενώνουν ζεύγη σημείων. Για παράδειγμα, τα σημεία ενός γράφου μπορούν να παριστούν πόλεις και οι γραμμές τις οδικές συνδέσεις μεταξύ τους. Λόγω της μεγάλης πληθώρας και ποικιλίας των προβλημάτων που σχετίζονται με γράφους, έχει αναπτυχθεί ομώνυμη θεωρία, η Θεωρία Γράφων, η οποία συχνά αποτελεί αυτοδύναμο μάθημα σε πανεπιστημιακά τμήματα. Π.χ. (Παράδειγμα κεφαλαίου 4.1) Πρόβλημα κινέζου ταχυδρόμου Επιθυμούμε ο ταχυδρομικός διανομέας, να ξεκινήσει από ένα χωριό, να επισκεφθεί έναν αριθμό από γειτονικά χωριά, για να μοιράσει ένα σύνολο επιστολών και να επιστρέψει στο χωριό, από όπου ξεκίνησε περνώντας μόνο μία φορά από κάθε χωριό. Το πρόβλημα έγκειται στην εύρεση της καλύτερης διαδρομής, έτσι ώστε ο διανομέας να διανύσει το μικρότερο δυνατό αριθμό χιλιομέτρων. Π.χ. (Παράδειγμα 2.3, σχολικού βιβλίου Β Λυκείου). Δίνεται ο ακόλουθος χάρτης διαδρομών που συνδέει ορισμένες πόλεις. Ο χάρτης δείχνει το χρόνο που απαιτείται για τη μετακίνηση από πόλη σε πόλη. 1. Ποια διαδρομή είναι η συντομότερη από την πόλη Α στην πόλη Β; 2. Σε ποια πόλη θα συναντηθούν τρεις φίλοι ώστε κανένας να μην κινηθεί περισσότερο από δεκαπέντε λεπτά αν βρίσκονται στις πόλεις Γ, Δ και Ε αντίστοιχα και τα τρένα τους ξεκινούν όλα στις 19:00; 5