Linked List
Linked List
Any variable, which is declared and initialized, has three things associated
with it
All the three things are equally important. The name of a variable, which
represents the memory location, is used to output the value stored in the variable and
the address of the variable is used to input a value to the variable.
a Name
5 Value
1000 Address
We have always used variables to store values, however a variable can also be
used to store the address of another variable such variables are termed as pointer
variables. Thus a pointer is a variable, which can contain the address of another variable.
The program below highlights this fact very clearly.
Linked List
2
Program 4.1: To show the creation of a pointer variable.
#include <stdio.h>
void main( )
{
int a = 9;
int *b;
b = &a;
OUTPUT
Address of the variable a = 1736
Value of the variable a = 9
Address present in the variable b = 1736
1. The address of a variable is accessed with the help of the “&” operator.
2. Using the name of the variable we can accesses the value of a variable.
3. A pointer variable is created by including the operator “*” when the variable is
declared.
4. A pointer variable can hold only the address of another variable and not the
value of another variable.
We have already seen the use of a pointer and its usage, in this section we try to
understand all the concepts clearly. A pointer is a variable that contains the address of
the memory location of another variable. To create a pointer variable we use the syntax
as shown in the Figure below. First we will have to specify the type of data stored in the
location identified by the pointer. Then a variable is created along with an asterisk. The
asterisk tells the compiler that you are creating a pointer variable. Finally, you give the
name of the variable.
For example:
int *ptr;
The base type of the pointer defines which type of variables the pointer is pointing
to. Technically, any type of operator can point anywhere in memory. All pointer arithmetic
is done relative to its base type. So it is important to declare the pointers correctly.
ptr = #
This places the memory address of the variable num into the pointer variable ptr. If
num is stored in memory 1765 address, then the variable ptr has the value 1765. The
figure below highlights the situation discussed above.
Contents of
45 1765
pointer
num ptr
NOTE
We can also assign an address to the variable ptr directly. Thus the instruction
ptr = 1765;
ptr = #
*ptr = 45;
This means “ Place the value 45 in the memory address pointed by the variable
ptr.” Since the pointer contains the address 1765, the value 45 is placed in that memory
location. And since this is the location of the variable num, the value of num is also
becomes 45. This shows how we can change the value of a variable indirectly using a
pointer and the indirection operator.
Linked List
4
Program 4.2: To display the contents of the variable and their address using a pointer
variable.
#include <stdio.h>
void main( )
{
int num,*int_ptr;
float x,*float_ptr;
char ch, *char_ptr;
OUTPUT
Num 123 stored at the address 65524
Value 12.340000000 stored at the address 65520
Character A stored at the address 65519
The amount of memory space allotted when a variable is created and compiled
depends on the data type of the variable. The amount of space reserved for a variable
has already been explained in the previous section. In this section we try to understand
how much space will be allotted to a pointer variable of different types of data. The
program below highlights this point clearly.
Program 4.3: To show the amount of space required to store variables and space
reserved for pointers.
#include <stdio.h>
void main( )
{
int a = 5, *int_ptr;
char b = ‘w’, *char_ptr;
float c = 17.53, *float_ptr;
What is observed from the above-described fact is a very important fact. The
amount of space to store different variables may vary. However the size of all the addresses
available is the same and depends on the word length of the computer being used. Thus
we observe that all the outputs are the same i.e., a pointer is created to hold the address
of another memory location and the size of the address is the same immaterial of the
type of data it holds, thus the outputs are the same.
Pointers are used very much with functions. Also sometimes complex function
can easily be represented and accessed only with a pointer. Arguments can be passed to
one of the following methods.
Program 4.4 : To exchange the contents of the two variables using call by value and call
by reference.
Linked List
6
#include <stdio.h>
void main( )
{
int a,b;
void swap_val(int , int );
void swap_ref(int *, int * );
So far, it has been seen that a member of a structure could be an ordinary data
type such as int, float, char and even a structure also. In C, it is permitted to declare a
pointer as a member to a structure. A pointer can be used to hold the address of structure
variable. The pointer variable with structure can be used to construct a complex data
structures such as linked lists, doubly linked lists, binary tree etc.
struct complex
{
float real;
float imag;
};
Linked List
7
struct complex *ptrc1;
Where ptrc1 is a pointer variable holding the address of the structure complex
and is having two members, real of type float and imag of type float. Values can be
assigned to individual elements of a structure using the following method.
#include <stdio.h>
void main( )
{
struct complex
{
float *real;
float *imagi;
};
struct complex *c1;
struct complex *c1;
float real_part,imagi_part;
real_part = 34;
imagi_part = 77;
c1->real = &re;
c1->imagi = &imagi;
printf(“Content of the real part : %.2f”,*c1->real);
printf(“Content of the imaginary part : %.2f”,*c1->imagi);
}
OUTPUT
Content of the real part : 34
Content of the imaginary part : 77
The definitions for the library functions malloc( ) and calloc( ) is present in the
header file “alloc,h”. malloc( ) and calloc( ) are similar in their works. However they
differ in two important aspects. The function malloc( ) needs one argument which identifies
the total space to be reserved and the function calloc( ) requires two arguments the first
argument identifies the total locations required and the second argument identifies the
space required for each location.
Another difference between the functions malloc( ) and calloc( ) is that the memory
space created with malloc( ) contains garbage values whereas the memory space created
with calloc( ) is initialized to zeros if it points to an integer and blank spaces if it points
to a character.
#include <stdio.h>
#include “alloc.h”
#include <stdlib.h>
void main( )
{
int n,*p, i ,s=0;
float avg;
if ( p== NULL)
{
printf(“ Memory allocation unsuccessfull\n”);
exit();
}
printf(“ Enter %d numbers \n”,n);
for ( i=0 ; i<n ; i++)
scanf(“%d”, ( p + i ));
Whenever we go to the departmental store we carry a list along with us. The list
usually contains a list of items arranged in order indicating the items of our requirement.
Many problems in computing also involve lists of items. A list is a data type, which
contains elements of the same type arranged in a set of continuous memory locations.
With lists it is possible for us to perform certain operations such as searching the list,
sorting it, printing it, and so on. The structure we have used as the concrete data
representation of a list is the array, which is a sequential structure.
Operations such as searching can be very efficiently carried out using an array
representation. However, inserting and deleting items cannot be easily performed with
an array representation. To insert a new item into a location in a list, we must shift the
array elements down to make room for the new item. Similarly, deleting an item from
the list requires that we shift up all the array elements following the one to be deleted.
Another drawback with arrays is that they are not very adaptable since the size
of the array must be fixed in advance. The size of the array cannot be increased or
decreased during the execution of the program. These problems can be overcome by
considering another data structure called - the linked list.
A linked list represents a linear collection of items, called as nodes. Nodes of a linked
list can be scattered about in the memory, they need not necessarily represent a set of
consecutive memory locations. Each node in a linked list has two parts:
INFO LINK
NODE
3 5 7 NULL
A linked list in its simplest form is a collection of nodes that together form a
linear ordering. The ordering is determined as in the children’s game “Follow the leader,”
in that each node usually consists of a structure that includes information fields and a
link pointer. A singly linked list looks like that shown in the Figure.
HEAD
3 5 7 NULL
The Figure shows a list of numbers, which is represented, in the form of a linked
list. HEAD is a pointer, which gives the address of the first node in the linked list. Link
field of the last node contains the NULL, which indicates it does not contain any address.
It might seem like circular reasoning to have a node reference another node, but
such a scheme easily works. The next reference inside a node can be viewed as a link or
pointer to another node. Likewise, moving from one node to another by following a next
reference is known as link hopping or pointer hopping. The first and last node of a
linked list usually is called the HEAD and TAIL of the list, respectively. We identify the
tail as the node having a NULL next reference, which indicates the termination of the
list. A linked list defined in this way is known as a singly linked list.
We have seen that a linked list is a collection of nodes of the same type and
hence and it can be defined as follows:
struct Node
{
Data type Information; INFO LINK
struct Node *Link;
}; NODE
Once the structure of a node is defined we may want to allocate memory space
for the nodes of the linked list. Memory space is always allocated with the help of a
declaration statement. If we want to create a linked list that contains three nodes called
Node1, Node2 and Node3 the declaration may be as follows.
Linked List
11
Program 4.7: A program to create a linked list which contains three nodes.
#include <stdio.h>
struct Node
{
int info;
struct Node *link;
};
void main( )
{
struct Node *Node1, *Node2, *Node3;
Node1->info=123;
Node1->link=Node2;
Node2->info=456;
Node2->link=Node3;
Node3->info=789;
Node3->link=NULL;
printf(“\nLinked list is \n”);
printf(“%d\t%d\t%d\t NULL”,Node1->info,Node2->info,Node3->info);
}
OUTPUT
123 456 789 NULL
Using the above program we were able to create a linked list, which contains
three nodes. There are some situations where we do not know how many elements are
to be inserted in a linked list. In such a situation we will have to use an alternative
technique in which the list components are dynamically created only as they are needed.
These dynamic nodes are created by using pointers and dynamic memory
allocation function such as malloc( ). We start accessing the list with a pointer variable
Linked List
12
that holds the address of the first node in the list. This pointer variable is named as
HEAD. Every node after the first node can be accessed by using the link member in the
previous node.
Such a list can expand or contrast as the program executes. To insert a new item
into the list, we allocate more space. To delete an item, we de-allocate the memory
assigned to it. We don’t have to know in advance how long the list will be. The only
limitation is the amount of available memory space. Data structures built using this
technique are called dynamic data structures.
We would like to generalize this algorithm so that we can use a loop to create a
dynamic linked list of any length. General algorithm for creating a linked list is given
below.
ALGORITHM 4.1:
1. HEAD is used to hold the address of the first node of the linked list.
2. NewNode is used to hold the address of the new node.
3. CurrPtr, which is updated to always point to the last node in the linked
list.
Linked List
13
Program 4.8: Program to create a linked list.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;
void Create_link_list(int);
void Display(NODE *);
void main()
{
int ele;
char ch;
clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);
getch();
}
NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
NewNode->link=NULL;
if( HEAD==NULL)
HEAD=NewNode;
Linked List
14
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr->link=NewNode;
}
}
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}
OUTPUT
Linked list creation
Enter information field of the node 56
Do you wish to enter one more node ? y
Enter information field of the node 89
Do you wish to enter one more node ? y
Enter information field of the node 23
Do you wish to enter one more node ?n
Linked list elements
56 89 23 NULL
The statement is used to initialize the header to NULL, which indicates that the
linked list has not yet been created.
Using the above statements, the contents of the new node are entered.
HEAD
HEAD = NewNode;
3 NULL
NewNode
Connects the first node to the header pointer
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr
HEAD
3 5 NULL 7 NULL
NewNode
The looping statement takes the CurrPtr from the first node to the last node of
the linked list.
CurrPtr->link=NewNode;
CurrPtr
HEAD
3 5 7 NULL
The pointer to the new node is copied into the link member of CurrPtr, which
connects the newnode to the linked list.
Traversing is the process of visiting each node of the linked list exactly once to
perform some operation. Our aim is to traverse the list starting from the first node to
the end of the list. Let LIST be a linked list with nodes containing two fields INFO and
LINK. HEAD is a pointer variable, which contains the address of the first node in the
linked list. CurrPtr is a pointer variable, which points to the node currently being
processed. The fields of the node is referenced by INFO[CurrPtr] indicates information
field of the node which has the address stored in CurrPtr variable. LINK[CurrPtr] is the
link field of the node which has the address stored in CurrPtr variable. The statement
Linked List
16
CurrPtr = LINK[CurrPtr]
moves the pointer to the next node in the list as illustrated in the figure below.
ALGORITHM 4.2:
This algorithm traverses a linked list by applying a process to each element of the list.
The variable CurrPtr points to the node currently being processed.
Example: Printing all the elements of the linked list is an example of traversing a
linked list. Here 3,5,7 is printed.
CurrPtr
HEAD
3 5 7 NULL
To print the components of a linked list, we need to access the nodes one at a
time. This requirement implies an event controlled loop such as while should be used.
The event that stops the loop is reaching the end of the list. The loop control variable i.e.
CurrPtr is a pointer that is initialized to first node whose address is passed as an
argument to the function and is the advanced from one node to another by copying the
the link member of the current node. When the loop control pointer equals NULL, the
last node has been accessed.
Linked List
17
Let us do a code walk-through using the following list.
CurrPtr
CurrPtr=HEAD;
HEAD
3 5 7 NULL
CurrPtr and head both point to the first node in the list.
printf(“%d\t”,CurrPtr->info); CurrPtr
CurrPtr=CurrPtr->link;
HEAD
3 5 7 NULL
The number 3 is printed. CurrPtr now points to the second node in the list.
printf(“%d\t”,CurrPtr->info); CurrPtr
CurrPtr=CurrPtr->link;
HEAD
3 5 7 NULL
The number 5 is printed. CurrPtr now points to the third node in the list.
printf(“%d\t”,CurrPtr->info); CurrPtr
CurrPtr=CurrPtr->link; NULL
HEAD
3 5 7 NULL
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;
void Create_link_list(int);
void Display(NODE *);
int Largest (NODE *);
void main( )
{
int ele;
char ch;
clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);
printf(“\nLargest element in the list is %d”,Largest(HEAD));
getch();
}
NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
Linked List
19
NewNode->link=NULL;
if( HEAD==NULL)
HEAD=NewNode;
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr->link=NewNode;
}
}
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}
OUTPUT
NULL
NODE *GetNode()
{
NODE *NewNode;
The variable pointer NewNode points to the free node. Using malloc() function
we can allocate a free node and the address of the free node will be assigned to NewNode
pointer. If free node is not available the function malloc() returns NULL value and
assigned to NewNode pointer. This means that all the nodes are currently in use and it
is impossible to allocate any more. If a program calls on GetNode() function when the
available list is empty, the amount of storage assigned for the program’s data structure
is too small. Therefore, overflow occurs.
Linked List
21
4.12.4 INSERTING AN ITEM INTO A LINKED LIST
There are many applications where it is desired to maintain an order linear list.
The ordering may be in increasing order or decreasing order of information field. Such
an ordering often results more efficient processes in many cases. Before inserting a new
node, first we have to take the free node from the available list. If no free nodes are
available then we cannot insert the node. There are different types of insertions.
Let the HEAD pointer hold the address of the first node of the linked list. The
following algorithm will create a new node and insert this node at the beginning of the
linked list.
ALGORITHM 4.3:
Let LIST be a list stored in memory, HEAD gives the address of the first node. This
algorithm inserts ITEM into the list as the first node.
Step 1 : [Create a new node and store its address in the pointer NewNode]
NewNode = Address of new node
Step 2 : [Copy the information for the new node to the information part]
INFO[NewNode] = element
Step 3 : [Set the contents of the link part to contain the address of the first node]
LINK[NewNode] = HEAD
Step 4 : [Make the new node as the first node of the linked list]
HEAD = NewNode
Step 5 : Exit
The schematic diagram of Step 2, Step 3 and Step 4 are shown below
HEAD
3 5 7 NULL
9
NewNode
HEAD
3 5 7 NULL
9
NewNode
Linked List
22
HEAD
9 3 5 7 NULL
NewNode
NewNode->info=ITEM;
NewNode->link=HEAD;
HEAD = NewNode;
In some of the applications we have to append an item at the end of the list. To
append an item to a linked list, we loop through the list until find the element whose
link member points to NULL. The following algorithm is used to insert a node into a
linked list as a last node.
ALGORITHM 4.4:
Let LIST be a list stored in memory, HEAD gives the address of the first node. This
algorithm inserts ITEM into the list as the last node. CurrPTR is a pointer, which is
pointing to the current node of the list.
Step 1 : [Create a new node and store its address in the pointer NewNode]
NewNode = Address of new node
Step 2 : [Copy the information for the new node to the information part]
INFO[NewNode] = element
Step 3 : [Set the contents of the link part to NULL]
LINK[NewNode] = NULL
Step 4 : [Initialize HEAD value to CURRPTR ]
CurrPtr = HEAD
Step 5 : [Find the last node of the list]
While LINK[CurrPtr] != NULL Do
Step 6 : [Move CURRPTR to next node]
CurrPtr = LINK[CurrPtr]
Linked List
23
[WhileEnd]
Step 7 : [Connect the new node to the link of the last node]
LINK[CurrPtr] = NewNode
Step 8: Exit
CurrPtr
HEAD
NewNode
3 5 7 NULL 9 NULL
CurrPtr
HEAD
NewNode
3 5 7 NULL 9 NULL
HEAD
NewNode
3 5 7 9 NULL
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr->link=NewNode;
}
Linked List
24
4.12.4.3 INSERT A NODE AT A GIVEN POSITION
Suppose we are given the ITEM, which has to be placed at a given position in the
linked list. The following is an algorithm, which inserts ITEM into LIST so that ITEM is
placed at the required position.
ALGORITHM 4.5:
Let LIST be a list stored in memory, HEAD gives the address of the first node. This
algorithm inserts ITEM into the list at the position POS. CurrPTR is a pointer, which is
pointing to the current node of the list.
Step 1 : [Create a new node and store its address in the pointer NewNode]
NewNode = Address of new node
Step 2 : [Copy the information for the new node to the information part]
INFO[NewNode] = element
Step 3 : [Initialize HEAD value to CURRPTR ]
CurrPtr = HEAD
Step 4 : [Move to the required position]
For I = 1 to POS - 1 and CurrPtr != NULL Do
Step 5 : [Move CURRPTR to next node]
CurrPtr = LINK[CurrPtr]
[ForEnd]
Step 6 : [Check whether the position is found or not]
If ( CurrPtr = NULL)
Print “ Position Out Of Range”
Exit
Step 7 : Else
[Insert the new node at the required position]
LINK[NewNode] = LINK[CurrPtr]
LINK[CurrPtr] = NewNode
[EndIf]
Step 8: Exit
CurrPtr
HEAD
3 5 7 NULL
NewNode
Linked List
25
CurrPtr
HEAD
3 5 7 NULL
9
NewNode
HEAD
3 5 9 7 NULL
NewNode
Figure 4.9 Insert an ITEM (9) at the third position of the list.
CurrPtr = HEAD;
for( i = 1; i< POS - 1 && CurrPtr != NULL; i++)
CurrPtr = CurrPtr->link;
if ( CurrPtr ==NULL)
{ printf(“Position Out Of Range\n”);
exit(0);
}
NewNode->link = CurrPtr->link;
CurrPtr->link = NewNode;
}
#include <stdio.h>
#include <stdlib.h>
Linked List
26
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;
void Create_link_list(int);
void Display(NODE *);
void Insert_Beginning(int);
void Insert_End(int);
void Insert_Position(int,int);
void main()
{
int ele,pos;
char ch;
clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);
printf(“\nInsert Operation\n\n”);
do
{
printf(“\nChoose Position To Insert: \n”);
printf(“\n1. AT THE BEGINING”);
printf(“\n2. AT THE END”);
printf(“\n3. AT A GIVEN POSITION”);
printf(“\n4. EXIT”);
printf(“\n\nEnter your choice : “);
scanf(“%d”,&ch);
switch(ch)
{
case 1: {
Linked List
27
printf(“\nEnter element to add : “);
scanf(“%d”,&ele);
Insert_Beginning(ele);
printf(“\nThe linked list is \n”);
Display(HEAD);
break;
}
case 2: {
printf(“\nEnter element to add : “);
scanf(“%d”,&ele);
Insert_End(ele);
printf(“\nThe linked list is \n”);
Display(HEAD);
break;
}
case 3: {
printf(“\nEnter element to add : “);
scanf(“%d”,&ele);
printf(“\nEnter position to add: “);
scanf(“%d”,&pos);
Insert_Position(ele,pos);
printf(“\nThe linked list is \n”);
Display(HEAD);
break;
}
}
}while(ch != 4);
getch();
}
NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
NewNode->link=NULL;
if( HEAD==NULL)
HEAD=NewNode;
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr->link=NewNode;
}
}
Linked List
28
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}
NewNode->info=ITEM;
NewNode->link=HEAD;
HEAD = NewNode;
}
CurrPtr->link=NewNode;
}
CurrPtr = HEAD;
Linked List
29
for( i = 1; i< POS-1 && CurrPtr != NULL; i++)
CurrPtr = CurrPtr->link;
if ( CurrPtr ==NULL)
{ printf(“Position Out Of Range\n”);
exit(0);
}
NewNode->link = CurrPtr->link;
CurrPtr->link = NewNode;
}
OUTPUT
Linked list creation
Enter information field of the node 56
Do you wish to enter one more node ? y
Enter information field of the node 89
Do you wish to enter one more node ? y
Enter information field of the node 23
Do you wish to enter one more node ?n
Linked list elements
56 89 23 NULL
Insert Operation
Choose Position To Insert:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 1
Enter element to add : 15
The linked list is
15 56 89 23 NULL
Choose Position To Insert:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 2
Enter element to add : 19
The linked list is
15 56 89 23 19 NULL
Choose Position To Insert:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 3
Enter element to add : 65
Enter position to add: 2
The linked list is
15 65 56 89 23 NULL
Linked List
30
4.13 GARBAGE COLLECTION
Garbage collection usually takes place in two steps. First the computer run
through all lists, tagging those cells which are currently in use, and then the computer
runs through the memory, collecting all untagged space onto the free-storage list. The
garbage collection may take place when there is only some minimum amount of space
or no space at all left in free-storage list or when CPU is idle and has time to do the
collection. Generally speaking, the garbage collection is invisible to the programmer.
The free( ) function in C returns a node to the free pool, i.e availability list. This function
makes a node that is no longer being used in the linked list available for reuse. The
following function FreeNode( ) is used to remove a node temp from the linked list and
inserted into availability list.
Function to delete a node and insert this node into availablity list
void FreeNode( )
{
NODE *temp;
free(temp);
}
To delete an existing node from a linked list, we have to loop through the nodes
until we find the node we want to delete. We should follow the steps below to delete a
node from a linked list:
1. If the linked list is empty, then deletion is not possible and this condition is
called as underflow condition.
2. To delete a particular node, we have to loop through the nodes until we find
the node we want to delete.
3. If the end of the list has been reached, “Position out of range” message can
be displayed.
4. Insert deleted node into the free area.
To delete the first node, we just change the HEAD pointer to point to the second
node or to contain NULL if we are deleting the only node in a one-node list. Suppose we
have a linked list as shown in Figure and want to delete first node.
HEAD
3 5 7 9 NULL
HEAD
5 7 9 NULL
ALGORITHM 4.6:
Let LIST be a linked list stored in memory. It deletes first node from the linked list.
HEAD gives the address of the first node.
int Delete_Beginning( )
{
NODE *CurrPtr;
int ele;
if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
ele = CurrPtr->info;
HEAD = CurrPtr->link;
free(CurrPtr);
return(ele);
}
To delete a last node of a linked list, we have to scan the list from the beginning
and find the address of the next to last node and assign NULL to link field of the next to
last node. The following algorithm deletes the last node from the linked list and insert-
deleted node into availability list. Following is the data structure after the execution of
the function.
CurrPtr
HEAD
3 5 7 NULL 9 NULL
PrevPtr
HEAD
3 5 7 NULL
ALGORITHM 4.7:
Let LIST be a linked list stored in memory, It deletes first node from the linked list.
HEAD gives the address of the first node. CurrPtr is a pointer, which is being pointing
Linked List
33
current node of the list. PrevPtr is a pointer, which is pointing the previous node of the
current node.
Step 1 : [List empty ?]
If HEAD = NULL Then
Display “Under flow”
Exit
[EndIf]
Step 2 : [ Initialize pointer variables CurrPtr ]
CurrPtr = HEAD
Step 3 : [Traverse linked list and take the pointer to next node]
While (LINK(CurrPtr) != NULL) Do
Step 4 : PrevPtr = CurrPtr
Step 5 : CurrPtr = LINK[CurrPtr]
[ End of While ]
Step 6 : LINK[PrevPtr] = NULL
Step 7 : [Return deleted node to the AVAIL list]
FREE[CurrPtr]
Step 8: Exit
int Delete_End( )
{
NODE *CurrPtr,*PrevPtr;
int ele;
if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
while ( CurrPtr->link != NULL)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}
ele = CurrPtr->info;
PrevPtr->link = NULL;
free(CurrPtr);
return(ele);
}
The function for deleting a node at a given position involves the following steps.
Linked List
34
1. Find the location of the node with CurrPtr, and location of previous node
with PrevPtr.
2. Delete the node (This is nothing but deleting the node following a given node).
CurrPtr
HEAD
3 5 7 9 NULL
PrevPtr
HEAD
3 5 9 NULL
Figure 4.12 Delete the node at the third position of the list.
ALGORITHM 4.8:
Let LIST be a linked list stored in memory, It deletes first node from the linked list.
HEAD gives the address of the first node. POS is the position of the node, which is to be
deleted. CurrPtr is a pointer, which is being pointing to the node at a given position of
the list. PrevPtr is a pointer, which is pointing the previous node of the current node.
if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
for( i = 1; i< POS && CurrPtr != NULL; i++)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}
if ( CurrPtr == NULL)
{
printf(“\nPositon out of range”);
exit(0);
}
ele = CurrPtr->info;
PrevPtr->link = CurrPtr->link;
free(CurrPtr);
return(ele);
}
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *link;
};
typedef struct node NODE;
NODE *HEAD;
Linked List
36
void Create_link_list(int);
void Display(NODE *);
int Delete_Beginning();
int Delete_End();
int Delete_Position(int);
void main( )
{
int ele,pos;
char ch;
clrscr();
HEAD = NULL;
printf(“\nLinked list creation\n\n”);
do{
printf(“Enter information field of the node\n”);
scanf(“%d”,&ele);
Create_link_list(ele);
printf(“Add another node\n”);
flushall();
scanf(“%c”,&ch);
}while(toupper(ch)==’Y’);
printf(“\nThe linked list is \n”);
Display(HEAD);
printf(“\nDeletion Operation\n\n”);
do
{
printf(“\nChoose Position To Delete: \n”);
printf(“\n1. AT THE BEGINING”);
printf(“\n2. AT THE END”);
printf(“\n3. AT A GIVEN POSITION”);
printf(“\n4. EXIT”);
printf(“\n\nEnter your choice : “);
scanf(“%d”,&ch);
switch(ch)
{
case 1: {
ele = Delete_Beginning();
printf(“\nDeleted element is :%d “,ele);
printf(“\nThe linked list is \n “);
Display(HEAD);
break;
}
case 2: {
ele = Delete_End();
printf(“\nDeleted element is :%d “,ele);
printf(“\nThe linked list is \n “);
Linked List
37
Display(HEAD);
break;
}
case 3: {
printf(“\nEnter position to delete: “);
scanf(“%d”,&pos);
ele = Delete_Position(pos);
printf(“\nDeleted element is :%d “,ele);
printf(“\nThe linked list is \n “);
Display(HEAD);
break;
}
}
}while(ch != 4);
getch();
}
NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->info=ele;
NewNode->link=NULL;
if( HEAD==NULL)
HEAD=NewNode;
else
{
CurrPtr=HEAD;
while(CurrPtr->link!=NULL)
CurrPtr=CurrPtr->link;
CurrPtr->link=NewNode;
}
}
/* Function to display linked list elements */
void Display(NODE *CurrPtr)
{
while(CurrPtr!=NULL)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->link;
}
printf(“NULL\n”);
}
Linked List
38
/* Function to delete a node at the beginning of the linked list */
int Delete_Beginning( )
{
NODE *CurrPtr;
int ele;
if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
ele = CurrPtr->info;
HEAD = CurrPtr->link;
free(CurrPtr);
return(ele);
}
int Delete_End( )
{
NODE *CurrPtr,*PrevPtr;
int ele;
if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
while ( CurrPtr->link != NULL)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}
ele = CurrPtr->info;
PrevPtr->link = NULL;
free(CurrPtr);
return(ele);
}
if ( HEAD == NULL)
{
printf(“\nDeletion not possible”);
exit(0);
}
CurrPtr = HEAD;
for( i = 1; i< POS && CurrPtr != NULL; i++)
{
PrevPtr = CurrPtr;
CurrPtr = CurrPtr->link;
}
if ( CurrPtr == NULL)
{
printf(“\nPositon out of range”);
exit(0);
}
ele = CurrPtr->info;
PrevPtr->link = CurrPtr->link;
free(CurrPtr);
return(ele);
}
OUTPUT
Linked list creation
Enter information field of the node 56
Do you wish to enter one more node ? y
Enter information field of the node 89
Do you wish to enter one more node ? y
Enter information field of the node 23
Do you wish to enter one more node ? y
Enter information field of the node 35
Do you wish to enter one more node ?n
Linked list elements
56 89 23 35 NULL
Deletion Operation
Choose Position To Delete:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 1
Deleted element is : 56
The linked list is
89 23 35 NULL
Choose Position To Delete:
Linked List
40
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 2
Deleted element is : 35
The linked list is
89 23 NULL
Choose Position To Delete:
1. AT THE BEGINING
2. AT THE END
3. AT A GIVEN POSITION
4. EXIT
Enter your choice : 3
Enter position to delete: 2
Deleted element is : 23
The linked list is
89 NULL
Some applications do not require that there be a particular first or last list element.
In such cases, it may be convenient to allow access from the last element to the first. In
the normal linked list, the link field of the last element stores the value NULL. By instead
storing a pointer to the first element in the list, a circular list is created. With this
implementation, a TAIL pointer is no longer needed. Figure illustrates a circular singly
linked list. The primary danger with such implementations is that list-processing
operations may go into infinite loop since there is no obvious end to the list. However,
the HEAD pointer can be used as a marker to determine when list processing has
worked full circle through the list.
HEAD
3 5 9 7
ALGORITHM 4.9:
HEAD is a header node which contains three fields, NodeNo, INFO and LINK. The LINK
field holds the address of the first node in a circular linked list. CurrPtr is a pointer
which is being pointing current node of the list.
Program 4.12:To illustrate circular linked list operations (Creation and traversing).
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <stdlib.h>
struct node
{
int NodeNo;
int info;
struct node *link;
};
typedef struct node NODE;
int count=0;
/* Function to create a circular linked list */
void Create_Circular_list(NODE *head)
{
char ans;
NODE *CurrPtr;
head->link=(NODE *)malloc(sizeof(NODE));
CurrPtr=head->link;
while(1)
{
Linked List
42
count++;
printf(“Enter information field of the node “);
scanf(“%d”,&CurrPtr->info);
CurrPtr->NodeNo=count;
printf(“\nDo you want enter next node ? “);
scanf(“ %c”,&ans);
if(toupper(ans)==’N’)
{
CurrPtr->link=head;
break;
}
CurrPtr->link=(NODE *)malloc(sizeof(NODE));
CurrPtr=CurrPtr->link;
}
head->NodeNo=count;
}
/* Function to display circular linked list elements */
void Display(NODE *head)
{
int i;
head=head->link;
for(i=1;i<=count;head=head->link,i++)
printf(“\nNode %d information is %d”,head->NodeNo,head->info);
}
/* Main function */
void main( )
{
NODE *head;
clrscr();
head=(NODE *)malloc(sizeof(NODE));
Create_Circular_list(head);
printf(“Number of nodes in the circular linked list is %d”,head->NodeNo);
Display(head);
}
OUTPUT
Enter information field of the node 25
Do you want enter next node ? y
Enter information field of the node 40
Do you want enter next node ? y
Enter information field of the node 60
Do you want enter next node ? y
Enter information field of the node 5
Do you want enter next node ? n
Number of nodes in the circular linked list is 4
Node 1 information is 25
Node 2 information is 40
Node 3 information is 60
Node 4 information is 5
Linked List
43
4.15.1 ADVANTAGES OF CIRCULAR LINKED LIST
1. In a circular linked list every node is accessible from a given node. That is
from the given node, nodes can be reached by merely chaining the list.
2. Concatenation and splitting the operations are more efficient.
The singly linked list presented in previous section allows for direct access from
a list node only to the next node in the list. This list is named as singly linked list
because each list element contains a pointer to the next element. In singly linked list,
traversing is possible only in one direction. Sometimes it is required to traverse a list in
forward direction or backward direction. A doubly linked list is designed to allow
convenient access from a list node to the next node and also to the preceding node on
the list. This is also used to traverse the list in both the directions.
In a doubly linked list each node has not only pointer to the next node but also
a pointer to the prior node. Each node of doubly linked list is divided into three parts
(fields):
1. A pointer BACK (leftlink) which contains the location of the preceding node
in the list.
2. An information field INFO which contains data of N.
3. A pointer FORW (rightlink) which contains location of the next node in the
list.
HEAD
NULL 3 5 7 NULL
The doubly linked list is also called as two-way list because we can traverse the
list in two directions: in the usual forward direction from the beginning of the list to
end, or in the backward direction from the end of the list to the beginning.
struct node
{
int info; // Information field
struct node *rlink; // a pointer which is pointing right node
struct node *llink; // a pointer which is pointing left node
};
ALGORITHM 4.10:
This algorithm is used to create a doubly linked list whose left-most and right-most
node addresses are given by the pointer variables LEFT and RIGHT, respectively.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
struct node
{
int info;
struct node *rlink;
struct node *llink;
};
Linked List
45
typedef struct node NODE;
/* Function to display doubly linked list in forward direction */
void Display_Forward(NODE *CurrPtr)
{
while(CurrPtr)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->rlink;
}
}
/* Function to display doubly linked list in backward direction */
void Display_Backward(NODE *CurrPtr)
{
while(CurrPtr)
{
printf(“%d\t”,CurrPtr->info);
CurrPtr=CurrPtr->llink;
}
}
/* Function to create a doubly linked list node */
NODE *GetNode()
{
NODE *NewNode=(NODE *)malloc(sizeof(NODE));
NewNode->llink=NULL;
NewNode->rlink=NULL;
printf(“Enter information field of the node “);
scanf(“%d”,&NewNode->info);
return NewNode;
}
/* Main function */
void main( )
{
NODE *RIGHT=NULL,*LEFT=NULL,*NewNode;
char ans;
clrscr( );
while(1)
{
printf(“Do you want to enter a new node ?”);
scanf(“ %c”,&ans);
if(toupper(ans)==’N’)break;
NewNode=GetNode();
if(RIGHT==NULL)
{
LEFT=NewNode;
RIGHT=NewNode;
}
else
{
NewNode->llink=RIGHT;
Linked List
46
RIGHT->rlink=NewNode;
RIGHT=RIGHT->rlink;
}
}
printf(“\nDoubly Linked list elements \n”);
Display_Forward(LEFT);
printf(“\nDoubly linked list in the reverse direction \n”);
Display_Backward(RIGHT);
}
OUTPUT
Do you want to enter a new node ? y
Enter information field of the node 34
Do you want to enter a new node ? y
Enter information field of the node 56
Do you want to enter a new node ? y
Enter information field of the node 7
Doubly Linked list elements
34 56 7
Doubly linked list in the reverse direction
7 56 34