0% found this document useful (0 votes)
71 views23 pages

Unit-3 Linked List

The document discusses linked lists as an alternative to arrays for storing data in memory. Linked lists allow for dynamic sizes and easier insertion/deletion compared to arrays. A linked list is a collection of nodes, where each node contains a data element and a pointer to the next node. There are two main types: singly linked lists, where each node points only to the next node, and doubly linked lists, where each node points to both the previous and next nodes. Linked lists are implemented using dynamic memory allocation of nodes rather than static arrays.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
71 views23 pages

Unit-3 Linked List

The document discusses linked lists as an alternative to arrays for storing data in memory. Linked lists allow for dynamic sizes and easier insertion/deletion compared to arrays. A linked list is a collection of nodes, where each node contains a data element and a pointer to the next node. There are two main types: singly linked lists, where each node points only to the next node, and doubly linked lists, where each node points to both the previous and next nodes. Linked lists are implemented using dynamic memory allocation of nodes rather than static arrays.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

Chapter-3 Linked Lists 1

Introduction
We have already studied about arrays. Arrays are used to store similar data in memory.
Arrays are simple to use, understand and elements are easily accessible. But unfortunately
arrays have some serious limitations.

1. Array is a static data structure. It means that you have to define the size of the array when
the program is being written.
2. Insertion and deletion of elements are difficult because there are lots of movement of
elements when an element is inserted or deleted in the mid of an array.

These problems are overcome by linked list. A linked list can grow and shrink in size during
its lifetime. Another advantage of a linked list is that nodes are stored at different memory
locations. In linked list, insertion and deletion is also simpler than arrays.

Introduction to Linked Lists and Doubly Linked Lists


Linked list is a very common data structure often used to similar data in memory. In a linked
list elements are stored anywhere in memory. The order of the elements of a linked list is
maintained by explicit links between them. The linked list is a collection of elements, called
nodes, where a node contains two pieces of information – an element of the list (Data) and a
Link.

Linked List – a collection of element, called as nodes, in which each element contains a
pointer or index to the "next" element, along with the data represented by the element

Figure-3.1 shows a linked list of an ordered sequence of nodes with links being represented
by arrows.

data link data link data link data link

21 38 18 62 NULL

Figure-3.1 Linked List of 4 nodes

A link is a pointer or an address that indicates the location of next node in the linked list. The
link field of last node contains a special value, known as NULL that indicates that this is the
last node of the list. The entire list is accessed from an external pointer, say first, that points
(contains the address of) the first node in the list, as shown in figure 3.2 (a). It is important to
note that first is not a node, rather the address of the first node of the list.

data link data link data link data link

first 21 38 18 62 NULL

(a) Singly Linked List

left data right left data right left data right left data right

first NULL 21 38 18 62 NULL

(b) Doubly Linked List

Figure-3.2 Types of Linked Lists

The linked list, as shown in figure 3.2(a) is known as singly linked list, because traversing is
possible in single direction only. The limitation of such a single linked list is that if we are at a
node number ‘6’ then we cannot reach at node number ‘3’. This limitation is overcome by
doubly linked list.

In a double linked list, each node contains two pointers – one to its predecessor and another
to its successor. Each node of a doubly linked list contains three pieces of information – Data
field, that contains the information of the node, and Right and Left fields that contains
pointers to the successor and predecessor nodes respectively, as shown in figure 3.2(b).
Chapter-3 Linked Lists 2

Doubly Linked List – a special type of linked list in which each element contains two
pointers, one to the previous element and one to the next element, along with the data
represented by the element

Notations Used in Algorithms

Let us study some notations for use in algorithms (but not in ‘C’ programs).

For Singly Linked List – Let ‘P’ is a pointer to a node then

NODE(P) - refers to the node pointed to by ‘P’,


Data(P) - refers to the data (information) field of node ‘P’, and
Link(P) - refers to the node next to node ‘P

For Doubly Linked List – Let ‘P’ is a pointer to a node then

NODE(P) - refers to the node pointed to by ‘P’,


Data(P) - refers to the data (information) field of node ‘P’, and
Left(P) - refers to the predecessor (Left) node of node ‘P
Right(P) - refers to the successor (right) node of node ‘P

3.3 Representation of Linked Lists in Memory


A linked list can be represented in memory in two ways - using arrays and using dynamic
variables (Pointers)

3.3.1 Implementation of Linked Lists Using Array

A linked list is defined as a collection of nodes that can be traversed starting at the first node.
A linked list is a collection of similar nodes; therefore it can be naturally implemented with the
help of an array.

Since array is a static data structure and it requires a contiguous memory locations for its
elements and linked lists are very useful in situations where the program needs to manage
memory very carefully and a contiguous block of memory is not needed. Therefore array
representation of linked list is not a good choice.

To overcome this limitation, we use dynamic nodes, rather than static nodes. A dynamic
node is created when needed and destroyed when it is no longer needed. The main
advantage of using dynamic nodes is that there is no need to mention the predefined limits
on the number of nodes in the list. As long as memory space is available, we can create a
dynamic node any time. Now let us see how a linked list is implemented using dynamic
variables.

3.3.2 Implementation of Linked Lists Using Dynamic Variables (Pointers)

The second way for implementing a linked list in memory is to use a structure (node) which is
called as self-referential structure. Nodes are created dynamically, when needed, using
malloc() function and destroyed using free(), when no longer needed. The link field of the last
node contains sentinel value, define as NULL in C.

Comparison between Linked List and Array

The following table shows the comparison between linked list and arrays.

S.No. Linked List Array


1 Linked list is dynamic in Array is static in nature
nature
2 Linked list elements can be Array elements are always stored
stored anywhere in memory in contiguous memory locations
3 Insertion and deletion of Insertion and deletion of
elements are simple elements are difficult

Let us study the representation and implementation of various types of linked lists using
dynamic variables and how various operations are implemented on them.
Chapter-3 Linked Lists 3

Linear Linked Lists


A linear linked list, also called singly linked list or one-way list, is defined as a collection of
elements, called nodes. Each node has two fields - information field (data field) and address
of next node (link). Such a node can be declared in C using self-referential structure.

Self Referential Structure – a structure whose one member is a pointer that


points to the structure itself

A typical node of a linear linked list is declared as:

struct node
{
int data;
struct node *link;
};

Here the member - struct node *link points to the structure itself and it is represented as:

Node
Data Link

To maintain a linear linked list we use a pointer variable ‘first’, also known as an external
pointer variable. The ‘first’ pointer contains an address of first node in the list. Here the name
‘first’ is just an user-defined identifier. You can also use other names, such as start, or head
etc. if the list is empty then the value of this external pointer variable must contain a NULL
value. Figure-3.3 represents a linear linked list of 4 nodes.

data link data link data link data link


first 21 38 18 62 NULL

Figure 3.3 A simple linked list of 4 nodes

The link field of last contains a NULL value to indicate that this is the last node of the list. Let
us see how this list is created. Since this list has four nodes, therefore firstly we create four
dynamic nodes as:

node1 = (struct node *) malloc (sizeof(struct node));


node2 = (struct node *) malloc (sizeof(struct node));
node3 = (struct node *) malloc (sizeof(struct node));
node4 = (struct node *) malloc (sizeof(struct node));

Here sizeof() is an operator which returns the number of bytes required for a structure type
“struct node”. The node1, node2, node3 and node4 are declared as:

struct node *node1, *node2, *node3, *node4;

node1 ? ?

node2 ? ?

node3 ? ?

node4 ? ?

The data fields of all these four nodes are set as:

node1->data = 21;
node2->data = 38;
Chapter-3 Linked Lists 4

node3->data = 18;
node4->data = 62;

Now we have four dynamic nodes as shown in following figure:

node1 21 ?

node2 38 ?

node3 18 ?

node4 62 ?

Now we create links between these four nodes as:

node1->link = node2;
node2->link = node3;
node3->link = node4;
node4->link = NULL;

We store NULL in the link field of node4 in order to indicate the end of the list. Finally all
these five nodes are represented as shown in Figure-3.4. Now if we store the address of first
node node1 in an external pointer variable ‘first’ we can easily access all four nodes by
walking through one node to next by using the link field of a node.

first

node1 21
1
node2 38
2
node3 18
3
node4 62
4 NULL

Figure-3.4 Representation of 4 linked nodes

3.4.1 Basic Operations on Linear Linked Lists

Generally we perform following operations on linear linked lists:

 Traverse() – Traversing a linear linked list


 Insertion() – Inserting an element into a linear linked list
 Deletion () – Deleting an element from a linear linked lists

However some other operations are also possible on lists, such as searching, reversing,
concatenating, disposing, etc. In all these operations, we will pass an address of external
pointer ‘first’ to allow it change during the initialization of a linked list.

Initially ‘first’ is assign to NULL indicating an empty list, as follows:

struct node *first = NULL;

Remind that the pointer variable ‘first’ contains either a NULL value (if the list is empty) or
the address of first node of the linked list.
Chapter-3 Linked Lists 5

3.4.1.1 Traversing a Linear Linked List

When we want to traverse a linear linked list we access each node of it and make use of
pointer field of each node while moving from one node to next. Firstly we will check whether
the list is empty or not. If the list is empty then it just displays an error message and the
control is returned back. If the list is not empty then we start accessing of nodes from first
node.

Algorithm : Traverse

Traverse(First)

Perform the following step if First is not NULL


1. Set Temp = First
2. Repeat through Step-4 while Temp <> NULL
3. Process the data of Temp node – Data(Temp)
4. Update the link of Temp node – Temp = Link(Temp)
5. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : Traverse

Traverse(struct node *first)


{
struct node *temp;
temp = first;
while (first != NULL)
{
printf("%d\n",first->data);
first = first->link;
}
}

3.4.1.2 Searching a Linear Linked List

If we are given a linked list and we want to search an item in that list then we will move from
one node to next until the node is searched or the entire list is searched. Firstly we will check
whether the list is empty or not. If the list is empty then it just displays an error message and
the control is returned back. If the list is not empty then we start searching from first node.

Algorithm : Search

Search(First, Item)

Perform the following step if First is not NULL


1. Set Current = First
2. Repeat through Step-4 while Current <> NULL
3. Compare Item with Data(Current)
If Data(Current) = Item then Display –“Item is found” and go to Step-6;
Otherwise go to Step-5
4. Update the value of Current – Current = Link(Current)
5. Display –“Item is not found in the list”
6. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : Search

Search(int item)
{
struct node *current;
current = first;
while (current != NULL)
{
If (current->data == item)
{
printf("%d\n is found in the list", current->data);
Chapter-3 Linked Lists 6

return;
}
else
current = current->link;
}
printf("%d\n is not found in the list", current->data);
}

3.4.1.3 Insertion into a Linear Linked List

Insertion in a linked list is possible in three ways:

1. Insertion at first position


2. Insertion at last position
3. Insertion at any position

Insertion at first position - When we insert a new node as a first node then firstly we
create a new node ‘Temp’ and then set the data field and assign the value of the ‘first’ pointer
variable to the link field of ‘temp’ node as:

Data(Temp) = 55
Link(Temp) = First

and finally we update the value of external pointer variable ‘First’ as:

First = Temp
.
Figure-3.5 illustrates a linear linked list before and after inserting a new node.

First 21 38 18 62 NULL

(a) Before Insertion of a node

First 21 38 18 62 NULL

55

Temp

(b) After Insertion of a node

Figure-3.5 Insertion of node as a first node

Algorithm : InsertionFirst

InsertionFirst (Item)

1. Create a new node – Node(Temp)


2. Set Data field of Temp node – Data(temp) = Item
3. Set Link field of Temp node – Link(Temp) = First
4. Update the value of ‘First’ – First = Temp
5. Exit
Chapter-3 Linked Lists 7

Here is the ‘C’ implementation of this algorithm.

Implementation : InsertionFirst

InsertionFirst(int item)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data=item;
temp->link = first;
first=temp;
}

Insertion at last position - When insert a new node at last position we will create a new
dynamic node first and update the external pointer variable, first, if the list is empty;
otherwise we store the address of this newly created node in the link field of last node.
Figure-3.6 illustrates a linear linked list before and after inserting a new node as last node.

First 21 38 18 62 NULL

(a) Before Insertion of a node

First 21 38 18 62

55 NULL

Temp

(b) After Insertion of a node

Figure-3.6 Insertion of node as a last node

Algorithm : InsertionLast

InsertionLast (Item)

1. Create a new node – Node(Temp)


2. Set Data field of Temp node – Data(temp) = Item
3. Set Link field of Temp node – Link(Temp) = NULL
4. If First = NULL then Update the value of ‘First’ – First = Temp and
goto Step-9
5. Set Current = First
6. Repeat through Step-7 While Link(Current) <> NULL
7. Update the value of Current – Current = Link(Current)
8. Update the value of Link(Current) – Link(Current) = Temp
9. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : InsertionLast

InsertionLast (int item)


{
struct node *temp, *current;
temp = (struct node *)malloc(sizeof(struct node));
temp->data=item;
temp->link=NULL;
if (first==NULL)
first = temp;
else
Chapter-3 Linked Lists 8

{
current = first;
while (current->link != NULL)
current = current->link;
current->link = temp;
}
}

Insertion at any position - When we insert a new node at any specific position we take two
pointer variables – ‘current’ and ‘previous’. The current pointer holds the address of current
node and previous pointer holds the address of previous node of current node. Now we
move from one node to next until we come at proper position. After this we insert the new
node between previous node and current node. However if we do not get proper position and
entire list gets exhausted then this new node is inserted as last node.

Figure-3.7 illustrates a linear linked list before and after inserting a new node at 4 th position.

First 21 38 18 62 NULL

(a) Before Insertion of a node


Current

First 21 38 18 62 NULL

Previous
55

Temp

(b) Before Insertion of a node

Figure-3.7 Insertion of node at 3rd Position

Algorithm : InsertionAny

InsertionLast (Item, Pos)

1. Create a new node – Node(Temp)


2. If First = NULL or Pos = 1 then Insert this new node as a first node
and go to Step-10
3. Set Previous = First
4. Set Current = Link(First)
5. Initialize I = 1
6. Repeat through Step-9 While Current <> NULL
7. If I + 1 = Pos then goto Step-10;
Otherwise go to Step-8
8. Update Previous and Current –
Previous = Current
Current = Link(Current)
9. Increment I – I + 1
10. Set Data field of Temp node – Data(Temp) = Item
11. Set Link field of Temp node – Link(Temp) = Current
12. Update the value of Link(Previous) – Link(Previous) = Temp
13. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : InsertionAny

InsertionAny(int item, int pos)


{
struct node *current, *previous, *temp;
int i;
Chapter-3 Linked Lists 9

temp = (struct node *)malloc(sizeof(struct node));

if ((first == NULL) || (pos==1))


{
temp->data = item;
temp->link = first;
first = temp;
return;
}
current = first->link;
previous = first;
i=1
while (current != NULL)
{
if ( (i+1) == pos )
break;
else
{
previous = current;
current = current->link;
i = i + 1;
}
}
temp->data = item;
temp->link = current;
previous->link = temp;
}

3.4.1.4 Deletion from a Linear Linked List

Deletion from a linked list may be possible in three ways:

1. Deletion at first position


2. Deletion at last position
3. Deletion at any position

Deleting at First Position – When we delete first node, if the list is not empty. Figure-3.8
illustrates a linear linked list of deleting first node.

First 21 38 18 62 NULL

(a) Before deletion of first node

Current

First 21 38 18 62 NULL

(b) After deletion of first node

Figure-3.8 Deletion of first node

Initially we assign the value of First to Current as:

Current = First
Now the Current points to first node of the list. So process the data field of current node and
update the value of First as:

First = Link(First)

And finally we free the space occupied by the Current node.


Chapter-3 Linked Lists 10

Algorithm : DeletionFirst

DeletionFirst ( )

1. Set Current = First


2. Process Data field of Current node - Data(Current)
3. Update the value of First – First = Link(First)
4. Free the memory occupied by Current node
5. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : DeletionFirst

DeletionFirst( )
{
struct node *current;
if (first == NULL)
printf("\nList is empty. ");
else
{
current = first;
printf(“\nDeleted item = %d”, current->data);
first = first->link;
free (current);
}
}

Deleting of Last Node - When we delete last node, if the list is not empty. Figure-3.8
illustrates a linear linked list before and after deleting first node.

First 21 38 18 62 NULL

(a) Before deletion of last node

Previous Current

First 21 38 18 62 NULL

NULL

(b) After deletion of last node

Figure-3.8 Deletion of last node

Initially we assign the value of First to Current as and NULL to Previous:

Current = First
Previous = NULL

Now we move both Current and Previous till the end of list is reached. Once the Current
point to last node and Previous points to Current node as update the value of Previous as:

Link(Previous) = Link(Current)

And finally we free the space occupied by the Current node.


Chapter-3 Linked Lists 11

Algorithm : DeletionLast

DeletionLast ( )

1. Set Current and Previous as:


Current = First
Previous = NULL
2. Update the value of First if Link(First) = NULL as:
First = Link(First) and go to Step-8
3. Repeat through Step-4 while Link(Current) <> NULL
4. Update the value of Previous and Current
Previous = Current
Current = Link(Current)
5. Update the Link of Previous – Link(Previous) = Link(Current)
6. Process the Data field of Current node – Data(Current)
7. Free the memory occupied by Current node
8. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : DeletionLast

DeletionLast ()
{
struct node *current, *previous;
if (first == NULL)
printf("\nList is empty.");
else
{
current = first;
previous=NULL;
if (first->link == NULL ) /* If there is only one node in the list */
first = first->link;
else
{
while (current->link != NULL) /* Move to last node */
{
previous = current;
current = current->link;
}
previous->link = current->link;
}
printf(“\nDeleted item = %d”, current->data);
free(current);
}

Deletion at any position - When we delete any node specific node, we will first move to
that node and then delete that node. For this we will come at that specific position using two
pointer variable Current and Previous. The Previous pointer will always points to the node
predecessor to Current node. Figure-3.9 illustrates a linear linked list of deletion of 3rd node.

First 21 38 18 62 NULL

(a) Before deletion of third node

Previous Current

First 21 38 18 62 NULL

(b) After deletion of third node

Figure-3.9 Deletion of 3rd node


Chapter-3 Linked Lists 12

If the node is other than the first node of the linked list then we assign the link part of the
deleted node (Current) to the link part of the Previous node as:

Link(Previous) = Link(Current)

And finally we remove the Current node.

Algorithm : DeletionAny

DeletionAny (Pos)

1. If Pos = 1 then delete the First node and goto Step-8


2. Set Current and Previous as:
Current = Link(First)
Previous = First
3. Initialize I = 2
4. Repeat through Step-6 while Current <> NULL
5. If I = Pos then
(i) Update the Link of Previous as:
Link(Previous) = Link(Current)
(ii) Process the Data field of Current node – Data(Current)
(iii) Free the memory occupied by Current node
Otherwise update the Current and Previous as:
(i) Previous = Current and
(ii) Current = Link(Current)
6. Increment the value of I – I = I + 1
7. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : DeletionAny

DeletionAny(int pos)
{
struct node *current, *previous;
int item, i;
if (first == NULL)
printf("\nList is empty. ");
else
{
if (pos == 1) /* If the node to be deleted is the first node */
{
current = first;
first = first->link;
printf("\nDeleted item = %d", current->data);
free(current);
}
else
{
current = first->link;
previous = first;
i = 2;
while (current != NULL) /* Move to the specific position */
{
if ( i == pos)
{
previous->link = current->link;
printf(“\nDeleted item = %d”, current->data);
free(current);
break;
}
else
{
previous = current;
current = current->link;
}
i++;
Chapter-3 Linked Lists 13

}
}

}
}

3.4.1.5 Disposing a Linear Linked List - Sometimes we need to free all the nodes in a
linear linked list in order to free the memory occupied by node.

Here is the ‘C’ implementation of this algorithm:

Dispose( )
{
struct node *current;
current = first;
while (first != NULL)
{
free = first->link;
free(current);
}
}

Applications of Linked List:


1) Dynamic Memory Allocation: As we know, we can dynamically allocate
memory in a linked list, so it can be very helpful when we don’t know the
number of elements we are going to use.
2) Implementing advanced data structures: We can implement data
structures like stacks and queues with the help of a linked list.
3) Manipulating polynomials: We can do polynomials manipulation with
the help of a linked list by storing the constants in the nodes of the linked
list. The linked list can be used to represent a polynomial of any degree.
Simply the information field is changed according to the number of
variables used in the polynomial. If a single variable is used in the
polynomial the information field of the node contains two parts: one for
coefficient of variable and the other for degree of variable. Let us consider
an example to represent a polynomial using linked list as follows:
Polynomial: 3x3-4x2+2x-9
Linked List:

In the above linked list, the external pointer ‘ROOT’ point to the first node
of the linked list. The first node of the linked list contains the information
about the variable with the highest degree. The first node points to the next
node with next lowest degree of the variable.

4) Arithmetic operations on long integers: As integers have a limit, we


cannot perform arithmetic operations on long integers. But, if we use a
linked list to represent the long integers, we can easily perform the
operations.
5) Graph Adjacency list Representation: Linked List helps in storing the
adjacent vertices of a graph in adjacency list representation. An array of
lists is used. The size of the array is equal to the number of vertices. Let the
Chapter-3 Linked Lists 14

array be an array[]. An entry array[i] represents the list of vertices adjacent to


the ith vertex. This representation can also be used to represent a weighted
graph. The weights of edges can be represented as lists of pairs. Following is
the adjacency list representation of the above graph.

6) Representation of Sparse Matrix: In linked list, each node has four fields.
These four fields are defined as:
 Row: Index of row, where non-zero element is located
 Column: Index of column, where non-zero element is located
 Value: Value of the non zero element located at index – (row,column)
 Next node: Address of the next node

7) Implementing Hash Tables

Hash Tables give a subset of the dynamic set operations. Generally, a


collection of keys are mapped with some values on the basis of specific
relations. Nevertheless, situations can arise when various keys map to the
exact position provided by the Hash function, causing a collision. This situation
can be solved by Hash Table Chaining. The chaining approach solves
collisions by moving ahead and putting all the keys that map to a slot in that
Chapter-3 Linked Lists 15

slot but depicting them as a linked list. Hash Table chaining in Java is
achievable with both, Doubly Linked List and Singly Linked List.

3.5 Circular Linked Lists


A linked list in which the link field of last node points to the first node of the list is called as a
circularly linked list or a circular list and is illustrated as in Figure-3.10.

first 21 38 18 62 last

Figure 3.10 – Circular Linked List of 4 nodes

Note that a circular linked list does not have a natural ‘first’ and ‘last’ node. We must,
therefore, establish a first and last node by convention. That’s why for the sake of simplicity
we will assume two external pointer variable ‘first’ and ‘last’. The ‘first’ and ‘last’ external
pointer variables will contain the address of first and last nodes respectively.

Circular Linked List – a special type of linked list in which the last element's pointer
points back to the first element, along with the data represented by the element

The structure of a circular linked list of a node is same as that of a linear linked list. The
structure of a node is as:

struct node
{
int data;
struct node *link;
};

And two external pointer variable ‘first’ and ‘last’ is declared as:

struct node *first, *last;

Initially both these external poiner variables are declared as:

first = NULL;
last = NULL;

3.6 Doubly Linked Lists


In both linked lists, linear and circular linked lists, if there are 100 nodes and we are at node
number 52 and we want to move at 48 node then there is no way to arrive at node 48 from
node 52. It is so because traversing is possible in one direction only. To overcome this
limitation, we use doubly linked lists in which each node contains two links – left and right.
The left link contains the information about predecessor node and right link about successor
node..

Doubly Linked List – a linked list in which each node has three fields – data
(information of the node), left (location of predecessor node) and right (location of
successor node).
Thus in a doubly linked list each node contains not only the address of next node but also the
address of previous node, as shown in Figure-3.14

first NULL 21 38 18 62 NULL

Figure-3.14 Doubly Linked List of 4 nodes


Chapter-3 Linked Lists 16

The type declaration for such a node containing an integer is as:

struct dnode
{
struct dnode *left;
int data;
struct dnode *right;
};

and it is represented as:

dnode
left data right

This declaration is for dynamic implementation of doubly linked list.

Like singly linked list, we maintain an external pointer ‘first’ that contains the address of first
node, if the list is empty; otherwise it contains a NULL value.

struct dnode *first = NULL;

Initially NULL is assigned to first to indicate that the list is empty. Generally we perform
following operations on doubly linked lists:

 Insertion ( ) – Inserting an element into a doubly linked list


 Deletion ( ) – Deleting an element from a doubly linked lists
 Traverse ( ) – Traversing a doubly linked list

3.6.1 Traversing a Doubly Linked List

We can traverse a doubly linked list in either direction or in both directions. It means that we
can traverse the list from left to right or right to left. That’s why we have stored NULL in the
left link of first node and right link of last node. Here is the ‘C’ implementation of this function.

Traverse ( )
{
if (first == NULL)
printf("\nList is empty.\n");
else
{
while (first != NULL)
{
printf("%d", first ->data);
first = first ->right;
}
}
}

3.6.2 Inserting an Element into a Doubly Linked List

Like singly linked list, insertion into a doubly linked list is possible at three different positions
– first position, last position or at any specific position. Let us see these insertions one by
one.

Inserting as a First Node - It is very simple to insert a new node at the beginning of the
doubly linked list, that is left of the leftmost node in the list. We will also consider the situation
when the list is empty.

Figure-3.15 illustrates a doubly linked list before and after inserting a new node at first
position.

first NULL 38 18 62 NULL


Chapter-3 Linked Lists 17

(a) before insertion of first node

first 38 18 62 NULL

NULL 21
Temp

(b) After insertion of first node

Figure-3.15 Insertion of node at first position

Algorithm : InsertionDFirst

InsertionDFirst (Item)

1. Create a new node – Node(Temp)


2. Set Data field of Temp node – Data(temp) = Item
3. Set Left Link field of Temp node – Left(Temp) = NULL
4. If First = NULL then Set Right(Temp) = NULL;
Otherwise Set Right(Temp) = First and
Left(First) = Temp
5. Update the value of First – First = Temp
6. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : InsertionDFirst

InsertDFirst(int item)
{
struct dnode *temp;

temp = (struct dnode *)malloc(sizeof(struct dnode));


temp->data = item;
temp->left = NULL;

if (first == NULL)
temp->right = NULL;
else
{
temp->right = first;
first->left = temp;
}
first = temp;
}

Inserting as a Last Node - When we insert a node at the last of a doubly linked list we
traverse the entire list until the last node is reached. And once we reach at last node we can
easily delete this one. We will also consider the situation when the list is empty. Figure-3.16
illustrates a doubly linked list before and after inserting a new node at last position.

first NULL 38 18 62 NULL

(a) Before insertion of Last node

first NULL 38 18 62

21 NULL
Chapter-3 Linked Lists 18

Temp

(b) After insertion of last node

Figure-3.16 Insertion of node at last position

Algorithm : InsertionDLast

InsertionDLast (Item)

1. Create a new node – Node(Temp)


2. Set Data field of Temp node – Data(temp) = Item
3. Set Right Link field of Temp node – Right(Temp) = NULL
4. If First = NULL then go to Step-5;
Otherwise go to Step-7
5. Set Left(Temp) = NULL
6. Update the value of First – First = Temp and go to Step-10
7. Initialize Current = First
8. Repeat through Step-9 while Right(Current) <> NULL
9. Update Current – Current = Right(Current)
10. Set Left link of Temp node – Left(Temp) = Current
11. Set Right link of Current node – Right(Current) = Temp
12. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : InsertinDLast

InsertDLast(int item)
{
struct dnode *temp;

temp = (struct dnode *)malloc(sizeof(struct dnode));


temp->data = item;
temp->right = NULL;
if (first == NULL)
{
temp->left = NULL;
first = temp;
}
else
{
current = first;
while (current ->right != NULL)
current = current->right;
temp->left = current;
current->right = temp;
}
}

Inserting a Node at Any Specific Location - When we insert a node at any position in
the doubly linked list we need to specify the position of the inserted node. If the position of
item is within the limitation then it is inserted at that specific position; otherwise this node is
inserted at the end of the doubly linked list.

Figure-3.17 illustrates a doubly linked list before and after inserting a new node at 3rd
position.

first NULL 38 18 62 NULL

(a) Before insertion of node at 3rd position

first NULL 38 18 62 NULL


Chapter-3 Linked Lists 19

29

Temp

(b) After insertion of node at 3rd position

Figure-3.17 Insertion of node at 3rd position

Algorithm : InsertionDAny

InsertionDAny (Item, Pos)

1. Create a new node – Node(Temp)


2. Set Data field of Temp node – Data(temp) = Item
3. If Pos = 1 then go to Step-4;
Otherwise go to Step-8
4. If First <> NULL then Set Left(First) = Temp
5. Set Right of Temp – Right(Temp) = First
6. Set Left of Temp – Left(Temp) = NULL
7. Update the value of First – First = Temp and go to Step-16
8. Initialize Current = First and I = 2
9. Repeat through Step-11 while ((i<pos) and Right(current) <> NULL)
10. Increment I – I = I +1
11. Update Current – Current = Right(Current)
12. Set Left link of Temp node – Left(Temp) = Current
13. Set Right link of Temp node – Right(Temp) = Right(Current)
14. If Right(Current) <> NULL then set Left(Right(Current)) = Temp
15. Set Right link of Current node – Right(Current) = Temp
16. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : InsertionDAny

InsertionDAny(int item, int pos)


{
struct dnode *temp, *current;
int i;

temp = (struct dnode *)malloc(sizeof(struct dnode));


temp->data = item;
if (pos==1)
{
if (first != NULL)
first->left = temp;
temp->right = first;
temp->left = NULL;
first = temp;
}
else
{
i=2;
current = first;
while ((i<pos) && (current->right != NULL))
{
i++;
current = current->right;
}
temp->left = current;
temp->right = current->right;

if (current->right != NULL)
temp->right->left = temp;
current->right = temp;
}
Chapter-3 Linked Lists 20

3.6.3 Deleting an Element from Doubly Linked List

Like insertion, deletion of an element from a doubly linked list is possible and classified into
three different categories - deleting first node, deleting last node and deleting any node. Let
us see these deletions one by one.

Deletion of First Node - When we delete a node from a doubly linked list we will first
check whether the list is empty or not. If the list is empty then it will simple report an error
message and the control is returned back; otherwise the first node of the list is deleted.

Figure-3.18 illustrates a doubly linked list before and after deletion of first node.

first NULL 21 38 18 62 NULL

(a) Before deletion of first node

first

NULL 38 18 62 NULL
NULL 21

(b) After deletion of first node

Algorithm : DeleteDFirst

DeleteDFirst ()
Perform the following steps if First <> NULL
1. Set Current = First
2. Update First – First = Right(First)
3. If First <> NULL then set Left(First) = NULL
4. Process the Data of Current node – Data(Current)
5. Free the memory occupied by Current node
6. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : DeleteDFirst

DeleteDFirst()
{
struct donode *current;

if (first == NULL)
printf("\nList is empty.");
else
{
current = first;
first = first->right;
if (first != NULL)
first->left = NULL;
printf(“\nDeleted item = %d”, current->data);
free(current);
}
}

Deletion of Last Node

When we delete the last node from a doubly linked list we will first check whether the list is
empty or not. If the list is empty then it will simple report an error message and the control is
returned back; otherwise the last node of the list is deleted. Unlike singly linked list, we need
Chapter-3 Linked Lists 21

not to maintain a previous pointer in the doubly linked list, because it is the current node who
contains the address of its previous node.

Figure-3.19 illustrates a doubly linked list before and after deletion of last node.

first NULL 21 38 18 62 NULL

(a) Before deletion of last node

first NULL 21 38 18 NULL

62 NULL

Current

(b) After deletion of last node

Algorithm : DeleteDLast

DeleteDLast ()
Perform the following steps if First <> NULL
1. Set Current = First
2. Repeat through Step-3 while Right(Current) <> NULL
3. Update Current – Current = Right(Current)
4. If Left(Current) <> NULL then set Right(Left(Current )) = Right(Current)
Otherwise Set First = NULL
5. Process the Data of Current node – Data(Current)
6. Free the memory occupied by Current node
7. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : DeleteDLast

DeleteDLast()
{
struct dnode *current;

if (first == NULL)
printf("\nList is empty.");
else
{
current = first;
while (current->right != NULL)
current = current->right;
if (current->left != NULL)
current->left->right = current->right;
else
first = NULL;

printf(“\nDeleted item = %d”, current->data);


free(current);
}
}

Deletion of Any Node

When we delete any node from a doubly linked list we will first check whether the list is
empty or not. If the list is empty then it will simple report an error message and the control is
returned back; otherwise position of the node, to be deleted, is to be find out using a loop.
However if the loop completes and the item is not found then it will simple display an error
message that – “Such an item does not exist.”
Chapter-3 Linked Lists 22

Figure-3.20 illustrates a doubly linked list before and after deletion of node number 3.

first NULL 21 38 18 62 NULL

(a) Before Deletion of 3rd node

first NULL 21 38 18 62 NULL

Current

(b) After Deletion of 3rd node

Algorithm : DeleteDAny

DeleteDAny (Pos)
Perform the following steps if First <> NULL
1. Set Current = First
2. Repeat through Step-8 while Current <> NULL
3. If I = Pos then go to Step-4;
Otherwise go to Step-7
4. If Left(Current) = NULL then update the following links:
Left(Right(Current)) = NULL
First = Right(Current)
Else If Right(Current) = NULL then update the following links:
Right(Left(Current)) = Right(Current)
Else update the following links:
Right(Left(Current)) = Right(Current)
Left(Right(Current)) = Left(Current)
5. Process the Data of Current node – Data(Current)
6. Free the memory occupied by Current node and go to Step-10
7. Increment the value of I – I = I + 1
8. Update the value of Current – Current = Right (Current)
9. Display – “Such a node number does not exist.”
10. Exit

Here is the ‘C’ implementation of this algorithm.

Implementation : DeleteDAny

Here is the ‘C’ function which implements this task.

DeleteDAny(int pos)
{
struct dnode *current, *previous;
int i=1;

if (first == NULL)
printf("\nList is empty.");
else
{
current = first;
while (current != NULL)
{
if (i == pos)
{
if (current->left == NULL)
{
current->right->left = NULL;
first = current->right;
}
else if (current->right == NULL)
Chapter-3 Linked Lists 23

current->left->right = current->right;
else
{
current->left->right=current->right;
current->right->left = current->left;
}
printf(“\nDeleted item = %d”, current->data);
free(current);
return;
}
i++;
current = current->right;
}
printf("\nSuch a node number does not exist.");
}
}

3.7 Header Linked Lists


A header linked list is a special type of linked list in which there is always a special first node,
called a header node, at the front of the list which contains some important information of list.
For example, a header node usually contains information such as the total number of nodes
in the list or whether the list is sorted or not.

Header Linked list – a special type of linked list in which the first nodes contains
special information about the linked list, rather than usual information of the node

Generally we have two types of header linked lists:

(i) Grounded Header Linked Lists - A grounded header linked list is one whose last
node contains a NULL value
(ii) Circular Header Linked Lists - A circular leader linked list is one whose last node
points to the header node; rather than containing a NULL value.

Figure-3.21 shows some header linked lists.

first # 38 18 62 NULL

(a) One Way Header Linked List

first last
# 38 18 62

(b) Circular Header Linked List

first # 21 38 18 62 NULL

(c) Two Way Header Linked List

first # 21 38 18 62

(d) Two Way Circular Header Linked List

Figure-3.21 Types of Header Linked Lists

You might also like