1 / 41

Linked Lists II Doubly Linked Lists

Linked Lists II Doubly Linked Lists. Chapter 3. Objectives. You will be able to: Describe, implement, and use a Doubly Linked List of integers. Some Issues. Issues in current implementation: Inserting and deleting at either end of the list requires special case code.

ananda
Download Presentation

Linked Lists II Doubly 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. Linked Lists IIDoubly Linked Lists Chapter 3

  2. Objectives You will be able to: • Describe, implement, and use a Doubly Linked List of integers.

  3. Some Issues • Issues in current implementation: • Inserting and deleting at either end of the list requires special case code. • Empty list requires special case code. • First node and last node are different from other nodes. • deleteFromTail is inefficient • Requires scanning entire list. • Solution: Doubly linked list with node as list head. (Not in book!)

  4. Some Other Issues • Issues in current implementation: • No way to retrieve a specified node. • No way to insert in order. • No way to traverse the list. • Solution: Add new methods.

  5. Figure 3.9 Doubly Linked List • Each node has a pointer to the next node and a pointer to the previous node. • Section 3.2 in the textbook. • Version in the book still has pointers to the head and tail as members of the list class. • Requires special case code for adding and deleting at the head and the tail.

  6. Doubly Linked List with List Head Node • We can avoid all special case code by using a Node object as a List Head. • Next pointer points to first element of List. • Prev pointer points to last element of List • If List is empty, both point to the List Head.

  7. Doubly Linked List with List Head Node • With a Node as List Head, all nodes in the list are alike. • Each node has a Node as next. • Each node has a Node as prev. • No pointer is ever null. • An empty list is not a special case. • There is still a List Head Node, with next and prev pointers. • The same Insert and Delete code works for all cases!

  8. Download • Download example from last class. • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_01_12_Singly_Linked_List/ • File intSLLst.zip

  9. Download example from last class

  10. Download example from last class

  11. Expand the .zip file Right click the .zip file icon.

  12. Expand the .zip file

  13. Select Destination for Expanded File

  14. Extraction Complete

  15. Downloaded Folder Expanded Drill down.

  16. The Solution Folder Double click the .sln file to open the solution in Visual Studio

  17. Open in Visual Studio • Rebuild solution and test. • Be sure we have a known starting point.

  18. Program in Action Now let's modify the list to be a doubly linked list with Listhead Node.

  19. Add Class intDLList

  20. Add Class intDLList

  21. Add Class intDLList

  22. Defining Class intDLList • Copy intSLLst.h as initial version of intDLList.h. • Update class names and guard. • Add prev pointer to Node class.

  23. intDLList.h #pragma once //************************ intDLList.h *************** // Doubly-linked list class to store integers class IntDLLNode { public: int info; class IntDLLNode *next; class IntDLLNode *prev; IntDLLNode(int el, IntDLLNode *ptr1 = 0, IntDLLNode *ptr2 = 0) { info = el; next = ptr1; prev = ptr2; } };

  24. intDLList.h class IntDLList { public: IntDLList(); ~IntDLList(); int isEmpty() const { return ListHead->next == ListHead; } void addToHead(int); void addToTail(int); int deleteFromHead(); // delete the head and return its info; int deleteFromTail(); // delete the tail and return its info; void deleteNode(int); bool isInList(int) const; void printAll() const; private: IntDLLNode* ListHead; };

  25. main.cpp • Update list class. • Comment out most of body • So that we can compile before adding all methods to IntDLList.cpp

  26. main.cpp #include <iostream> #include "intDLList.h" using namespace std; int main() { IntDLList myList; //myList.addToHead(3); //myList.addToHead(2); //myList.addToHead(1); //myList.addToHead(0); //cout << "Initial List:\n"; //myList.printAll(); //while (!myList.isEmpty()) //{ ... //} cin.get(); // Hold window open. }

  27. Implementing Class intDLList • Start by adding constructor and destructor to intDLList.cpp • Add remaining methods one at a time. • Build after adding each method

  28. Constructor //************************ intDLList.cpp ************* #include <iostream> #include "intDLList.h" using namespace std; IntDLList::IntDLList() { ListHead = new IntDLLNode(0); ListHead->next = ListHead; ListHead->prev = ListHead; } IntDLList::~IntDLList(void) { } Build

  29. addToHead void IntDLList::addToHead(int el) { IntDLLNode *p = new IntDLLNode(el); p->next = ListHead->next; p->prev = ListHead; ListHead->next->prev = p; ListHead->next = p; } Build

  30. addToTail void IntDLList::addToTail(int el) { IntDLLNode *p = new IntDLLNode(el); p->next = ListHead; p->prev = ListHead->prev; ListHead->prev->next = p; ListHead->prev = p; }

  31. deleteFromHead int IntDLList::deleteFromHead() { if (isEmpty()) { throw("Attempt to delete from empty list"); } int el = ListHead->next->info; IntDLLNode *tmp = ListHead->next; ListHead->next->next->prev = ListHead; ListHead->next = ListHead->next->next; delete tmp; return el; }

  32. deleteFromTail int IntDLList::deleteFromTail() { if (isEmpty()) { throw("Attempt to delete from empty list"); } int el = ListHead->prev->info; IntDLLNode *tmp = ListHead->prev; tmp->prev->next = ListHead; ListHead->prev = tmp->prev; delete tmp; return el; }

  33. deleteNode // Delete node with a specified value void IntDLList::deleteNode(int el) { IntDLLNode *p = ListHead->next; while (p != ListHead && p->info != el) { p = p->next; } if (p == ListHead) { return; // It's not there. Claim success! } // p points to node to be deleted. p->prev->next = p->next; p->next->prev = p->prev; delete p; }

  34. isInList bool IntDLList::isInList(int el) const { IntDLLNode *p = ListHead->next; while (p != ListHead && p->info != el) { p = p->next; } return p != ListHead; }

  35. printAll void IntDLList::printAll() const { if (isEmpty()) { cout << "List is empty\n"; return; } IntDLLNode *p = ListHead->next; while (p != ListHead) { cout << p->info << " "; p = p->next; } cout << endl; }

  36. Destructor Add following the constructor: IntDLList::~IntDLList(void) { while (!isEmpty()) { deleteFromTail(); } delete ListHead; }

  37. main.cpp #include <iostream> #include "intDLList.h" using namespace std; int main() { IntDLList myList; myList.addToHead(3); myList.addToHead(2); myList.addToHead(1); myList.addToHead(0); cout << "Initial List:\n"; myList.printAll(); while (!myList.isEmpty()) { cout << "Deleting head node\n"; myList.deleteFromHead(); cout << "Current List:\n"; myList.printAll(); } cin.get(); // Hold window open. }

  38. Program Running

  39. Check Error Handling cout << "\nCalling deleteFromHead for empty list\n"; cout << "This should output an error message\n\n"; try { myList.deleteFromHead(); } catch (const char* err) { cout << err << endl; } cout << "\nTest complete\n";

  40. Program Running

  41. Test Thoroughly • We need to test the class code much more thoroughly. • Call every method. • Set up potential special cases. • Empty List • Exactly one node. • Multiple nodes

More Related