Γραμμικές λίστες Γκόγκος Χρήστος ΤΕΙ Ηπείρου
Στατική αναπαράσταση γραμμικής λίστας const int MAX = 50000; struct static_list { T elements[max]; int size = 0; ; https://www.securecoding.cert.org/confluence/display/cplusplus/ctr00-cpp.+understand+when+to+prefer+vectors+over+arrays 2
Επιστροφή του στοιχείου που βρίσκεται στη θέση i T access(static_list<t>& static_list, int i) { if (i < 0 i >= static_list.size) throw -1; else return static_list.elements[i]; 3
Αναζήτηση στοιχείου στη λίστα int search(static_list<t>& static_list, T x) { for (int i = 0; i < static_list.size; i++) if (static_list.elements[i] == x) return i; return -1; 4
Προσθήκη στοιχείου στο τέλος της λίστας void push_back(static_list<t>& static_list, T x) { if (static_list.size == MAX) return; static_list.elements[static_list.size] = x; static_list.size++; 5
Προσθήκη στοιχείου στη θέση i void insert(static_list<t>& static_list, int i, T x) { if (static_list.size == MAX) return; if (i < 0 i >= static_list.size) return; for (int k = static_list.size; k > i; k--) { static_list.elements[k] = static_list.elements[k - 1]; static_list.elements[i] = x; static_list.size++; 6
Διαγραφή στοιχείου που βρίσκεται στη θέση i void delete_item(static_list<t>& static_list, int i) { if (i < 0 i >= static_list.size) return; for (int k = i; k < static_list.size; k++) { static_list.elements[k] = static_list.elements[k + 1]; static_list.size--; 7
Αξιολόγηση στατικής λίστας Θετικά Εύκολη υλοποίηση Σταθερός Ο(1) χρόνος εντοπισμού στοιχείου με βάση τη θέση του Γραμμικός χρόνος O(n) για αναζήτηση, εισαγωγή και διαγραφή στοιχείου Αρνητικά Δέσμευση μεγάλου τμήματος μνήμης ακόμη και όταν η λίστα περιέχει λίγα στοιχεία ή είναι άδεια Επιβάλει άνω όριο στο μέγεθος των δεδομένων που μπορεί να δεχθεί (ωστόσο ο περιορισμός αυτός μπορεί να ξεπεραστεί με συνθετότερη υλοποίηση που αυξομειώνει το μέγεθος του πίνακα υποδοχής όταν απαιτείται) 8
Αναπαράσταση γραμμικής λίστας με απλά συνδεδεμένη λίστα struct node { T data; struct node<t>* next = NULL; ; struct linked_list { struct node<t>* head = NULL; int size = 0; ; http://www.codeproject.com/articles/24684/how-to-create-linked-list-using-c-c 9
Επιστροφή του στοιχείου που βρίσκεται στη θέση i struct node<t>* access(linked_list<t>& linked_list, int i) { if (i < 0 i >= linked_list.size) return NULL; struct node<t>* current = linked_list.head; for (int k = 0; k < i; k++) { current = current->next; return current; 10
Αναζήτηση στοιχείου int search(linked_list<t>& linked_list, T x) { struct node<t>* current = linked_list.head; int i = 0; while (current!= NULL) { if (current->data == x) return i; i++; current = current->next; return -1; 11
Προσθήκη στοιχείου μετά τη θέση i void insert_after(linked_list<t>& linked_list, int i, T x) { if (i < 0 i >= linked_list.size) return; struct node<t>* ptr = access(linked_list, i); struct node<t>* new_node = new node<t>(); new_node->data = x; new_node->next = ptr->next; ptr->next = new_node; linked_list.size++; 12
Προσθήκη στοιχείου στην κεφαλή της λίστας void insert_head(linked_list<t>& linked_list, T x) { struct node<t>* new_node = new node<t>(); new_node->data = x; new_node->next = linked_list.head; linked_list.head = new_node; linked_list.size++; 13
Προσθήκη στοιχείου στη θέση i void insert(linked_list<t>& linked_list, int i, T x) { if (i == 0) insert_head(linked_list, x); else insert_after(linked_list, i - 1, x); 14
Προσθήκη στοιχείου στο τέλος της λίστας void push_back(linked_list<t>& l, T x) { struct node<t>* new_node, *current; new_node = new node<t>(); new_node->data = x; new_node->next = NULL; current = l.head; if (current == NULL) { l.head = new_node;l.size++; else { while (current->next!= NULL) { current = current->next; current->next = new_node; l.size++; 15
Διαγραφή στοιχείου από τη θέση i της λίστας void delete_item(linked_list<t>& l, int i) { if (i < 0 i >= l.size) return; if (i == 0) { struct node<t>* ptr = l.head; l.head = ptr->next; delete ptr; else { struct node<t>* ptr = access(l, i - 1); struct node<t>* to_be_deleted = ptr->next; ptr->next = to_be_deleted->next; delete to_be_deleted; 16
Αξιολόγηση συνδεδεμένης λίστας Θετικά Κάνει καλή χρήση του αποθηκευτικού χώρου Σταθερός χρόνος Ο(1) για την εισαγωγή και διαγραφή στοιχείων Αρνητικά Έχει συνθετότερη υλοποίηση Απαιτεί επιπλέον χώρο ανά στοιχείο λόγω της ύπαρξης των δεικτών Δεν επιτρέπει απευθείας μετάβαση σε κάποιο στοιχείο με βάση τον δείκτη του 17
STL list παράδειγμα cout << "add items 5,15,11" << endl; list<int> alist = { 5, 15, 11 ; print_std_list(alist); list<int>::iterator it; it = alist.begin(); advance(it, 1); cout << "value found at position 1 " << *it << endl; cout << "insert value 33 at position 1 " << endl; alist.insert(it, 33); print_std_list(alist); cout << "insert value 44 at position 0 " << endl; it = alist.begin(); alist.insert(it, 44); print_std_list(alist); cout << "search for item with value 33" << endl; it = std::find(alist.begin(), alist.end(), 33); cout << "value 33 found at position " << std::distance(alist.begin(), it) << endl; cout << "delete item at position 2" << endl; it = alist.begin(); advance(it, 2); alist.erase(it); print_std_list(alist); cout << "delete item at position 0" << endl; it = alist.begin(); alist.erase(it); print_std_list(alist); void print_std_list(list<int>& alist) { int i = 0; cout << "std::list ["; for (int x : alist) { cout << i << "-" << x << " "; i++; cout << "]" << endl; add items 5,15,11 std::list [0-5 1-15 2-11 ] value found at position 1 15 insert value 33 at position 1 std::list [0-5 1-33 2-15 3-11 ] insert value 44 at position 0 std::list [0-44 1-5 2-33 3-15 4-11 ] search for item with value 33 value 33 found at position 2 delete item at position 2 std::list [0-44 1-5 2-15 3-11 ] delete item at position 0 std::list [0-5 1-15 2-11 ] 18