Lists– Λίστες 1
Αυτό-αναφορικές δομές Τα μέλη μίας δομής μπορεί να είναι οποιουδήποτε τύπου, ακόμα και δείκτες σε δομές του ίδιου τύπου. Χρησιμοποιώντας τέτοιου είδους δομές, που ονομάζονται αυτοανα ϕ ορικές και είναι πολύ χρήσιμες στον προγραμματισμό, μπορούμε να οργανώσουμε δεδομένα με τρόπους που διευκολύνουν εξαιρετικά τη διαχείριση και επεξεργασία τους. Οι πλέον συνήθεις οργανώσεις δεδομένων μέσω αυτοανα ϕ ορικών δομών είναι οι συνδεδεμένες λίστες (ή, απλά, λίστες). 2
Λίστες Η υλοποίηση μιας λίστας είναι πολύ διαφορετική σε σχέση με τις στοίβες. Στις λίστες τα στοιχεία αποθηκεύονται σε απομονωμένα τμήματα μνήμης το καθένα, μαζί με την πληροφορία (συνήθως σε μορφή δεικτών) για τη θέση του επόμενου και του προηγούμενου στοιχείου. 3
Λίστες Η συγκεκριμένη εσωτερική δομή παρουσιάζει το μειονέκτημα ότι δεν επιτρέπει τυχαία προσπέλαση των στοιχείων. Αντίθετα, πρέπει να μετακινούμαστε διαδοχικά από το ένα στοιχείο στο άλλο ώσπου να φτάσουμε στο ζητούμενο. Η δομή όμως έχει ένα σημαντικό πλεονέκτημα: η προσθήκη ή διαγραφή στοιχείων σε οποιοδήποτε σημείο μιας λίστας είναι το ίδιο γρήγορη καθώς απαιτεί αλλαγές δεικτών και όχι αντιγραφή στοιχείων. 4
Λίστες Η χρήση της std::list προϋποθέτει τη συμπερίληψη του header. Ορισμός Ορισμός μιας λίστας γίνεται ως εξής: list L;: Δημιουργεί μια κενή λίστα. list L1(L2); : Δημιουργεί λίστα, αντίγραφο άλλης. list L(N);: Δημιουργεί λίστα N στοιχείων list L(N, elem); : Δημιουργεί λίστα από N αντίγραφα του elem. list L(beg, end); : Δημιουργεί λίστα από τα στοιχεία στο διάστημα [beg, end). 5
Λίστες Προσθήκη στοιχείων L1 = L2; : Αντιγράφει τα στοιχεία της L2 στην L1 καταστρέφοντας τα αρχικά. L.assign(N,elem); : Καταστρέφει τα στοιχεία της L και εισάγει N αντίγραφα του elem. L.assign(beg, end); : Καταστρέφει τα στοιχεία της L και εισάγει τα στοιχεία του διαστήματος [beg, end). L1.swap(L2); ή std::swap(L1,L2); : Εναλλάσσει τα στοιχεία των L1, L2. 6
Λίστες L.insert(pos,elem); : Εισάγει πριν τη θέση του pos, αντίγραφο του elem. L.insert(pos,N,elem); : Εισάγει πριν τη θέση του pos, N αντίγραφα του elem. L.insert(pos, beg, end); : Εισάγει πριν τη θέση του pos τα στοιχεία στο διάστημα [beg, end). L.push_back(elem); : Εισάγει αντίγραφο του elem στο τέλος της L. L.push_front(elem); : Εισάγει αντίγραφο του elem στην αρχή της L. L.resize(N); : Μεταβάλλει σε N το πλήθος των στοιχείων της L. 7
Παράδειγμα 1 8 // output List is:
Λίστες Διαγραφή στοιχείων Διαγραφή στοιχείων από μια λίστα L, γίνεται ως εξής : L.pop_back(); : Διαγράφει το τελευταίο στοιχείο. L.pop_front(); : Διαγράφει το πρώτο στοιχείο. L.erase(pos); : Διαγράφει το στοιχείο στη θέση pos L.erase(beg,end); : Διαγράφει τα στοιχεία στο διάστημα [beg,end) L.clear(); : Διαγράφει όλα τα στοιχεία της L. 9
Παράδειγμα 2 10 // output List is:
Λίστες Προσπέλαση στοιχείων Προσπέλαση στοιχείων μιας list γίνεται ως εξής : Με τις συναρτήσεις–μέλη front() και back(). Αυτές επιστρέφουν αναφορά στο πρώτο και τελευταίο στοιχείο αντίστοιχα χωρίς να ελέγχουν αν αυτά υπάρχουν. Με τη δράση του τελεστή (*) σε όνομα iterator. Προσέξτε ότι αν είναι τύπου const_iterator δεν μπορούμε να μεταβάλουμε την τιμή που ‘‘δείχνει’’ αλλά μόνο να τη διαβάσουμε. 11
Λίστες Επιπλέον συναρτήσεις - μέλη size() Το πλήθος των στοιχείων empty()True / False αν η λίστα είναι κενή ή όχι max_size()Το μέγιστο δυνατό πλήθος στοιχείων sort()ταξινομεί τη λίστα συγκρίνοντας τα στοιχεία µε τον τελεστή (<). reverse() αναστρέφει τη σειρά των στοιχείων unique() αφαιρεί συνεχόμενα επαναλαμβανόμενα στοιχεία L.remove(val);διαγράφει όλα τα στοιχεία της L µε τιμή val. L.remove_if(func); διαγράφει τα στοιχεία για τα οποία η func() δίνει true. 12
Παράδειγμα 3 13
Παράδειγμα 4: 14 // output List is:
Διδάσκων: Παύλος Παυλικκάς15
Άσκηση 3 (Α’ γύρος 2012) 16 Χρησιμοποιώντας λίστες η επίλυση της άσκησης 3 του δοκιμίου του Α’ γύρου 2012 είναι πολύ απλή:
Άσκηση 1 (Training Α’ γύρος 2015) 17
Άσκηση 1 (Training Α’ γύρος 2015) 18
Άσκηση 1 (Training Α’ γύρος 2015) 19
Links Όλες οι εντολές του list class 20