Download presentation
Presentation is loading. Please wait.
Published bySusanto Sasmita Modified over 6 years ago
1
A Doubly Linked List There’s the need to access a list in reverse order prev next data dnode header 1
2
Doubly Linked List Implementation
template <typename T> 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<T> *prev; // previous node in the list dnode<T> *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); }; 2
3
Default and Copy Constructors
Constructor creates an empty list by assigning this to both left and right. template <typename T> dnode<T>::dnode() { next = this; // the next node is the current node prev = this; // the previous node is the current node } dnode<T>::dnode(const T& value): nodeValue(value) 3
4
Node Insertion current node prev next prev prev next prevNode newNode
dnode<T> *newNode, *prevNode; // allocate a new node and assign prevNode to reference the predecessor of curr newNode = new dnode<T>(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; 4
5
The insert() Function template <typename T>
dnode<T> *insert(dnode<T> *curr, const T& item) { // declare pointer variables for the new node and the previous node dnode<T> *newNode, *prevNode; // allocate new dnode with item as initial value newNode = new dnode<T>(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; } 5
6
Node Deletion – Self Removal
curr prevNode succNode prev next next prev prev next dnode<T> *prevNode = curr->prev, *succNode = curr->next; prevNode -> next = succNode; succNode -> prev = prevNode; delete curr; 6
7
The erase() Function template <typename T>
void erase(dnode<T> *curr) { // return if the list is empty if (curr->next == curr) return; // declare pointers for the predecessor and successor nodes dnode<T> *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; } 7
8
Circular Doubly Linked Lists
header Simplify coding. Avoid tests to determine if the list is empty. Remove the additional code for updating the head pointer. prev header next An empty circular linked list header -> next == header header-> prev == header 8
9
Scanning a Doubly Linked List
template <typename T> void writeDlinkedList(dnode<T>* header, const string& separator = “ “) { // header points at first dnode. p moves through the list dnode<T> *p = header->next; while (p != header) cout << p->nodeValue << separator; p = p->next; } 9
10
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<T> *header; int listSize; dnode<T> *getDNode(const T& item); // allocate a dnode dnode<T> *dinsert(dnode<T> *curr, const T& item); // insert before node curr and // return address of the new node void derase(dnode<T> *curr); // erase node curr from the linked list 10
11
A Constructor template <typename T>
miniList<T>::miniList(int n, const T& value): listSize(n) { int i; // create an empty list header = new dnode<T>; 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); } 11
12
Copy Constructor template <typename T>
miniList<T>::miniList(const miniList<T>& obj): listSize(obj.listSize) { // curr moves through the nodes in obj, and end marks the finish // of a traversal through obj dnode<T> *curr = obj.header->next, *end = obj.header; // create an empty list header = new dnode<T>; 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; } 12
13
Iterator Nested Class template <typename T> class miniList {
class iterator { public: friend class miniList<T>; // 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<T> *nodePtr; // pointer to the current list node // private constructor. converts p to an iterator // by assigning p to nodePtr iterator(dnode<T> *p): nodePtr(p) {} }; template <typename T> class miniList { public: // include the iterator // nested classes #include “d_liter.h” … private: dnode<T> *header; int listSize; dnode<T> *getDNode( const T& item); dnode<T> *dinsert( dnode<T> *curr, const T& item); void derase(dnode<T> *curr); }; 13
14
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 14
15
begin() and insert() Both are member functions of class miniList.
template <typename T> miniList<T>::iterator miniList<T>::begin() { return iterator(header->next); } miniList<T>::iterator miniList<T>::insert(iterator pos, const T& item) dnode<T> *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); 15
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.