Presentation is loading. Please wait.

Presentation is loading. Please wait.

A Doubly Linked List prevnextdata There’s the need to access a list in reverse order header dnode.

Similar presentations


Presentation on theme: "A Doubly Linked List prevnextdata There’s the need to access a list in reverse order header dnode."— Presentation transcript:

1 A Doubly Linked List prevnextdata There’s the need to access a list in reverse order header dnode

2 Doubly Linked List Implementation template class dnode { public: // the members of a dnode object are used for operations within a // doubly linked list; access is simplified by making them public T nodeValue;// data value of the node dnode *prev;// previous node in the list dnode *next;// next node in the list // default constructor. creates object with value T(), the default value // of type T. set the node pointers to point at the node itself dnode(); // constructor with an argument to initialize nodeValue. // set the node pointers to point at the node itself dnode(const T& value): nodeValue(value); };

3 Default and Copy Constructors Constructor creates an empty list by assigning this to both left and right. template dnode ::dnode() { next = this;// the next node is the current node prev = this;// the previous node is the current node } template dnode ::dnode(const T& value): nodeValue(value) { next = this;// the next node is the current node prev = this;// the previous node is the current node }

4 Node Insertion prevnextprev next current node dnode *newNode, *prevNode; // allocate a new node and assign prevNode to reference the predecessor of curr newNode = new dnode (item); prevNode = curr->prev; // update pointer fields in newNode newNode->prev = prevNode; newNode->next = curr; // update curr and its predecessor to point to newNode prevNode->next = newNode; curr->prev = newNode; newNode prevNode

5 The insert() Function template dnode *insert(dnode *curr, const T& item) { // declare pointer variables for the new node and the previous node dnode *newNode, *prevNode; // allocate new dnode with item as initial value newNode = new dnode (item); // assign prevNode the pointer value of node before p prevNode = curr->prev; // update pointer fields in newNode newNode->prev = prevNode; newNode->next = curr; // update curr and prevNode to point at newNode prevNode->next = newNode; curr->prev = newNode; return newNode; }

6 Node Deletion – Self Removal next prev nextprev curr prevNode -> next = succNode; succNode -> prev = prevNode; dnode *prevNode = curr->prev, *succNode = curr->next; delete curr; prevNodesuccNode

7 The erase() Function template void erase(dnode *curr) { // return if the list is empty if (curr->next == curr) return; // declare pointers for the predecessor and successor nodes dnode *prevNode = curr->prev, *succNode = curr->next; // update pointer fields for predecessor and successor prevNode->next = succNode; succNode->prev = prevNode; // deallocate the memory used by the node delete curr; }

8 Circular Doubly Linked Lists header next An empty circular linked list header -> next == header header-> prev == header header Simplify coding. Avoid tests to determine if the list is empty. Remove the additional code for updating the head pointer. prev

9 Scanning a Doubly Linked List template void writeDlinkedList(dnode * header, const string& separator = “ “) { // header points at first dnode. p moves through the list dnode *p = header->next; while (p != header) { cout nodeValue << separator; p = p->next; }

10 Application: The Josephus Problem n customers to compete in a contest for a free world cruise. The customers are placed in a circle by a travel agent. The agent draws a number m (m  n) from a hat. He rotates clockwise about the circle and stop at every m th contestant. This person is then removed from the game. The game continues with every m th person eliminated until only one remains. The survivor is the winner!

11 A Game Example n = 10 1 2 3 4 5 6 7 8 9 10 m = 5 The winner!

12 Solution to the Josephus Problem void josephus(int n, int m) { // declare the circular doubly linked list dList and scan pointer dnode *dList = new dnode, *curr; int i, j; // initialize the list of contestants 1 2 3... n for (i = 1; i <= n; i++) insert(dList, i); // curr moves around the list, starting at person 1 curr = dList->next; // delete all but one person from the list for (i=1; i < n; i++) { // counting current person at curr, visit m persons. // we must advance m-1 times. for (j=1; j <= m-1; j++) { // advance the pointer curr = curr->next;

13 Solution (cont’d) // if curr at the header, move again if (curr == dList) curr = curr->next; } cout nodeValue << endl; // advance curr and erase the node we just left curr = curr->next; erase(curr->prev); // might have deleted the rear of the list, so // curr is now at the header. move again if (curr == dList) curr = curr->next; } cout nodeValue << " wins the cruise" << endl; // delete the one remaining node and the list header delete curr; delete dList; }

14 The Main Program void main() { // numContestants is number of contestants // removeM is the rotation selector randomNumber rnd; int n, m; cout << "Enter the number of contestants: "; cin >> n; // generate a random number between 1 // and numContestants m = 1 + rnd.random(n); cout << "Generated the random number " << m << endl; // solve the Josephus problem and output the cruise winner josephus(n, m); } Enter the number of contestants? 10 Generated the random number 5 Delete person 5 Delete person 10 Delete person 6 Delete person 2 Delete person 9 Delete person 8 Delete person 1 Delete person 4 Delete person 7 Contestant 3 wins the cruise.

15 The miniList Class A variation of the STL list class. A doubly linked list as the underlying structure. Implementation of an iterator. Private members: dnode *header; int listSize; dnode *getDNode(const T& item); // allocate a dnode dnode *dinsert(dnode *curr, const T& item); // insert before node curr and // return address of the new node void derase(dnode *curr); // erase node curr from the linked list

16 A Constructor template miniList ::miniList(int n, const T& value): listSize(n) { int i; // create an empty list header = new dnode ; if (header == NULL) throw memoryAllocationError (“miniList(): memory allocation failure”); // insert n copies of value at the front of the list for (i = 0; i < n; i++) dinsert(header->next, value); }

17 Copy Constructor template miniList ::miniList(const miniList & obj): listSize(obj.listSize) { // curr moves through the nodes in obj, and end marks the finish // of a traversal through obj dnode *curr = obj.header->next, *end = obj.header; // create an empty list header = new dnode ; if (header == NULL) throw memoryAllocationError (“miniList(): memory allocation failure”); // insert the values in the linked list obj.header at the back of the current list while (curr != end) { dinsert(header, curr->nodeValue); // before the header, i.e., back of the list curr = curr -> next; }

18 Iterator Nested Class template class miniList { public: // include the iterator // nested classes #include “d_liter.h” … private: dnode *header; int listSize; dnode *getDNode( const T& item); dnode *dinsert( dnode *curr, const T& item); void derase(dnode *curr); }; class iterator { public: friend class miniList ; // needed by the const_iterator constructor // that converts a const iterator to a const_iterator friend class const_iterator; // constructor iterator() {} bool operator==(const iterator& rhs) const; bool operator!= (const iterator& rhs) const; T& operator* (); // pointer dereference operator iterator& operator++ (); iterator operator++ (int) ; // postfix increment. move forward one node iterator& operator-- (); iterator operator-- (int); private: dnode *nodePtr; // pointer to the current list node // private constructor. converts p to an iterator // by assigning p to nodePtr iterator(dnode *p): nodePtr(p) {} };

19 Implementing Iterator Operations T& operator* () { // if the node's successor is itself, the list is empty if (nodePtr->next == nodePtr) throw referenceError("miniList iterator: reference error"); return nodePtr->nodeValue; } iterator& operator++ () { nodePtr = nodePtr->next; // move to the successor of nodePtr return *this; // return new iterator value } iterator operator++ (int) { // save the current value of the iterator iterator tmp = *this; // move to the successor of nodePtr nodePtr = nodePtr->next; return tmp; // return original iterator value }

20 begin() and insert() Both are member functions of class miniList. template miniList ::iterator miniList ::begin() { return iterator(header->next); } template miniList ::iterator miniList ::insert(iterator pos, const T& item) { dnode *curr = pos.nodePtr, *newNode; // insert item before curr and capture the new node’s address newNode = dinsert(curr, item); // increment the list size listSize++; // constructor converts newNode to an iterator return iterator(newNode); }


Download ppt "A Doubly Linked List prevnextdata There’s the need to access a list in reverse order header dnode."

Similar presentations


Ads by Google