Data Structure Unit-4.1-Doubly-Linked-List
Data Structure Unit-4.1-Doubly-Linked-List
A Doubly Linked List (DLL) contains an extra pointer, typically called the
previous pointer, together with the next pointer and data which are there in the
singly linked list.
struct Node {
int data;
Applications of DLL:
• It is used by web browsers for backward and forward navigation of
web pages
• LRU ( Least Recently Used ) / MRU ( Most Recently Used ) Cache
are constructed using Doubly Linked Lists.
• Used by various applications to maintain undo and redo
functionalities.
• In Operating Systems, a doubly linked list is maintained by thread
scheduler to keep track of processes that are being executed at that
time.
Insertion in DLL:
A node can be added in four ways:
• At the front of the DLL
• After a given node.
• At the end of the DLL
• Before a given node.
Below is the implementation of the 5 steps to insert a node at the front of the
linked list:
/* Given a reference (pointer to pointer) to the head of a
list and an int, inserts a new node on the front of the
list. */
void push(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node
= (struct Node*)malloc(sizeof(struct Node));
/* 2. put in the data */
new_node->data = new_data;
Below is the implementation of the 7 steps to insert a node after a given node in
the linked list:
/* Given a node as prev_node, insert a new node after the
* given node */
void insertAfter(struct Node* prev_node, int new_data)
{
/*1. check if the given prev_node is NULL */
if (prev_node == NULL) {
printf("the given previous node cannot be NULL");
return;
}
/* 2. allocate new node */
struct Node* new_node
= (struct Node*)malloc(sizeof(struct Node));
Below is the implementation of the 7 steps to insert a node at the end of the
linked list:
/* Given a reference (pointer to pointer) to the head
of a DLL and an int, appends a new node at the end */
void append(struct Node** head_ref, int new_data)
{
/* 1. allocate node */
struct Node* new_node
= (struct Node*)malloc(sizeof(struct Node));
return;
}
4) Add a node before a given node:
Follow the below steps to solve the problem:
Let the pointer to this given node be next_node and the data of the new node be
added as new_data.
• Check if the next_node is NULL or not. If it’s NULL, return from the
function because any new node can not be added before a NULL
• Allocate memory for the new node, let it be called new_node
• Set new_node->data = new_data
• Set the previous pointer of this new_node as the previous node of the
next_node, new_node->prev = next_node->prev
• Set the previous pointer of the next_node as the new_node,
next_node->prev = new_node
• Set the next pointer of this new_node as the next_node, new_node-
>next = next_node;
• If the previous node of the new_node is not NULL, then set the next
pointer of this previous node as new_node, new_node->prev->next =
new_node
• Else, if the prev of new_node is NULL, it will be the new head node.
So, make (*head_ref) = new_node.
return;
}
// Driver code
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
getchar();
return 0;
}
Output
Created DLL is:
Traversal in forward direction
1 7 8 6 4
Traversal in reverse direction
4 6 8 7 1
// Connect nodes
one.next = two;
two.next = three;
three.next = one;
Explanation: In the above program one, two, and three are the node with
values 3, 5, and 9 respectively which are connected in a circular manner as:
• For Node One: The Next pointer stores the address of Node two.
• For Node Two: The Next stores the address of Node three
• For Node Three: The Next points to node one.
return last;
}
2) Insertion at the end of the list: To insert a node at the end of the list, follow
these steps:
• Create a node, say T.
• Make T -> next = last -> next;
• last -> next = T.
• last = T.
Before insertion,
Circular linked list before insertion of node at the end
After insertion,
return last;
}
3) Insertion in between the nodes: To insert a node in between the two nodes,
follow these steps:
• Create a node, say T.
• Search for the node after which T needs to be inserted, say that node is
P.
• Make T -> next = P -> next;
• P -> next = T.
Suppose 12 needs to be inserted after the node has the value 10,
return last;
}
p = p -> next;
} while (p != last -> next);
cout << item << " not present in the list." << endl;
return last;
}
2. Deletion in a circular linked list:
1) Delete the node only if it is the only node in the circular linked list:
• Free the node’s memory
• The last value should be NULL A node always points to another node,
so NULL assignment is not necessary.
Any node can be set as the starting point.
Nodes are traversed quickly from the first to the last.
2) Deletion of the last node:
• Locate the node before the last node (let it be temp)
• Keep the address of the node next to the last node in temp
• Delete the last memory
• Put temp at the end
3) Delete any node from the circular linked list: We will be given a node and
our task is to delete that node from the circular linked list.
Algorithm:
Case 1: List is empty.
• If the list is empty we will simply return.
Case 2:List is not empty
• If the list is not empty then we define two pointers curr and prev and
initialize the pointer curr with the head node.
• Traverse the list using curr to find the node to be deleted and before
moving to curr to the next node, every time set prev = curr.
• If the node is found, check if it is the only node in the list. If yes, set
head = NULL and free(curr).
• If the list has more than one node, check if it is the first node of the
list. Condition to check this( curr == head). If yes, then move prev
until it reaches the last node. After prev reaches the last node, set head
= head -> next and prev -> next = head. Delete curr.
• If curr is not the first node, we check if it is the last node in the list.
Condition to check this is (curr -> next == head).
• If curr is the last node. Set prev -> next = head and delete the node
curr by free(curr).
• If the node to be deleted is neither the first node nor the last node, then
set prev -> next = curr -> next and delete curr.
• If the node is not present in the list return head and don’t do anything.
Below is the implementation for the above approach:
// C++ program to delete a given key from
// linked list.
#include <bits/stdc++.h>
using namespace std;
*head_ref = ptr1;
}
// If head is to be deleted
if ((*head)->data == key) {
// Driver code
int main()
{
// Initialize lists as empty
Node* head = NULL;
deleteNode(&head, 7);
return 0;
}
Output
List Before Deletion: 10 8 7 5 2
List After Deletion: 10 8 5 2