1 / 45

CSE 30331 Lecture 12 – Linked Lists …

CSE 30331 Lecture 12 – Linked Lists …. Array vs. Linked List Pointers & Nodes Singly linked list Doubly linked list Circular linked lists Header (dummy) node Implementing ADT’s Stack Queue. Reading. Linked Lists Ford: Ch 9. Array vs. Linked List. Arrays (& STL vectors)

ellis
Télécharger la présentation

CSE 30331 Lecture 12 – Linked Lists …

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. CSE 30331Lecture 12 – Linked Lists … • Array vs. Linked List • Pointers & Nodes • Singly linked list • Doubly linked list • Circular linked lists • Header (dummy) node • Implementing ADT’s • Stack • Queue

  2. Reading • Linked Lists • Ford: Ch 9

  3. Array vs. Linked List • Arrays (& STL vectors) • Direct access by index – O(1) • Insertion & deletion requires shifting – O(n) • Dynamically resizable only at one end • May require copying of all values • Pop & push at end – O(1) • Unless resizing is involved • Linked Lists ( & STL lists) • Sequential access – O(n) • Insertion & deletion without shifting – O(1) • Dynamically resizable anywhere –O(1) • Pop & push at either end – O(1)

  4. front back Abstraction of a Linked List Singly Linked List Doubly Linked List

  5. Linked List Nodes • Each Node is like a piece of a chain • To insert a new link, break the chain at the desired location and simply reconnect at both ends of the new piece.

  6. Linked List Nodes • Removal is like Insertion in reverse.

  7. Node Composition(singly linked list) • An individual Node is composed of two parts • a Data field containing the data stored by the node • a Pointer field containing the address of the next Node in the list.

  8. Inserting at the Front of an empty Singly Linked List

  9. Inserting at the Front of a nonempty Singly Linked List

  10. front // front = NULL Deleting front of a 1-node list Deleting From the Front of a Singly Linked List

  11. front // front = front->next Deleting front of a multi-node list Deleting From the Front of a Singly Linked List

  12. front next target // // prev curr Removing a Target Node

  13. A stack as a NULL terminated singly linked list

  14. Node data structure // forward declaration, just to keep the compiler happy template <typename T> class Stack; template <typename T> class Node { friend class Stack<T>; // let Stack access data & next public: Node(T value = T()) : data(value), next(NULL) { } private: T data; Node *next; };

  15. Stack as a Singly Linked List template <typename T> class Stack { public: Stack(); ~Stack(); bool empty(); // true or false, status of stack T top(); // return copy of top node’s value void pop(); // remove top node void push(T value); // create new top node with value void clear(); // remove all nodes from stack private: Node<T> *topNode; };

  16. Stack member functions template <typename T> Stack<T>::Stack() : topNode(NULL) { } template <typename T> Stack<T>::~Stack() { clear(); // make sure all memory is freed } template <typename T> bool Stack<T>::empty() { return (NULL == topNode); }

  17. Stack member functions template <typename T> T Stack<T>::top(){ if (empty()) throw(“in top() with Empty Stack”); return topNode->data; } template <typename T> void Stack<T>::pop() { if (! empty()) { Node<T> *temp = topNode; // point to top node topNode = topNode->next; // point around to next node delete temp; // free node memory } }

  18. Stack member functions template <typename T> void Stack<T>::push(T value) { Node<T> *temp = new Node<T>(value); // create new Node temp->next = topNode; // new node points to top Node topNode = temp; // now new node IS top Node } template <typename T> void Stack<T>::clear() { while(! empty()) pop(); }

  19. Stack Tester #include "myStack.h" #include <string> #include <iostream> using namespace std; int main () { Stack<string> S; string name; cout << "Enter names ('done' to quit, 'purge' to clear)\n"; cin >> name; // get first name while (name != "done") { if (name == "purge") S.clear(); else S.push(name); cin >> name; // get another name } cout << "Names entered -- NOW reversed --\n"; while (! S.empty()) { cout << S.top() " "; S.pop(); } cout << endl; return 0; }

  20. Queue as a Null Terminated Singly Linked List Need front and back pointers so we have access to both ends of list

  21. Node data structure(Queue version ~ same as Stack) // forward declaration, just to keep the compiler happy template <typename T> class Queue; template <typename T> class Node { friend class Queue<T>; // let Queue access data & next public: Node(T value = T()) : data(value), next(NULL) { } private: T data; Node *next; };

  22. Queue as a Singly Linked List template <typename T> class Queue { public: Queue(); ~Queue(); bool empty(); // true or false, status of queue T front(); // return copy of first value void pop(); // remove first node void push(T value); // create new last node with value void clear(); // remove all nodes from queue private: Node<T> *first, *last; };

  23. Queue member functions template <typename T> Queue<T>::Queue() : first(NULL), last(NULL) { } template <typename T> Queue<T>::~Queue() { // same as Stack clear(); // make sure all memory is freed } template <typename T> bool Queue<T>::empty() {// essentially same as Stack return (NULL == first); }

  24. Queue member functions template <typename T> T Queue<T>::front(){ if (empty()) throw(“in front() with Empty Queue”); return first->data; } template <typename T> void Queue<T>::pop() { if (! empty()) { Node<T> *temp = first; // point to first node first = first->next; // point around to next node delete temp; // free node memory } }

  25. Queue member functions template <typename T> void Queue<T>::push(T value) { Node<T> *temp = new Node<T>(value); // create new Node if (empty()) first = temp; // new last node is also first node else last->next = temp; // new last node follows old last = temp; // now new node IS last Node } template <typename T> void Queue<T>::clear() { while(! empty()) pop(); }

  26. Doubly Linked Lists • Singly linked list only allow easy traversal in one direction (forward) • Doubly linked lists allow easy traversal both directions (forward and backward) • The list can be linear • Having NULL pointers at both ends • The list can be circular • Having each end point back to the other • Usually this is implemented with a header node • That contains no data • That points to itself when list is empty

  27. Circular Doubly Linked Lists • A Watch Band provides a good Real Life analogue for this Data Structure

  28. Circular Doubly Linked Lists • Implemented on a Computer it might look something like this.

  29. Empty and Non Empty Doubly Linked List

  30. Implementing a Circular Doubly Linked List // forward declaration, just to keep the compiler happy template <typename T> class LinkedList; template <typename T> class Node { friend class LinkedList<T>; // let LinkedList access data & next public: Node(T value = T()) : data(value), next(NULL), prev(NULL) { } private: T data; Node *next, *prev; };

  31. LinkedList(Circular and Doubly Linked) template <typename T> class LinkedList { public: LinkedList(); ~LinkedList(); int size(); // number of nodes in list T get(int pos); // return copy of value at pos void erase(int pos); // remove first node void insert(T value, int pos); // create new node with value at pos void clear(); // remove all nodes from queue int find(T value); // return position of first node with value private: Node<T> *last, // indicate beginning and end of list *current; // indicates current node int numNodes, // number of nodes in list currentPos; // indicates current position void moveTo(int pos); // moves current to desired Node };

  32. LinkedList member functions template <typename T> LinkedList<T>::LinkedList() : numNodes(0), currentPos(-1) { last = new Node<T>; last->next = last; last->prev = last; current = last; // point to the header } template <typename T> LinkedList<T>::~LinkedList() { clear(); // make sure all Node memory is freed delete last; // free the header Node memory }

  33. LinkedList member functions template <typename T> int LinkedList<T>::size() { return numNodes; } template <typename T> void LinkedList<T>::clear() { while(size() > 0) erase(0); // remove all nodes }

  34. LinkedList member functions template <typename T> void LinkedList<T>::moveTo(int pos) { if ((pos < 0)|| (size() <= pos)) throw range_error(“LinkedList::moveTo() pos out of range”); while (currentPos < pos) // move forward along list { current = current->next; currentPos++; } while (currentPos > pos) // move backward along list { current = current->prev; currentPos--; } }

  35. LinkedList member functions template <typename T> T LinkedList<T>::get(int pos) { try { moveTo(pos); // move to indicated position in list } catch (exception &e) { cerr << “Error from LinkedList::get()\n”; cerr << e.what(); exit 1; } return current->data; // return value of Node }

  36. LinkedList member functions template <typename T> int LinkedList<T>::find(T value) { current = last->next; // point to first Node currentPos = 0; while (current != last) // move forward along list { if (current->data == value) break; current = current->next; currentPos++; } if (current == last) currentPos = -1; return currentPos; }

  37. Deleting a Node at a Position // unlink the node (*curr) from the list curr->prev->next = curr->next; curr->next->prev = curr->prev; delete curr;

  38. LinkedList member functions template <typename T> void LinkedList<T>::erase(int pos) { try { moveTo(pos); // move to indicated position in list } catch (exception &e) { cerr << “Error from LinkedList::get()\n”; cerr << e.what(); exit 1; } current->prev->next = current->next; // point around Node forward current->next->prev = current->prev; // point around Node backward delete current; // free Node memory }

  39. Inserting a Node at a Position // insert newNode before curr newNode->prev = curr->prev; newNode->next = curr; curr->prev->next = newNode; curr->prev = newNode;

  40. LinkedList member functions template <typename T> void LinkedList<T>::insert(T value, int pos) { try { moveTo(pos); // move to indicated position in list } catch (exception &e) { cerr << “Error from LinkedList::get()\n”; cerr << e.what(); exit 1; } Node<T> *newNode = new Node(value); // make a new Node with value newNode->prev = current->prev; // point back at previous Node newNode->next = current; // have it point to new Node current->prev->next = newNode; // point forward to next Node current->prev = newNode; // have it point to new Node }

  41. So what is missing? • Copy Constructor & Assignment Operator • Need a deep copy • Traverse source list • Copy each node • Insert in destination list • Comparison Operator (==) • Compare list lengths, and if equal … • Traverse both lists • Compare corresponding nodes

  42. Copy Constructor template <typename T> LinkedList<T>::LinkedList(LinkedList<T>& theList) : numNodes(0), currentPos(-1) { last = new Node<T>; last->next = last; last->prev = last; current = last; // point to the header intpos(0);// start at dummy node while (pos < theList.size()) // while nodes in theList { this->insert(theList.get(pos),pos)); // copy node and insert pos++; // move forward } }

  43. Assignment Operator (=) template <typename T> LinkedList<T>& LinkedList<T>::operator=(LinkedList<T>& theList) { if (this == &theList) return; // same lists, nothing to do LinkedList<T> *newList; intpos(0);// start at dummy node while (pos < theList.size()) // while nodes in theList { newList.insert(theList.get(pos),pos)); // copy node and insert pos++; // move forward } return newList; }

  44. Comparison (==) template <typename T> bool LinkedList<T>::operator==(LinkedList<T>& theList) { if (this == &theList) return true; // same lists, nothing to do if (this->size() != theList.size()) return false; // lists have different number of values bool same(true); // assume the same intpos(0);// start at first node while (same && (pos < size()) // while same and more nodes { if (this->get(pos) != theList.get(pos)) same = false; // nodes differ so lists do, too pos++; // move forward } return same; }

  45. Comparison (==)(more efficient, without function calls) template <typename T> bool LinkedList<T>::operator==(LinkedList<T>& theList) { if (this == &theList) return true; // same lists, nothing to do if (this->numNodes != theList.numNodes) return false; // lists have different number of values bool same(true); // assume the same Node<T> *nodeThis(this->last->next);// start at first node Node<T> *nodeThat(theList.last->next); // start at first node while (same && (nodeThis != last) // while same and more nodes { if (nodeThis->data != nodeThat->data) same = false; // nodes differ so lists do, too nodeThis = nodeThis->next; // move forward nodeThat = nodeThat->next; // move forward } return same; }

More Related