υναµικές οµές εδοµένων (συν.) Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: Ταξινοµηµένες Λίστες µε δυναµική δέσµευση µνήµης Αναδροµκές συναρτήσεις ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 1 Λίστες Στις δοµές δεδοµένων ουρά και στοίβα είδαµε πως η θέση των στοιχείων στη δοµή εξαρτάται από την σειρά εισδοχή τους. Για παράδειγµα, σε µια στοίβα το στοιχείο στην κορυφή είναι πάντα αυτό που εισάχθηκε τελευταία, ενώ σε µια ουρά, αυτό που εισάχθηκε πρώτο. Έτσι αν εφαρµόζαµε διαδοχικά τις εντολές: εισαγωγή του 5, εισαγωγή του 1 και εισαγωγή του θα είχαµε... ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 2 1
σε στοίβα Λίστες data next 1 top size 5 σε λίστα data next data next data next NULL 1 NULL data next data next 5 head tail length ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ Λίστες... και εφαρµόζοντας τρεις φορές τις διαδικασίες pop και dequeue στη στοίβα και την ουρά, αντίστοιχα, θα επιστρέφονταν από τη στοίβα τα στοιχεία, 1, 5 (µε αυτή τη σειρά), και από την ουρά τα στοιχεία 5, 1, (µε αυτή τη σειρά). ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 4 2
Ταξινοµηµένες Λίστες Έστω ότι µας ενδιαφέρει να διατηρούµε µια δοµή στην οποία να τοποθετούµε χρήσιµα στοιχεία (π.χ. ακέραιους) ταξινοµηµένα σε κάποια σειρά (π.χ. αύξουσα) και από την οποία να µπορούµε εύκολα να προσθέτουµε και να αφαιρούµε στοιχεία. Έτσι, για παράδειγµα αν εφαρµόζαµε διαδοχικά τις εντολές: εισαγωγή του 5, εισαγωγή του 1 και εισαγωγή του θα θέλαµε η λίστα µας να είχε τη µορφή size head data next data next data next 1 NULL 5 ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 5 Ταξινοµηµένες Λίστες Ποιες δοµές χρειάζονται για υλοποίηση της ταξινοµηµένης λίστας µας; Ένας κόµβος είναι δοµικά ίδιος µε αυτό µιας συνδεδεµένης λίστας! Ενώ ο κόµβος που ορίζει τη λίστα είναι ο ίδιος µε αυτό που ορίζει µια στοίβα: typedef struct node { typedef struct slist { int data; NODE *top; struct node *next; int size; NODE; SLIST; Οι ορισµοί λοιπόν και οι κλήσεις: SLIST list; list.top = NULL; list.size = 0; ορίζουν µία λίστα, τα στοιχεία της οποίας θα κρατούνται στη µεταβλητή list τύπου SLIST και αρχικοποιούν τα πεδία της ανάλογα. ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 6
Ταξινοµηµένες Λίστες Τώρα αποµένει να ορίσουµε τρείς διαδικασίες: insert, η οποία εισαγάγει ένα στοιχείο µέσα στη λίστα, delete, η οποία αφαιρεί κάποιο στοιχείο από τη λίστα (αν αυτό υπάρχει) και printlist, η οποιά τυπώνει όλα τα στοιχεία της λίστας. Για χρήση της λίστας θα ορίσουµε επίσης σε ένα δεύτερο αρχείο µια συνάρτηση main η οποία περιέχει ένα switch που µας επιτρέπει να καλέσουµε αυτές τις διαδικασίες ταξινοµηµένης λίστας. ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 7 Παραδείγµατα Εισαγωγή του 4 στη λίστα της διαφάνειας 5: 4 1 5 4 Εξαγωγή του από τη λίστα της διαφάνειας 5: 2 1 5 ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 8 4
Η συνάρτηση main int main(){ int x, y; SLIST list; list.top = NULL; list.size = 0; while (x!= 4){ printf("you have the following options:\n"); printf("\t 1\t: for inserting an item in the list\n"); printf("\t 2\t: for deleting an item from the list\n"); printf("\t \t: for printing the list elements\n"); printf("\t 4\t: for exiting the system\n"); scanf("%d", &x); ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 9 H συνάρτηση main switch (x){ case 1: printf("enter number to be inserted: "); scanf("%d", &y); insert(&list, y); case 2: printf("give me the number to be deleted: "); scanf("%d", &y); delete(&list, y); case : printlist(&list); case 4: printf("goodbye!\n"); default: printf("wrong entry to the system\n"); return 0; ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 10 5
Η συνάρτηση printlist void printlist(slist *l){ NODE *p; if (l->size == 0) printf("the list is empty\n"); else { p = l->top; printf("%d", p->data); while((p = p->next)!= NULL) printf(", %d", p->data); printf("\n"); ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 11 Αναδροµική συνάρτηση printlist void printlist(slist *l){ if (l->size == 0) printf("the list is empty\n"); else printnode(l->top); void printnode(node *p){ if (p!= NULL){ printf("%d", p->data); printnode(p->next); ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 12 6
Η συνάρτηση insert void insert(slist *l, int x){ ++(l->size); l->top = insertnode(l->top, x); ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 1 Η συνάρτηση insertnode NODE *insertnode(node *p, int x){ NODE *q; if (p == NULL){ q = (NODE *)malloc(sizeof(node)); q->data = x; q->next = NULL; else if ( p->data >= x ) { q = (NODE *)malloc(sizeof(node)); q->data = x; q->next = p; else { q = p; q->next = insertnode(q->next, x); return q; ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 14 7
Η συνάρτηση delete void delete(slist *l, int x){ int isdeleted; l->top = deletenode(l->top, x, &isdeleted); if (isdeleted) --(l->size); ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 15 Η συνάρτηση deletenode NODE *deletenode(node *p, int x, int *isdeleted){ NODE *q; if ( ( p == NULL) (p->data > x) ){ printf("item %d not found \n", x); q = p; *isdeleted = 0; else if ( p->data == x ){ printf("item %d has been deleted\n", x); q = p->next; free(p); *isdeleted = 1; else { q = p; q->next = deletenode(q->next, x, isdeleted); return q; ΕΠΛ 12 Αρχές Προγραµµατισµού ΙΙ 16 8