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



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

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

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

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

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

Διάλεξη 14: Δομές Δεδομένων ΙΙI (Λίστες και Παραδείγματα)

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

υναµική έσµευση Μνήµης (συν.) ΕΠΛ 132 Αρχές Προγραµµατισµού ΙΙ 2 Εφαρµογή

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

υναµικές οµές εδοµένων

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

4. Συνδεδεμένες Λίστες

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

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

Διάλεξη 12: Λίστες Υλοποίηση & Εφαρμογές. Διδάσκων: Παναγιώτης Ανδρέου

Εργαστήριο 4: Υλοποίηση Αφηρημένου Τύπου Δεδομένων: Ταξινομημένη Λίστα

ΕΠΛ232 Προγραμματιστικές Τεχνικές και Εργαλεία Δυναμική Δέσμευση Μνήμης και Δομές Δεδομένων (Φροντιστήριο)

υναµικές οµές εδοµένων (συν.) Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα:

Διάλεξη 07: Λίστες Ι Υλοποίηση & Εφαρμογές

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

διεύθυνση πρώτου στοιχείου διεύθυνση i-οστού στοιχείου T t[n]; &t[0] είναι t &t[i] είναι t + i*sizeof(t)

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

ΛΙΣΤΕΣ. Ορισμός ΑΤΔ Λίστα ΑΤΔ Ακολουθιακή Λίστα Διαχείριση Δεικτών και Λιστών στη C ΑΤΔ Συνδεδεμένη Λίστα. Εφαρμογές και Χρήση Λιστών

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

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

Διάλεξη 13: Δομές Δεδομένων ΙΙ (Ταξινομημένες Λίστες)

Βασικές οµές εδοµένων

Γραμμικές λίστες. Γκόγκος Χρήστος ΤΕΙ Ηπείρου

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

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

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

Επιλογές και Κριτήρια Σχεδιασμού ΑΤΔ Ανεξαρτήτως από Γλώσσα Υλοποίησης 24/4/2012

Διάλεξη 15: Δομές Δεδομένων IV (Διπλά Συνδεδεμένες Λίστες)

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

Δομές Δεδομένων. Ενότητα 4: Ο ΑΤΔ Λίστα & Υλοποίηση Λίστας με σειριακή αποθήκευση- Ο ΑΤΔ Συνδεδεμένη Λίστα- Υλοποίηση ΑΤΔ Συνδεδεμένη Λίστα με πίνακα

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

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

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

Βασικές Έννοιες Δοµών Δεδοµένων

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

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

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

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

Δείκτες και Δομές. Info. Link. typedef struct NodeTag { InfoField Info; struct NodeTag *Link; } NodeType;

Πανεπιστήµιο Θεσσαλίας, THMMY HY120, Σεπτέµβριος 2015 ΟΝΟΜΑΤΕΠΩΝΥΜΟ:

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

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

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

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

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

ιαφάνειες παρουσίασης #5 (β)

Επανάληψη για τις Τελικές εξετάσεις

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Οι λίστες, χάνοντας τα πλεονεκτήματα των πινάκων, λύνουν προβλήματα που παρουσιάζουν οι πίνακες

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

Προγραμματισμός Δομές Δεδομένων

Εργαστήριο 5: Υλοποίηση Αφηρημένου Τύπου Δεδομένων: Διπλά Συνδεδεμένη Λίστα

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

Διάλεξη 08: Λίστες ΙΙ Κυκλικές Λίστες

Ενότητα 2: Στοίβες Ουρές - Λίστες Ασκήσεις και Λύσεις

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

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

Στοίβες με Δυναμική Δέσμευση Μνήμης

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

Στοιχειώδεις Δομές Δεδομένων

Διάλεξη 22η: Επιπλέον στοιχεία της C

Συνδεδεμένη Λίστα (Linked List)

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

Οργάνωση αρχείων: πως είναι τοποθετηµένες οι εγγραφές ενός αρχείου όταν αποθηκεύονται στο δίσκο

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

Εισαγωγή στον Προγραμματισμό

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

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

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

Η γλώσσα προγραμματισμού C Συνδεδεμένες Λίστες

Sheet2. Σωστή, και µπράβο που µεριµνήσατε για λίστες διαφορετικών µεγεθών.

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

#2 Αλγόριθµοι, οµές εδοµένων και Πολυπλοκότητα

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

Ενότητα 2: Στοίβες Ουρές - Λίστες Ασκήσεις και Λύσεις

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

ΕΝΟΤΗΤΑ 6 ΛΙΣΤΕΣ ΠΑΡΑΛΕΙΨΗΣ (SKIP LISTS)

Σύνοψη Προηγούμενου. Λίστες (Lists) Συνδεδεμένες Λίστες: Εισαγωγή (1/2) Συνδεδεμένες Λίστες. Ορέστης Τελέλης

Θεωρητικό Μέρος. int rec(int n) { int n1, n2; if (n <= 5) then return n; else { n1 = rec(n-5); n2 = rec(n-3); return (n1+n2); } }

Απλές Δοµές Δεδοµένων Στην ενότητα αυτή θα γνωρίσουµε ορισµένες απλές Δοµές Δεδοµένων και θα τις χρησιµοποιήσουµε για την αποδοτική επίλυση του προβλή

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

Στόχοι και αντικείμενο ενότητας. Πέρασμα Πίνακα σε Συνάρτηση (συν.) Πέρασμα Πίνακα σε Συνάρτηση. #8.. Ειδικά Θέματα Αλγορίθμων

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

Ιδιοκτησία Αντικειµένου

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

Δείτε τώρα και πώς θα έπρεπε να ήταν το παραπάνω: Page 1

ΣΥΜΒΟΛΟΣΕΙΡΕΣ (Strings) Ο ΑΤΔ Συµβολοσειρά Μία συµβολοσειρά είναι µία ακολουθία χαρακτήρων. Bασικές πράξεις : 1. Δηµιουργία. 2. Μήκος. 3.

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Ενδεικτικές Απαντήσεις Εξετάσεων Α' Περιόδου Θέµα 1. (α') 2 - ii 3 - iii 4 - iv

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Ταξινόµηση Mergesort Κεφάλαιο 8. Ε. Μαρκάκης Επίκουρος Καθηγητής

Προγραμματισμός Η/Υ. Ενότητα 9: Ειδικά θέματα Δομών Δεδομένων

ΕΝΟΤΗΤΑ 7 ΟΥΡΕΣ ΠΡΟΤΕΡΑΙΟΤΗΤΑΣ ΣΩΡΟΙ

Εισαγωγή στην επιστήμη των υπολογιστών. Οργάνωση εδομένων Κεφάλαιο 11ο ομές εδομένων

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

Διάλεξη 10: Δομές Δεδομένων Ι (Στοίβες & Ουρές)

Alternative to Balanced Trees, Comms of the ACM, 33(6), June 1990,

Transcript:

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

Ανασκόπηση ΟΑΤ λίστα Ακολουθιακή λίστα Συνδεδεµένη λίστα Υλοποίηση συνδεδεµένης λίστας µε πίνακα Υλοποίηση συνδεδεµένης λίστας µε δείκτες Παραδείγµατα Λίστα µε header Λίστα µε sentinel Κυκλική λίστα ιπλά συνδεδεµένη λίστα Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 2

ΑΤ Λίστα Γραµµική συλλογή στοιχείων ίδιου τύπου Έχει πρώτο και τελευταίο στοιχείο Κάθε στοιχείο εκτός του πρώτου έχει ένα προηγούµενο Κάθε στοιχείο εκτός του τελευταίου έχει ένα επόµενο Εφαρµογές: γραµµική διαχείριση πληροφοριών στοιχείο 1 στοιχείο ν-1 στοιχείο ν πρώτο τελευταίο Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 3

Υποστηρίζει τις πράξεις: ΑΤ Λίστα (2) ηµιουργία κενής λίστας Εισαγωγή, διαγραφή και αναζήτηση συγκεκριµενου στοιχείου Μήκος λίστας Έλεγχος αν η λίστα είναι κενή... Π.χ. εισαγωγή στοιχείου στοιχείο ν+1 στοιχείο 1 στοιχείο ν-1 στοιχείο ν πρώτο τελευταίο Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 4

Υλοποίηση λίστας Ακολουθιακή Λίστα Αποθηκεύει διαδοχικά στοιχεία σε γειτονικές θέσεις µνήµης Βασίζεται σε πίνακα ιατηρεί το πλήθος των στοιχείων σε βοηθητική µεταβλητή typedef struct { seqlist_t list; int number; void init(seqlist *list) { element_t records[maxelements]; list->number = 0; seqlist_t; a 1 a n records 0 number-1 MaxElements-1 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 5

Εισαγωγή Στοιχείου O(n) void insertafter(seqlist_t *listptr, element_t elem, int pos) { /* number < MaxElements && pos >= 0 && pos <= number 1 */ /* µετακίνηση στοιχείων δεξιά κατά 1 θέση*/ for (int i = listptr->number 1; i >= pos + 1; i--) listptr->records[i+1] = listptr->records[i]; listptr->records[pos+1] = elem; listptr->number++; pos number-1 MaxElements-1 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 6

ιαγραφή Στοιχείου Ο(n) void delete(seqlist_t *listptr, int pos) { /* pos >= 0 && pos <= number 1 */ /* µετακίνηση στοιχείων αριστερά κατά 1 θέση*/ for (int i = pos; i <= listptr->number 1; i++) listptr->records[i] = listptr->records[i+1]; listptr->number--; pos number-1 MaxElements-1 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 7

Μειονεκτήµατα Πίνακα Σταθερό µέγεθος που καθορίζεται κατά τη δήλωση ή τη δηµιουργία του πίνακα Συνήθως ο προγραµµατιστής δηλώνει «αρκετά µεγάλο» πίνακα που οδηγεί σε Αχρησιµοποίητη µνήµη Τερµατισµό προγράµµατος αν η πρόβλεψη έγινε λάθος Εισαγωγή στοιχείων στην αρχή του πίνακα ακριβή Προσπέλαση στοιχείων απαιτεί υπολογισµό διεύθυνσης Αλλά το κόστος διαχείρισης µνήµης χαµηλό Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 8

Απλή Συνδεδεµένη Λίστα Κάθε στοιχείο της λίστας καλείται κόµβος και περιέχει εδοµένα είκτη στον επόµενο κόµβο της λίστας Μια µεταβλητή δείχνει στον πρώτο κόµβο της λίστας κενή λίστα λίστα δεδοµένα Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 9

Τέσσερις δείκτες Εισαγωγή Στοιχείου O(1) head δείχνει στον πρώτο κόµβο newnode δείχνει στο νέο κόµβο current διατρέχει τους κόµβους beforecurrent δείχνει τον κόµβο αµέσως πριν τον current newnode head beforecurrent current Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 10

Τρεις δείκτες ιαγραφή Στοιχείου O(1) headδείχνει στον πρώτο κόµβο current διατρέχει τους κόµβους beforecurrent δείχνει τον κόµβο αµέσως πριν τον current head beforecurrent current Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 11

Σύγκριση Κόστους Πράξεων Συνδεδεµένη λίστα Εισαγωγή και διαγραφή κόµβου κοστίζει σταθερό χρόνο Ο(1) Αναζήτηση στοιχείου κοστίζει γραµµικό χρόνο Ο(n) Ακολουθιακή λίστα Εισαγωγή και διαγραφή κόµβου κοστίζει γραµµικό χρόνο Ο(n) Αναζήτηση i-στού στοιχείου κοστίζει σταθερό χρόνο Ο(1) Αναζήτηση µε βάση το περιέχοµενο κοστίζει γραµµικό χρόνο O(n) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 12

Στατική Συνδεδεµένη Λίστα Πίνακας σταθερού αριθµού δοµών typedef struct { data_t data; /* δεδοµένα */ int next; /* δείκτης στοιχείου πίνακα */ node_t; node_t nodes[maxnodes]; Μειονεκτήµατα Ανάγκη πρόβλεψης του αριθµού κόµβων πριν την εκτέλεση έσµευση µνήµης για όλους τους κόµβους κατά την εκτέλεση... Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 13

Αρχικοποίηση Πίνακα freenode /* λίστα διαθέσιµων κόµβων */ for (int i = 0; i < MaxNodes 1 ; i++ ) nodes[i].next = i + 1; nodes[maxnodes-1].next = -1; /* πρώτος διαθέσιµος κόµβος */ freenode= 0; 0 1 2 3 data next 1 2 3 4 /* κενή λίστα */ int head = -1; 4 5 5 6 6-1 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 14

έσµευση & Αποδέσµευση Κόµβου freenode int getnode() { int c; If (freenode == -1) return (-1) /* υπερχείλιση */ c = freenode; freenode = nodes[freenode].next; return (c); void relnode(int c) { nodes[c].next = freenode; freenode = c; 0 1 2 3 4 5 data next 1 2 3 4 5 6 6-1 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 15

Εισαγωγή Κόµβου freenode headptr void insafter(int *headptr, int b, data_t d) { int n; if ((n = getnode()) < 0) printf( υπερχείλιση ); else { nodes[n].data = d; if (b < 0) { /* αρχή λίστας */ nodes[n].next = *headptr; *headptr = n; else { /* ενδιάµεσα */ nodes[n].next = nodes[b].next; nodes[b].next = n; 0 1 2 3 4 5 6 d 1-1 3 4 5 6-1 current newnode Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 16

ιαγραφή Κόµβου void delafter(int *headptr, int b, data_t *d) { int c; freenode if (b < 0) { /*διαγραφή πρώτου κόµβου*/ if (*headptr >= 0) { c = *headptr; *headptr = nodes[c].next; *d = nodes[c].data; relnode(c); else printf( κενή λίστα ); else if (nodes[b].next < 0) printf( άκυρη διαγραφή ); else { /* διαγραφή ενδιάµεσου κόµβου */ c = nodes[b].next; *d = nodes[c].data; nodes[b].next = nodes[c].next; relnode(c); 0 1 2 3 4 5 6 headptr 2-1 1 4 5 6-1 beforecurrent current Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 17

Αναζήτηση Κόµβου int find(int head, data_t d) { while (head > -1 && nodes[head].data!= d) head = nodes[head].next; return (head); 0 freenodes 1 int findi(int head, int i) { if (i < 1) return (-1); while (head > -1 && --i) head = nodes[head].next; 2 3 4 head 2-1 1 4 5 return (head); 5 6 6-1 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 18

υναµική Συνδεδεµένη Λίστα υναµική καταχώρηση µνήµης για δηµιουργία κόµβων Ορίζεται µε αυτοαναφορική (ή αναδροµική) δοµή /* δήλωση τύπου */ typedef struct node { data_t data; struct node *next; node_t, *nodeptr_t; /* ορισµός λίστας */ nodeptr_t head = NULL; Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 19

έσµευση και Αποδέσµευση Κόµβου /* δέσµευση µνήµης κόµβου */ nodeptr_t getnode(data_t d) { nodeptr_t newnode; newnode = (nodeptr_t) malloc(sizeof(node_t)); newnode->data = d; return (newnode); newnode data next /* αποδέσµευση µνήµης κόµβου */ void relnode(nodeptr_t oldnode) { free(oldnode); Heap Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 20

Εισαγωγή Κόµβου void insafter(nodeptr_t *headptr, nodeptr_t b, data_t d) { headptr nodeptr_t n; if ((n=getnode(d)) == NULL) printf( κενός κόµβος ); else if (b == NULL) { /* πριν τον πρώτο κόµβο */ n->next = *headptr; *headptr = n; else { /* ενδιάµεσα */ n->next = b->next; b->next = n; beforecurrent newnode Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 21

ιαγραφή Κόµβου void delafter(nodeptr_t *headptr, nodeptr_t b, data_t *d) { nodeptr_t c; if (b == NULL) { /* διαγραφή πρώτου κόµβου */ if (*headptr == NULL) printf( κενή λίστα ); else { c = *headptr; *headptr = c->next; *d = c->data; relnode(c); else if (b->next == NULL) printf( άκυρη διαγραφή ); else { c = b->next; *d = c->data; b->next = c->next; relnode(c); headptr beforecurrent Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 22

Μήκος Λίστας ίνεται δείκτης στον πρώτο κόµβο της συνδεδεµένης λίστας (head) Να υπολογιστεί το µήκος της λίστας (length) head current Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 23

Λύση head int length(nodeptr_t head) { nodeptr_t current = head; int count = 0; while (current!= NULL) { count++; current = current->next; current return count; Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 24

Αντιγραφή Λίστας ίνεται δείκτης σε συνδεδεµένη λίστα Να δηµιουργηθεί ένα νέο πλήρες αντίγραφο της λίστας head head Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 25

Λύση nodeptr_t CopyList(nodePtr_t head) { /* αρχική λίστα */ nodeptr_t current = head; /* νέα λίστα */ nodeptr_t newlist = NULL; nodeptr_t tail = NULL; current head newlist while (current!= NULL) { if (newlist == NULL) { newlist = getnode(current->data); newlist->next = NULL; tail = newlist; else { tail->next = getnode(current->data); tail = tail->next; tail->next = NULL; current = current->next; return(newlist); tail Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 26

ιαγραφή Λίστας ίνεται δείκτης στον πρώτο κόµβο µίας συνδεδεµένης λίστας Να διαγραφούν όλοι οι κόµβοι από την λίστα και να αποδεσµευτεί η µνήµη που καταλαµβάνουν current head head Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 27

Λύση void deletelist(nodeptr_t *headref) { nodeptr_t current = *headref; nodeptr_t next; current head while (current!= NULL) { next = current->next; relnode(current); current = next; *headref = NULL; next Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 28

Συνδεδεµένη Λίστα µε Header Η υλοποίηση πράξεων της απλής συνδεδεµένης λίστας Συχνά απαιτεί τροποποίηση του δείκτη στον πρώτο κόµβο Εισάγει επιπλέον ειδικές περιπτώσεις στις συναρτήσεις Αυξάνει το επίπεδο έµµεσης αναφοράς σε δύο επίπεδα head Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 29

Συνδεδεµένη Λίστα µε Header (2) Μια λύση είναι η χρήση κενού κόµβου (header) στην αρχή της λίστας Απλοποιεί επαναληπτικές διεργασίες Αποθηκεύει επιπλέον χρήσιµες πληροφορίες όπως το µήκος της λίστας, δείκτη στον τελευταίο κόµβο, κτλ Αλλά ξοδεύει τη µνήµη ενός κόµβου ακόµη και για κενή λίστα header head Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 30

Εισαγωγή κόµβου σε λίστα µε Header void insertafter(nodeptr_t b, data_t d) { nodeptr n; if ((n=getnode(d)) == NULL) printf( κενός κόµβος ); else { /* ενδιάµεσα */ n->next = b->next; b->next = n; header beforecurrent newnode Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 31

ιαγραφή κόµβου από λίστα µε Header void delafter(nodeptr_t b, data_t *d) { nodeptr_t c; if (b->next == NULL) printf( άκυρη διαγραφή ); else { c = b->next; *d = c->data; b->next = c->next; relnode(c); header beforecurrent Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 32

Συνδεδεµένη Λίστα µε Sentinel Ηαναζήτηση σε απλή συνδεδεµένη λίστα συνήθως τερµατίζεται από δείκτη NULL Εναλλακτικά µπορούµε να έχουµε κάποια ειδική τιµή δεδοµένων για τερµατισµό στον τελευταίο κόµβο Απλοποιούµε τον βρόχο αναζήτησης µε λιγότερες συγκρίσεις head sentinel +oo Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 33

Παράδειγµα Θεωρήστε ακολουθία αριθµών σε αύξουσα σειρά αποθηκευµένη σε συνδεδεµένη λίστα Εξετάζουµε εναλλακτικούς τρόπους αναζήτησης /* απλή συνδεδεµένη λίστα /* λίστα µε sentinel +oo µε αύξουσα διάταξη */ τερµατίζει µε +oo > n */ while (p && p->data < n) while (p->data < n) p=p->next; p=p->next; head sentinel +oo Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 34

Κυκλική Λίστα Απλή συνδεδεµένη λίστα της οποίας ο τελευταίος κόµβος δείχνει στον πρώτο Με δείκτη σε οποιονδήποτε κόµβο της λίστας µπορούµε να φτάσουµε σε όλους τους υπόλοιπους Φυσική αναπαράσταση για συγκεκριµένες εφαρµογές Η περιφέρεια πολυγώνου µπορεί να παρασταθεί µε κυκλική λίστα των κόµβων του πολυγώνου head Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 35

Εισαγωγή Κόµβου σε Κυκλική Λίστα εδοµένης της κυκλικότητας δε χρειάζεται να τροποποιήσουµε το δείκτη στον πρώτο κόµβο παρά µόνο όταν εισάγουµε κόµβο σε κενή λίστα void insertafter(nodeptr_t *headptr, nodeptr_t nodeptr b, data_t d) { nodeptr n; if ((n=getnode(d)) == NULL) printf( κενός κόµβος ); else if (*headptr == NULL) { n->next = n; /* κενή λίστα */ *headptr = n; else { /* ενδιάµεσα */ n->next = b->next; b->next = n; head beforecurrent newnode Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 36

ιαδροµή Κυκλικής Λίστας Αν η λίστα ενδέχεται να είναι κενή χρειάζεται ειδική αντιµετώπιση µε έλεγχο if (head == NULL) Αλλιώς µπορούµε να χρησιµοποιήσουµε το βρόχο op = p = head do { /* επεξεργασία p */ p = p->next while (p!= op) /*συνθήκη τερµατισµού*/ Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 37

ιπλά Συνδεδεµένη Λίστα Κάθε κόµβος έχει δείκτη τόσο στον προηγούµενο όσο και στον επόµενο κόµβο Από ένα κόµβο έχουµε άµεση πρόσβαση στους δύο γειτονικούς σε σταθερό χρόνο Ο(1) Εισάγουµε κόµβο πριν ή µετά από κόµβο µε ένα δείκτη ιαγράψουµε κόµβο µε ένα δείκτη ιατρέχουµε τη λίστα σε δύο κατευθύνσεις Μειονεκτήµατα Χρησιµοποιεί διπλάσιο αριθµό δεικτών από την απλή Αυξάνει την πιθανότητα σφάλµατος δεικτών head Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 38

ήλωση ιπλά Συνδεδεµένης Λίστας Χρειαζόµαστε δύο δείκτες σε κάθε κόµβο που να δείχνουν στον προηγούµενο και τον επόµενο κόµβο struct node { data_t data; struct node *prev, *next; node_t, *nodeptr_t; Εναλλακτικά µπορούµε να χρησιµοποιήσουµε array δύο στοιχείων για εύκολη υλοποίηση αµφίδροµης διαδροµής struct node { data_t data; struct node *link[2]; node_t, *nodeptr_t; Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 39

Αρχικοποίηση ιπλά Συνδεδεµένης Λίστας Θεωρούµε διπλά συνδεδεµένη λίστα µε header void create(nodeptr_t *headptr) { nodeptr_t header = (nodeptr_t) malloc(sizeof(node_t)); header->prev = header->next = NULL; *headptr = header; head header Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 40

Εισαγωγή Κόµβου void insertafter(nodeptr_t b, data_t d) { nodeptr n; if ((n=getnode(d)) == NULL) printf( κενός κόµβος ); else { /* ενδιάµεσα */ n->prev = b; n->next = b->next; if (b->next!= NULL) b->next->prev = n; b->next = n; header head newnode beforecurrent Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 41

Υλοποίηση Συνόλου µε Λίστα Χρησιµοποιούµε απλή συνδεδεµένη λίστα ταξινοµηµένων στοιχείων: empty(s) : ελέγχει αν το σύνολο s είναι κενό dumpset(s) : τυπώνει τα µέλη του συνόλου member(s, n) : ελέγχει αν το n είναι στοιχείο του s insert(s, n) : εισάγει το στοιχείο n στο s unite(s 1, s 2 ) : επιστρέφει την ένωση των s 1 και s 2 typedef struct element element; struct element { element *next; int value; ; typedef element *set; #define empty(s) (s == NULL) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 42

Υλοποίηση Πράξεων Συνόλου /* τυπώνει τα µέλη του συνόλου */ void dumpset(set s) { while (s) { printf( %d, s->value); s = s->next; /* ελέγχει αν το n είναι µέλος του s */ int member(set s, int n) { while (s && s->value < n) s = s->next; return s && s->value == n; Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 43

Eισαγωγή Στοιχείου σε Σύνολο /* εισάγει το στοιχείο n στο σύνολο s */ set insert(set s, int n) { element dummy, *p, *new; p = &dummy; p->next = s; while (p->next && p->next->value < n) p = p->next; if (!(p->next && p->next->value == n)) { /* το n δεν είναι µέλος του συνόλου */ new = (element *) malloc(sizeof(element)); new->value = n; new->next = p->next; p->next = new; return dummy.next; dummy p new Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 44

Ένωση Συνόλων /* εισάγει το στοιχείο n στο σύνολο s */ set unite(set s1, set s2) { element dummy, *p; p = &dummy; while (s1 && s2) { if (s1->value < s2->value) p->next=getnode(s1->value); s1=s1->next; else if (s2->value < s1->value) { p-> next = getnode(s2->value); s2 = s2->next; else { /* ίδια µέλη */ p->next = getnote(s1->value); s1 = s1->next; s2 = s2->next; p = p->next; /* αντιγραφή υπολοίπου συνόλου */ if (!s1) s1 = s2; while (s1) { p->next = getnode(s1->value); p = p->next; s1 = s1->next; return dummy.next; /* δηµιουργία νέου κόµβου */ element *getnode(int n) { element *p = (element *) malloc(sizeof(element)); p->value = n; return p; Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 45