Singly and Doubly Linked list
Singly and Doubly Linked list
Linked List
Dr Deepak Gupta
Assistant Professor, SMIEEE
CSED, MNNIT Allahabad, Prayagraj
Email: deepakg@mnnit.ac.in
Linked List
❑ Advantage:
❑ Dynamic size
❑ Ease of insertion and deletion
❑ Disadvantage:
❑ Random access is not allowed in Linked list.
Representation of Linked List
start = NULL;
❑ The new node that we are adding will be the only node in the list.
Since it is first node, start should point to this node and it is also the
last node so its next should be
tmp->next = NULL;
start = tmp;
❑ Since initially start was NULL, we can write start instead of NULL in
the first statement, so now these two statements can be written as -
tmp->next = start;
start = tmp;
2. Insertion at the beginning of the list
❑ We have to insert node T at the beginning of the list. Suppose the first
node of list is node P, so the new node T should be inserted before it.
start = tmp;
p->next = tmp;
tmp->next = NULL;
❑ So, in this case we should have a pointer p pointing to the last node of the
list. The only information about the linked list that we have is the pointer
start. p = start; Terminating condition is
while(p->next!=NULL) (p->next!=NULL).
p = p->next;
Start
ptr next
1 2 3 4
Start
ptr next
1 2 3 4
Start
prev ptr
1 2 3 4
Start
prev ptr next
1 2 3 4
Start
prev ptr next
1 2 3 4
Start
prev ptr
1 2 3 4
Start
prev ptr next
1 2 3 4
Start
prev ptr next
1 2 3 4
Start
prev ptr
1 2 3 4
1 2 3 4
Start next is NULL
prev ptr
1 2 3 4
1 2 3 4
1 2 3 4
Reversing a Single Linked List:
Struct node *reverse(struct node *start)
{
struct node *prev, *ptr, *next;
prev = NULL;
ptr = start;
while(ptr!=NULL)
{
next = ptr->next;
ptr->next = prev;
prev = ptr;
ptr = next;
}
start = prev;
return start;
}/*end of reverse*/
Doubly Linked List
To overcome the drawback of a singly linked list, we have another data
structure called a doubly linked list or two-way list, in which each node has
two pointers and one information value. One of these pointers points to the
next node and the other points to the previous node.
The structure of a doubly linked list can be declared as:
struct node{
struct node *prev;
int info;
struct node *next;
Contains address
}; of the next node
Contains address of
the previous node
Traversing a doubly linked list
The function of traversal of doubly linked list is similar to singly linked
list.
void display(struct node *start)
{
struct node *p;
if(start==NULL)
{
printf(“List is empty”);
}
p=start;
while(p!=NULL)
{
printf(“%d”, p->info);
p=p->next;
}
printf(“/n”);
}
Insertion in a doubly linked list
We will study all four cases of insertion in a doubly linked list:
1. Insertion at the beginning of the list
2. Insertion in an empty list
3. Insertion at the end of the list
4. Insertion in between the nodes
1. Insertion at the beginning of the list
After Insertion
Before Insertion Start
Start
Node P
1 2 3 4
Node P
Node T
1 2 3 4 6
• Node T has become the first node so its prev should be NULL.
tmp->prev = NULL;
• The next part of the Node T should point to node P, and address of
node P is in strat so we should write:
tmp->next = start;
• Node T is inserted before node P so prev part of node P should now
point to node T.
start->prev = tmp;
• Now Node T has become the first node so start should point to it.
start = tmp;
struct node *addatbeg (struct node *start, int data)
{
struct node *tmp;
tmp = (struct node*)malloc(sizeof(struct node));
tmp -> info = data;
tmp -> prev = NULL;
tmp -> next = start;
start -> prev = tmp;
start = tmp;
return start;
}
2. Insertion in an empty list
• Node T is the first node so its prev part should be NULL, and it is also
the last node so its next part should also be NULL. Node T is the first
node so start should point to it.
tmp->prev = NULL;
tmp->next = NULL;
start = tmp;
struct node *addtoempty (struct node *start, int data)
{
struct node *tmp;
tmp = (struct node*)malloc(sizeof(struct node));
tmp -> info = data;
tmp -> prev = NULL;
tmp -> next = NULL;
start = tmp;
return start;
}
3. Insertion at the end of the list
tmp->prev = p; tmp->prev = p;
tmp->next = q; tmp->next = p->next;
q->prev = tmp; p->next ->prev = tmp;
p->next = tmp; p->next = tmp;
4. Insertion in between the nodes (continue..)
struct node *addafter (struct node *start, int data, int item)
{
struct node *tmp, *p;
tmp = (struct node*)malloc(sizeof(struct node));
tmp -> info = data;
p = start;
while(p != NULL)
{
if(p->info == item)
{
tmp->prev = p;
tmp->next = p->next;
if ( p->next!=NULL)
p->next ->prev = tmp;
p->next = tmp;
return start;
}
p = p -> next;
}
printf(“%d not present in the list\n”, item);
return start;
}
Creation in a doubly linked list
struct node *create_list (struct node *start)
{
int i, n, data;
printf(“Enter the number of nodes: ”);
scanf(“%d”, &n);
start = NULL;
if(n==0)
return start;
printf(“Enter the element to be inserted: ”);
scanf(“%d”, &data);
start = addtoempty(start, data);
for(i=2; i<=n; i++)
{
printf(“Enter the element to be inserted: ”);
scanf(“%d”, &data);
start = addatend(start, data);
}
return start;
}
Deletion from doubly linked list
We will study all four cases of insertion in a doubly linked list:
1. Deletion of the first node
2. Deletion of the only node
3. Deletion in between the nodes
4. Deletion at the end of the list
1. Deletion of the first node
• Now Node P is the first node so its prev part should contain NULL
start->prev = NULL;
2. Deletion of the only node
tmp = start;
start = NULL;
3. Deletion in between the nodes
Suppose we have to delete Node T, and let pointers p, tmp and q point to
Nodes P, T and Q respectively.
• The two statements for deleting Node T can be written as:
p->next = q;
q->prev = p;
• The address of q is in tmp->next so we can replace q by tmp->next.
• The address of p is in tmp->prev so we can replace p by tmp->prev.
tmp->prev->next = tmp->next;
tmp->next->prev = tmp->prev;
4. Deletion at the end of the list
struct node{
int info;
struct node *next;
};
Traversal in a Circular linked list
The function of traversal of a Circular linked list is similar to a singly
linked list.
void display(struct node *last)
{
struct node *p;
if(last==NULL)
{
printf(“List is empty”);
return;
}
p=last->next;
do
{
printf(“%d”, p->info);
p=p->next;
} while(p!=last->next);
printf(“/n”);
}
Insertion in a Circular linked list
1. Insertion at the beginning of the list
• After insertion, T is the last node so the pointer last points to node T
last = tmp;
• Here, T is the first node so last->link points to node T
last->next = last;
• There will be only one node in the list if link of the last node points to
itself. After deletion, the list will become empty so NULL Is assigned to
last.
last = NULL;
• It is similar to a doubly linked list that points to not only the next node
but to the previous node as well. In a doubly circular linked list, the
next of the last node points to the first node and the prev of the first
node points to the last node.
Doubly Circular Linked List
1. Insertion at the beginning of the list
struct node *addatbeg (struct node *start, int data)
{ struct node *tmp, *ptr;
ptr = (struct node*)malloc(sizeof(struct node));
if(ptr==NULL)
printf(“\nOverflow”);
else
ptr -> info = data;
if(start = = NULL) /*list is empty*/
{ start=ptr;
ptr->next = start;
ptr->prev = start;
}
else /*list is not empty*/
{ temp = start;
while(temp->next!=start)
temp=temp->next;
temp -> next = ptr;
ptr -> prev = temp;
start -> prev = ptr;
ptr->next = start;
start = ptr;
}
}
Doubly Circular Linked List
2. Insertion at the end of the list
struct node *addatend (struct node *start, int data)
{ struct node *tmp, *ptr;
ptr = (struct node*)malloc(sizeof(struct node));
if(ptr==NULL)
printf(“\nOverflow”);
else
ptr -> info = data;
if(start = = NULL) /*list is empty*/
{ start=ptr;
ptr->next = start;
ptr->prev = start;
}
else /*list is not empty*/
{ temp = start;
while(temp->next!=start)
temp=temp->next;
temp -> next = ptr;
ptr -> prev = temp;
start -> prev = ptr;
ptr->next = start;
}
}
Doubly Circular Linked List
1. Deletion at the beginning of the list
struct node *delatbeg (struct node *start, int data)
{ struct node *tmp;
if(start==NULL)
printf(“\nUnderflow”);
else if(start->next==start)
{
start = NULL;
free(start);
printf(“Node deleted”);
}
else
{
temp = start;
while(temp->next!=start)
temp=temp->next;
temp -> next = start->next;
start -> next -> prev = temp;
free(start);
start = temp->next;
}
}
Doubly Circular Linked List
2. Deletion at the end of the list
struct node *delatbeg (struct node *start, int data)
{ struct node *ptr;
if(start==NULL)
printf(“\nUnderflow”);
else if(start->next==start)
{
start = NULL;
free(start);
printf(“Node deleted”);
}
else
{
ptr = start;
if(ptr->next!=start)
ptr = ptr->next;
ptr ->prev-> next = start;
start ->prev = ptr->prev;
free(ptr);
printf(“node deleted”);
}
}