Δυναμικη Δεσμευση Μνημης Συνδεδεμενες Λιστες (dynamic memory allocation, linked lists) Πως υλοποιουμαι προγραμματα που δεν γνωριζουμε πριν την εκτελεση του προγραμματος το μεγεθος των δεδομενων (πχ αριθμος φοιτητων) Δυναμικη Δεσμευση Μνημης - dynamic memory allocation
Στατικη vs Δυναμικη Δεσμευση Στατικη: γνωστη η ποσοτητα μνημης που θα δεσμευθει(αποδεσμευθει) κατα την διαρκεια του μεταγλωτισμου: κληση(επιστροφη) καθε συναρτησης, και εισοδο(εξοδο) καθε τμημα προγραμματος Δυναμικη δεσμευση:κατα την διαρκεια της εκτελεσης του προγραμματος
Δυναμικη Δεσμευση (stdlib.h) Συνταξη: malloc(αριθμος bytes) Σημασια: δεσμευει μνημη ιση με τον αριθμο bytes, επιστεφει δεικτη στην πρωτη διευθυνση int *t = malloc(sizeof(int) * 100000); δημιουργα ενα πινακα με 100000 ακεραιους for(i=0;i<100000;++i) t[i]=0; for(i=0;i<100000;++i) *(t+i)=0;
Δυναμικη Δεσμευση student_t *t; t = (student_t *) malloc(sizeof(student_t) * 100000); for(i=0;i<100000;++i) t[i].vathmos = 0; for(i=0;i<100000;++i) (t+i)->vathmos = 0;
Δυναμικη Aποδεσμευση Αποδεσμευση μνημης που δεσμευθηκε δυναμικα κατα την διαρκεια της εκτελεσης του προγραμματος free(p); αποδεσμευει μνημη που δεσμευθηκε δυναμικα και την δειχνει ο δεικτης p (garbage collection) η διευθυνση του p πρεπει να ειναι διευθυνση που επιστρεψε το malloc
Παραδειγμα Αποθηκευση μιας απροσδιοριστου μεγεθους σειρας ακεραιων αριθμων σε πινακα. Τερματιζεται με 0. Ξεκινα με πινακα με μεγεθος ν, count =0 Διαβαζε στοιχεια μεχρι το 0 count++ εαν διαβαστηκαν ν στοιχεια (count==n) δεσμευσε πινακα διπλασιου μεγεθους (2ν) αντιγραψε τον προηγουμενο στον νεο αποδεσμευσε τον παλιο ν = 2ν
int read_series(int *table, int *final_size) { int size=16, count=0, i, num; int *table = (int *) malloc(sizeof(int) * size); assert(table==NULL); /* failed to allocate memory*/ while((num=getint())!=0){ if (count==size){ temp_table = (int *) malloc(sizeof(int) * (size<<1)); assert(temp_table==NULL); /* failed to allocate memory*/ for(i=0;i<size;++i) temp_table[i]=table[i]; free(table); table = temp_table; size = size << 1; } table[count]=num; ++count; *final_size = size; return count;
Συνδεδεμενες Λιστες Πινακες δεν ειναι καλη δομη οταν θελουμε να αφαιρεσουμε(προσθεσουμε) στοιχεια απο(στην) μεση. Linked lists ειναι πιο καταληλες δομες -για εφαρμογες οπου τετοιες πραξεις ειναι συχνες.
Συνδεδεμενες Λιστες Aδεια λιστα (NULL) data id 456 grade 5.6 data pointer στο επομενο στοιχειο id 112 grade 8.6 id 456 grade 5.6 id 333 grade 3.5 id 112 grade 8.6 id 456 grade 5.6
Συνδεδεμενες Λιστες Ορισμος δομης Δημιουργια νεας δομης (δυναμικη δεσμ.) Συνδεση δομων σε λιστα Επεξεργασια λιστας Αποδεσμευση δομης (συναμικη αποδεσμ.)
struct for a link list: Aυτο-αναφορικη Δομη Δομη που περιεχει δεικτη ιδιου τυπου με την δομη struct student_node_s{ int id; float grade; struct student_node_s *next; } typedef student_node_s strudent_node_t;
traversing a link list void display_link_list(student_node_t *cursor) { while(cursor!= NULL){ printf(“Id: %d Grade: %f\n”,cursor->id, cursor->grade); cursor = cursor->next; }
Συνδεδεμενες Λιστες Δημιουργια νεας δομης (δυναμικη δεσμ.) Δημιουργια λιστας Συνδεσμοι: δεικτες αρχικα αδεια: NULL διατηρηση μεταβλητης που δειχνει στην αρχη της λιστας (head)
student_node_t* read_ids() /*diabase ids kai apothikeyse ta se synded. lista */ { int id; student_node_t *head = NULL, *node; while((id=getint())!=-1){ node =new_node(id); if(head==NULL){ /* 1o stoixeio ?*/ head = node; } else{ /*oxi 1o stoixeio*/ node->next = head; return head; /*epestrepse deikth sthn arxi tis listas */
student_node_t* new_node(int id) { student_node_t *node; node = (student_node_t *)malloc(sizeof(student_node_t)); assert(node==NULL); /* failed to allocate memory*/ node->id = id; node->grade = 0; node->next = NULL; return node; }
student_node_t* add_student(int id, student_node_t*head) /* at the front*/ { node =new_node(id); if(head==NULL){ /* 1o stoixeio ?*/ head = node; } else{ /*oxi 1o stoixeio*/ node->next = head; return head; /*epestrepse deikth sthn arxi tis listas */
student_node_t* add_student(int id, student_node_t*head) /* at the end*/ { student_node_t *node, *cursor; node =new_node(id); if(head==NULL){ /* 1o stoixeio ?*/ head = node; } else{ /*oxi 1o stoixeio*/ for(cursor=head;cursor->next!=NULL;cursor=cursor->next); cursor->next = node; return head; /*epestrepse deikth sthn arxi tis listas */
Συνδεδεμενες Λιστες Aποδεσμευση δομης (δυναμικη αποδεσμ.) Συνδεσμοι (με δεικτες)
student node_t* delete_item(student_node_t *head, int id) { student_node_t *prev, *cursor,*t; for(prev=NULL, cursor=head;cursor!= NULL; prev=cursor,cursor=cursor->next){ if (cursor->id==id){ if (prev==NULL){ /* this is the head */ t = head; head=head->next; free(t); } else{ prev->next = cursor->next; free(cursor); break; return head;}
αναζητηση στοιχειου student_node_t * get_item(student_node_t *head, int id) { student_node_t *cursor; for(cursor = head;cursor!=NULL;cursor=cursor->next) if (cursor->id == id) return cursor; } return NULL;
Συνδεδεμενες Λιστες: insertion_sort Διαβαζουμε δεδομενα ενα καθε φορα και το συνδεουμε στην λιστα ωστε η λιστα να ειναι ταξινομημενη. Αλγοριθμος:
Συγκριση: Πινακες vs Συνδεδ. Λιστες insertion/deletion: αναζητηση: ταξινομηση: