html5-img
1 / 55

Data Structures

Andreas Savva. Data Structures. Chapter 6 Linked Lists. Jacky. 99-296580. Paul. Carol. Tom. 18 Feb. 99-456543. 99-785434. 99-672205. 30 Jun. 21 Jan. 28 Feb. Fred. 99-767554. 3 Oct. Lists. Like a stack or a queue, a list has a sequence of entries as its data values.

amory
Télécharger la présentation

Data Structures

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Andreas Savva Data Structures Chapter 6 Linked Lists

  2. Jacky 99-296580 Paul Carol Tom 18 Feb 99-456543 99-785434 99-672205 30 Jun 21 Jan 28 Feb Fred 99-767554 3 Oct Lists • Like a stack or a queue, a list has a sequence of entries as its data values. • However, unlike a stack or a queue, a list permits operations that alter arbitrary entries of the sequence. A linked list

  3. List Definition • A list of elements of type T is a finite sequence of elements of T together with the following operations: • Construct the list, leaving it empty. • Determine whether the list is empty or not. • Determine whether the list is full or not. • Find the size of the list. • Clear the list to make it empty. • Insert an entry at a specified position of the list. • Remove an entry at a specified position in the list. • Retrieve the entry from a specified position in the list. • Replace the entry at a specified position in the list. • Traverse the list, performing a given operation on each entry.

  4. A Simple Linked List implementation structList { // data members List_entry head; List *tail; // constructors List(); List(List_entry item, List *lst = NULL); }; List::List() { tail = NULL; } List::List(List_entry item, List *lst) { head = item; tail = lst; }

  5. List Functions List *cons(List_entry x, List *lst) { List *m = new List(x, lst); if (m == NULL) { cout << “Memory full” << endl; return lst; } elsereturn m; } List_entry head(List *lst) { return lst->head; } List *tail(List *lst) { return lst->tail; }

  6. Insert - Sorted List *insert(List_entry x, List *lst) { if (lst == NULL) return cons(x, NULL); else if (x < head(lst)) return cons(x, lst); else return cons(head(lst), insert(x, tail(lst))); } insert(5, [1,3,4,7,9,12])

  7. cons(1, insert(5, [3,4,7,9,12])) cons(1, cons(3, insert(5, [4,7,9,12]))) cons(1, cons(3, cons(4, insert(5, [7,9,12])))) cons(1, cons(3, cons(4, cons(5, [7,9,12])))) cons(1, cons(3, cons(4, [5,7,9,12]))) cons(1, cons(3, [4,5,7,9,12])) cons(1, [3,4,5,7,9,12]) [1,3,4,5,7,9,12] Insert insert(5, [1,3,4,7,9,12])

  8. Garbage lst 1 3 4 7 9 12 5 4 3 1 lst Insert - Garbage insert(5, [1,3,4,7,9,12]) cons(1, insert(5, [3,4,7,9,12])) cons(1, cons(3, insert(5, [4,7,9,12]))) cons(1, cons(3, cons(4, insert(5, [7,9,12])))) cons(1, cons(3, cons(4, cons(5, [7,9,12])))) cons(1, cons(3, cons(4, [5,7,9,12]))) cons(1, cons(3, [4,5,7,9,12])) cons(1, [3,4,5,7,9,12]) [1,3,4,5,7,9,12]

  9. Insert - Sorted List *insert(List_entry x, List *lst) { if (lst == NULL) return cons(x, NULL); else if (x < head(lst)) return cons(x, lst); else { List *temp = lst; return cons(head(lst), insert(x, tail(lst))); delete temp; } } insert(5, [1,3,4,7,9,12])

  10. Exercises • Write the following functions: • List *remove(List_item x, List *l); • int length(List *l); • bool isin(List_item x, List *l); • int nooftimes(List_item x, List *l); • List *append(List *l, List *t); • List *reverse(List *l); • void print(List *l);

  11. Class Templates • A C++ template construction allows us to write code to implement a class, that uses objects of an arbitrary, generic type. • In template code we utilize a parameter enclosed in angles brackets <………> to denote the generic type. List<int> first_list; List<char> second_list;

  12. The Node Structure template <class Node_entry> structNode { Node_entry entry; Node<Node_entry> *next; Node (); Node(Node_entry item, Node<Node_entry> *n = NULL); }; template <class Node_entry> Node<Node_entry>::Node() { next = NULL; } template <class Node_entry> Node<Node_entry>::Node(Node_entry item, Node<Node_entry> *n) { entry = item; next = n; }

  13. 3 4 7 9 12 Andy Ann John Mark Paul Sorted Linked Lists • Lists are sequential (visit one node at a time) • Sequential sorting Examples of sorted linked lists:

  14. The List Class template <class List_entry> class List { public: List(); void clear(); bool empty() const; int size() const; Error_code remove(const List_entry &item); Error_code insert(const List_entry &item); void print() const; // Safeguards ~List(); List(const List<List_entry> &copy); voidoperator = (const List<List_entry>&original); protected: Node<List_entry>*head; };

  15. head Create List Constructor: template <class List_entry> List<List_entry>::List( ) { head = NULL; }

  16. Empty template <class List_entry> bool List<List_entry>::empty() const { return head == NULL; }

  17. head temp 3 4 7 9 12 Size template <class List_entry> int List<List_entry>::size() const { int count = 0; Node<List_entry> *temp = head; while (temp!=NULL) { count++; temp = temp->next; } return count; } count 1 4 5 2 3 0

  18. new_entry head else If (item<head->entry) head new_entry 4 4 5 6 8 9 Insert Numbers.insert(4); If (empty())

  19. head head current previous current previous // If (current==NULL) new_entry new_entry 3 2 1 1 6 4 3 4 2 NULL Insert (continue) else

  20. Insert template <class List_entry> Error_code List<List_entry>::insert(const List_entry &item) { Node<List_entry> *new_entry = new Node<List_entry>(item); if (new_entry == NULL) return overflow; // IF FULL else if (empty()) head = new_entry; else if (item < head->entry) { new_entry->next = head; head = new_entry; } else { Node<List_entry> *previous = head, *current = head->next; while (current != NULL) { if (item < current->entry) { new_entry->next = current; break; // Exit the loop } previous = current; current = current->next; } previous->next = new_entry; } return success; }

  21. head head else current current previous 8 4 9 3 4 6 9 1 Remove Numbers.remove(4); If (item==head->entry)

  22. Remove template <class List_entry> Error_code List<List_entry>::remove(const List_entry &item) { Node<List_entry> *current = head; if (empty()) return underflow; if (item < head->entry) returnnot_found; if (item == head->entry) { head = head->next; delete current; returnsuccess; } Node<List_entry> *previous = current; current = current->next; while (current != NULL) { if (item < current->entry) break; // Exit the loop if (item == current->entry) { previous->next = current->next; delete current; returnsuccess; } else { previous = current; current = current->next; } } returnnot_found; }

  23. head temp Screen 3 4 7 9 12 Print template <class List_entry> void List<List_entry>::print() const { Node<List_entry> *temp = head; if (empty()) cout << "Empty List" << endl; else while (temp != NULL) { cout << temp->entry << endl; temp = temp->next; } } 3 4 7 9 12

  24. head temp 3 4 7 9 12 Clear & ~List template <class List_entry> void List<List_entry>::clear() { Node<List_entry> *temp; while (head != NULL) { temp = head; head = head->next; delete temp; } } NULL

  25. Size - Recursive template <class List_entry> int List<List_entry>::size_recursive(Node<List_entry> *lst) const { if (lst == NULL) return 0; else return 1 + size_recursive(lst->next); } template <class List_entry> int List<List_entry>::size() const { returnsize_recursive(head); }

  26. Print - Recursive template <class List_entry> void List<List_entry>::print_recursive(Node<List_entry> *lst) const { if (lst != NULL) { cout << lst->entry << endl; print_recursive(lst->next); } } template <class List_entry> void List<List_entry>::print() const { if (empty()) cout << "Empty List" << endl; else print_recursive(head); }

  27. head Cursor Dear Ann I am now living in Cyprus where I got marr|ied and bought a house. This is a great place to be. The weather is perfect and life is . . . ’D’ ’e’ ’a’ ’r’ ’ ’ ’A’ ’n’ ’n’ ’\n’ ’I’ . . . Unsorted Lists • A text editor example: • Using position (cursor) for insert, remove, replace.

  28. The List Class template <classEntry> class List { public: . . . . . voidtraverse(void(*visit)(Entry &)); private: intcount; // Number of nodes in the list Node<Entry> *head; // Auxiliary function used to locate list position Node<Entry> *set_position(int position) const; };

  29. Empty template <class Entry> bool List<Entry>::empty() const { return count == 0; }

  30. Size template <class Entry> int List<Entry>::size() const { return count; }

  31. head q ’S’ ’P’ ’A’ ’I’ ’N’ current Set Position Position starts at 0 template<class Entry> Node<Entry> *List<Entry>::set_position(int position) const { Node<Entry> *q = head; for (int i=0; i<position; i++) q = q->next; return q; } Example: current = set_position(2); 0 1 2 3 4 i 1 0 2

  32. Traverse template <class Entry> void List<Entry>::traverse(void (*visit)(Entry &)) { Node<Entry> *current = head; for (int i=0; i<count; i++) { (*visit)(current->entry); current = current->next; } }

  33. Example: What output will be produced by the program on the left if the list numbers is as bellow? head Screen 4 5 8 10 13 3 4 7 9 12 Calling Traverse for Printing void AddOne(int &x) { x++; } void Print(int &x) { cout << x << endl; } void main( ) { List<int> numbers; . . . . . numbers.traverse(AddOne); numbers.traverse(Print); }

  34. Retrieve template <class Entry> Error_code List<Entry>::retrieve(int position, Entry &x) { if (empty()) return underflow; if (position < 0 || position >= count) return range_error; Node<Entry> *current; current = set_position(position); x = current->entry; return success; }

  35. Insert template <class Entry> Error_code List<Entry>::insert(int position, const Entry &x) { if (position < 0 || position > count) return range_error; Node<Entry> *new_node, *previous, *current; if (position == 0) current = head; else { previous = set_position(position - 1); current = previous->next; } new_node = new Node<Entry>(x,current); if (new_node == NULL) return overflow; if (position == 0) head = new_node; else previous->next = new_node; count++; return success; }

  36. head head else current current previous new_entry new_entry ’u’ ’o’ ’u’ ’s’ ’e’ ’h’ ’e’ ’s’ ’o’ ’h’ Insert if (position==0)

  37. Remove template <class Entry> Error_code List<Entry>::remove(int position) { if (position < 0 || position >= count) return range_error; Node<Entry> *previous, *current; if (position == 0) current = head; else { previous = set_position(position - 1); current = previous->next; } if (position == 0) head = head->next; else previous->next = current->next; delete current; count--; return success; }

  38. head head else current current previous ’s’ ’c’ ’a’ ’t’ ’p’ ’c’ ’a’ ’t’ Remove if (position==0)

  39. Replace template <class Entry> Error_code List<Entry>::replace(int position, const Entry &x) { if (position < 0 || position >= count) return range_error; Node<Entry> *current; current = set_position(position); current->entry = x; return success; }

  40. Keeping the Current Position template <class Entry> class List { public: . . . . . protected: int count; mutableint current_position; Node<Entry> *head; mutableNode<Entry> *current; voidset_position(int position) const; }; Mutable data members of a class can be changed, even by constant methods

  41. Set Position template<class Entry> void List<Entry>::set_position(int position) const { if (position < current_position) { // start over at head of list current_position = 0; current = head; } for (; current_position < position; current_position++) current = current->next; }

  42. ’e’ ’H’ ’n’ ’l’ ’e’ Doubly Linked Lists • In the last section the problem of moving backwards was solved by traversing the list from its beginning until the desired node was found, but this solution is generally unsatisfactory since: • its programming is difficult, and • the running-time of the program will depend on the length of the list, which may be quite long. • Some applications of linked lists require that we move both forward and backward through the list.

  43. ’e’ ’H’ ’n’ ’l’ ’e’ 0 3 1 2 4 current Doubly Linked Lists current_position 3 Class data members Set Position: for ( ; current_position < position ; current_position++) current = current->next; for ( ; current_position > position ; current_position--) current = current->back;

  44. The Node Structure template <classEntry> struct Node { Entry entry; Node<Entry> *back; Node<Entry> *next; Node(); Node(Entry item, Node<Entry> *b = NULL, Node<Entry> *n = NULL); }; template <class Entry> Node<Entry>::Node() { next = NULL; back = NULL; } template <class Entry> Node<Entry>::Node(Entry item, Node<Entry> *b, Node<Entry> *n) { entry = item; back = b; next = n; }

  45. The Class List template <class Entry> class List { public: . . . . . protected: intcount; mutable intcurrent_position; mutable Node<Entry> *current; void set_position(int position) const; }

  46. Set Position template<class Entry> void List<Entry>::set_position(int position) const { if (current_position <= position) for (; current_position < position; current_position++) current = current->next; else for (; current_position > position; current_position--) current = current->back; }

  47. Insert template<class Entry> Error_code List<Entry>::insert(int position, const Entry &x) { Node<Entry> *new_node, *following, *preceding; if (position < 0 || position > count) return range_error; if (position == 0) { if (empty()) following = NULL; else { set_position(0); following = current; } preceding = NULL; } else { set_position(position – 1); preceding = current; following = preceding->next; } new_node = new Node<Entry>(x,preceding,following); if (new_node == NULL) return overflow; if (preceding != NULL) preceding->next = new_node; if (following != NULL) following->back = new_node; current = new_node; current_position = position; count++; return success; }

  48. new_entry ’o’ ’M’ ’t’ ’r’ ’e’ ’h’ preceding following Insert thelist.insert(3,’h’); 0 3 1 2 4

  49. Remove template<class Entry> void List<Entry>::remove(int position) { Node<Entry> *new_node, *following, *preceding; if (position < 0 || position >= count) return range_error; set_position(position); if (position == 0) preceding = NULL; else preceding = current->back; if (position == count-1) following = NULL; else following = current->next; if (preceding != NULL) preceding->next = following; if (following != NULL) following->back = preceding; delete current; count--; if (!empty()) if (following == NULL) { current_position = position – 1; current = preceding; } else current = following; return success; }

  50. ’l’ ’e’ ’H’ ’n’ ’e’ current preceding following Remove thelist.remove(2);

More Related