Doubly Linked List Doubly Linked Lists Slide 2

  • Slides: 28
Download presentation
Doubly Linked List

Doubly Linked List

Doubly Linked Lists / Slide 2 Motivation * Doubly linked lists are useful for

Doubly Linked Lists / Slide 2 Motivation * Doubly linked lists are useful for playing video and sound files with “rewind” and instant “replay” * They are also useful for other linked data where “require” a “fast forward” of the data as needed

Doubly Linked Lists / Slide 3 * list using an array: Knowledge of list

Doubly Linked Lists / Slide 3 * list using an array: Knowledge of list size n Access is easy (get the ith element) n Insertion/Deletion is harder n * list using ‘singly’ linked lists: Insertion/Deletion is easy n Access is harder n n But, can not ‘go back’!

Doubly Linked Lists / Slide 4 Doubly Linked Lists In a Doubly Linked-List each

Doubly Linked Lists / Slide 4 Doubly Linked Lists In a Doubly Linked-List each item points to both its predecessor and successor prev points to the predecessor n next points to the successor n 10 Head 20 Cur->prev 40 Cur 55 Cur->next 70

Doubly Linked List Definition struct Node{ int data; Node* next; Node* prev; }; typedef

Doubly Linked List Definition struct Node{ int data; Node* next; Node* prev; }; typedef Node* Node. Ptr;

Doubly Linked Lists / Slide 6 Doubly Linked List Operations * insert. Node(Node. Ptr&

Doubly Linked Lists / Slide 6 Doubly Linked List Operations * insert. Node(Node. Ptr& Head, int item) //add new node to ordered doubly linked //list * delete. Node(Node. Ptr& Head, int item) //remove a node from doubly linked list * Search. Node(Node. Ptr Head, int item) * Print(node. Ptr Head, int item)

Doubly Linked Lists / Slide 7 Deleting a Node * Delete a node Cur

Doubly Linked Lists / Slide 7 Deleting a Node * Delete a node Cur (not at front or rear) (Cur->prev)->next = Cur->next; (Cur->next)->prev = Cur->prev; delete Cur; 10 20 40 Head Cur 55 70

Doubly Linked Lists / Slide 8 void delete. Node(Node. Ptr& head, int item) {

Doubly Linked Lists / Slide 8 void delete. Node(Node. Ptr& head, int item) { Node. Ptr cur; cur = search. Node(head, item); if (head==NULL) { … } else if (cur->prev == NULL) { … } else if (cur->next==NULL) { … } else { Empty case At-the-beginning case At-the-end case General case (cur->prev)->next = cur->next; (cur->next)->prev = cur->prev; delete cur; } } A systematic way is to start from all these cases, then try to simply the codes, …

Doubly Linked Lists / Slide 9 Inserting a Node * Insert a node New

Doubly Linked Lists / Slide 9 Inserting a Node * Insert a node New before Cur (not at front or rear) New->next = Cur; New->prev = Cur->prev; Cur->prev = New; (New->prev)->next = New; 10 Head 20 55 40 New Cur 70

Doubly Linked Lists / Slide 10 void insert. Node(Node. Ptr& head, int item) {

Doubly Linked Lists / Slide 10 void insert. Node(Node. Ptr& head, int item) { Node. Ptr cur; cur = search. Node(head, item); if (head==NULL) { … } else if (cur->prev == NULL) { … } else if (cur->next==NULL) { … } else { blablabla … } } Many special cases to consider.

Doubly Linked Lists / Slide 11 Many different linked lists … * singly linked

Doubly Linked Lists / Slide 11 Many different linked lists … * singly linked lists Without ‘dummy’ n With dummy n circular n * doubly linked lists Without ‘dummy’ n With dummy n Using ‘dummy’ is a matter of personal preference! + simplify codes (not that much - Less logically sounds

Doubly Linked Lists / Slide 12 singly linked list Head 10 20 20 40

Doubly Linked Lists / Slide 12 singly linked list Head 10 20 20 40 55 70 (singly) circular linked list 10 20 40 55 70 Rear (regular) doubly linked list 10 20 40 55 70 Head doubly linked list with dummy Dummy 10 Head 20 40 55 70

Doubly Linked Lists with Dummy Head Node Doubly Linked Lists / Slide 13 *

Doubly Linked Lists with Dummy Head Node Doubly Linked Lists / Slide 13 * To simplify insertion and deletion by avoiding special cases of deletion and insertion at front and rear, a dummy head node is added at the head of the list * The last node also points to the dummy head node as its successor

Doubly Linked Lists / Slide 14 Idea of ‘dummy’ object ‘dummy object’ is also

Doubly Linked Lists / Slide 14 Idea of ‘dummy’ object ‘dummy object’ is also called a ‘sentinel’, it allows the simplification of special cases, but confuses the emptyness NULL! l l Instead of pointing to NULL, point to the ‘dummy’!!! Skip over the dummy for the real list Dummy Head Node 10 Head 20 40 55 70

Doubly Linked Lists / Slide 15 Empty list: Dummy Head Node Head->next = head;

Doubly Linked Lists / Slide 15 Empty list: Dummy Head Node Head->next = head; compared with head=NULL;

operations creation Doubly linked with dummy void create. Head(Node. Ptr& head){ head = new

operations creation Doubly linked with dummy void create. Head(Node. Ptr& head){ head = new Node; head->next = head; head->prev = head; } Singly linked Node. Ptr head=NULL; Node. Ptr head; create. Head(head); reference Node. Ptr cur=head; Start from cur=cur->next; cur=head; Empty test cur=head; // dummy head cur=NULL; // or head=NULL;

Print the whole list: void print(Node. Ptr head){ Node. Ptr cur=head->next; while(cur != head){

Print the whole list: void print(Node. Ptr head){ Node. Ptr cur=head->next; while(cur != head){ cout << cur->data << " "; cur = cur->next; } }

Searching a node (returning NULL if not found the element): Node. Ptr search. Node(Node.

Searching a node (returning NULL if not found the element): Node. Ptr search. Node(Node. Ptr head, int item){ Node. Ptr cur = head->next; while ((cur != head) && (item != cur->data)) cur=cur->next; if (cur == head) cur = NULL; // we didn’t find return cur; } End of the list, empty

Doubly Linked Lists / Slide 19 Deleting a Node * Delete a node Cur

Doubly Linked Lists / Slide 19 Deleting a Node * Delete a node Cur at front (Cur->prev)->next = Cur->next; (Cur->next)->prev = Cur->prev; delete Cur; Dummy Head Node 10 Head Cur 20 40 55 70

Doubly Linked Lists / Slide 20 * Delete a node Cur in the middle

Doubly Linked Lists / Slide 20 * Delete a node Cur in the middle (Cur->prev)->next = Cur->next; (Cur->next)->prev = Cur->prev; delete Cur; // same as delete front! Dummy Head Node 10 Head 20 40 Cur 55 70

Doubly Linked Lists / Slide 21 * Delete a node Cur at rear (Cur->prev)->next

Doubly Linked Lists / Slide 21 * Delete a node Cur at rear (Cur->prev)->next = Cur->next; (Cur->next)->prev = Cur->prev; delete Cur; // same as delete front and middle! Dummy Head Node 10 Head 20 40 55 70 Cur

void delete. Node(Node. Ptr head, int item){ Node. Ptr cur; cur = search. Node(head,

void delete. Node(Node. Ptr head, int item){ Node. Ptr cur; cur = search. Node(head, item); if(cur != NULL){ cur->prev->next = cur->next; cur->next->prev = cur->prev; delete cur; } } If we found the element, it does not mean any emptyness!

Doubly Linked Lists / Slide 23 Inserting a Node * Insert a Node New

Doubly Linked Lists / Slide 23 Inserting a Node * Insert a Node New after dummy node and before Cur New->next = Cur; New->prev = Cur->prev; Cur->prev = New; (New->prev)->next = New; Dummy Head Node 20 10 Head New Cur

Doubly Linked Lists / Slide 24 * Insert a Node New at Rear (with

Doubly Linked Lists / Slide 24 * Insert a Node New at Rear (with Cur pointing to dummy head) New->next = Cur; New->prev = Cur->prev; Cur->prev = New; (New->prev)->next = New; Dummy Head Node 10 Cur Head 20 40 55 70 New

Doubly Linked Lists / Slide 25 * Insert Cur a Node New in the

Doubly Linked Lists / Slide 25 * Insert Cur a Node New in the middle and before New->next = Cur; New->prev = Cur->prev; Cur->prev = New; (New->prev)->next = New; Dummy Head Node 10 Head 20 40 New 55 Cur

Doubly Linked Lists / Slide 26 * Insert a Node New to Empty List

Doubly Linked Lists / Slide 26 * Insert a Node New to Empty List (with Cur pointing to dummy head node) New->next = Cur; New->prev = Cur->prev; Cur->prev = New; (New->prev)->next = New; Dummy Head Node 20 Head Cur New

void insert. Node(Node. Ptr head, int item){ Node. Ptr newp, cur; newp = new

void insert. Node(Node. Ptr head, int item){ Node. Ptr newp, cur; newp = new Node; creation newp->data = item; location cur = head->next; while ((cur != head)&&(!(item<=cur->data))) cur = cur->next; insertion newp->next = cur; newp->prev = cur->prev; cur->prev = newp; (newp->prev)->next = newp; } It is similar to, but different from Search. Node! (it returns NULL if no element)

void main(){ Node. Ptr Head, temp; create. Head(Head); insert. Node(Head, 3); Result is insert.

void main(){ Node. Ptr Head, temp; create. Head(Head); insert. Node(Head, 3); Result is insert. Node(Head, 5); 235 insert. Node(Head, 2); 123578 print(Head); 12358 insert. Node(Head, 7); Data is contained in the list insert. Node(Head, 1); insert. Node(Head, 8); print(Head); delete. Node(Head, 7); delete. Node(Head, 0); print(Head); temp = search. Node(Head, 5); if(temp !=NULL) cout<<" Data is contained in the list"<<endl; else cout<<" Data is NOT contained in the list"<<endl; }