Module 3 Notes
Module 3 Notes
MODULE-3
LINKED LISTS
TOPICS
Linked Lists: Definition, Representation of linked lists in Memory, Memory allocation:
Garbage Collection.
Linked list operations: Traversing, Searching, Insertion, and Deletion.
Doubly Linked lists, Circular linked lists, and header linked lists
Linked Stacks and Queues.
Applications of Linked lists – Polynomials, Sparse matrix representation.
Programming Examples
LINKED LISTS
In this chapter, the list data structure is presented. This structure can be used as the basis for the
implementation of other data structures (stacks, queues etc.). The basic linked list can be used without
modification in many programs. However, some applications require enhancements to the linked list
design. These enhancements fall into three broad categories and yield variations on linked lists that can
be used.
The disadvantages of arrays are:
● The size of the array is fixed. Most often this size is specified at compile time. This makes the
programmers to allocate arrays, which seems "large enough" than required.
● Inserting new elements at the front is potentially expensive because existing elements need to be
shifted over to make room.
● Deleting an element from an array is not possible. Linked lists have their own strengths and
weaknesses, but they happen to be strong where arrays are weak. Generally, arrays allocate the
memory for all its elements in one block whereas linked lists use an entirely different strategy.
Linked lists allocate memory for each element separately and only when necessary.
Here is a quick review of the terminology and rules of pointers. The linked list code will depend
on the following functions:
● malloc() is a system function which allocates a block of memory in the "heap" and returns a pointer
to the new block. The prototype of malloc() and other heap functions are in stdlib.h. malloc() returns
NULL if it cannot fulfill the request. It is defined by: void *malloc (number_of_bytes) Since a void *
is returned the C standard states that this pointer can be converted to mple, any type.
● For ex: char *cp; cp = (char *) malloc (100); Attempts to get 100 bytes and assigns the starting
address to cp. We can also use the sizeof() function to specify the number of bytes. For example, int
*ip; ip = (int *) malloc (100*sizeof(int));
● free() is the opposite of malloc(), which de-allocates memory. The argument to free() is a pointer to
a block of memory in the heap — a pointer which was obtained by a malloc() function. The syntax
is: free (ptr); The advantage of free() is simply memory management when we no longer need a
block.
● A circular linked list is one, which has no beginning and no end. A single linked list can be made a
circular linked list by simply storing address of the very first node in the link field of the last node.
● A circular double linked list is one, which has both the successor pointer and predecessor pointer in
the circular manner.
3. Removal of nodes
At any point if the allocated nodes are not in use, they are removed by free( ).
Example: To create a linked list of words following the above steps follow the steps given below.
1. Defining a node
Using self-referential structures nodes are created. for a list of words, in every node the data field should
store words, so define datatype accordingly.
typedef struct listnode *listpointer;
typedef struct
{
char data[4];
listpointer link;
}listNode;
This definition will result into a node by name listNode containing char data field of size 4 and a
field by name link , which is a pointer variable of type listpointer , where listpointer is a pointer to whole
structure.
link
listpointer first=NULL;
● Here, first is a variable of type pointer i.e. listpointer, initially making it as NULL and hence , a
new list is created by name first and it is empty,
strcpy(first🡪data,”BAT”);
first🡪link=NULL;
These statements are represented as below:
B A T \0 NULL
GARBAGE COLLECTION
● When the memory is allocated to the linked lists, a special list is maintained which consists of
unused memory cells. This list, which has its own pointer, is called the list of available space/ the
free storage list or the free pool.
● When node is deleted from a list or a entire list is deleted from a program, the memory space has to
be inserted into free storage list, so that it will be reusable.
● The operating system of a computer may periodically collect all the deleted space onto the
free-storage list. Any technique which does this collection is called garbage collection.
1. The computer runs through all list, 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.
2. the garbage collection may take place when there is only some minimum amount of space or
no space at all left in the free-storage list or when the CPU is idle and has time to do the
collection
1. INSERTION
Insertion operation is used to insert new node to the list created. This operation is performed
depending on many scenarios of linked lists like
● If the linked list is empty, then new node after insertion becomes the first node.
● If the list already contains nodes the new node is attached either at front end of the list or at the last
end.
● If the insertion is based on the data element/position, then search the list to find the location and then
insert the new node.
NOTE: same conditions are checked for deleting a node from the list as well.
Here, if we need to insert the data item GAT between FAT and HAT, the following steps are
followed.
● Get a node temp
● Set the link field of temp to point to the node after FAT, which contains HAT
In figure, if we need to delete FAT, then find the element that immediately precedes the element to be
deleted.
EX :- Here, identify EAT.
● Set that element link to the position of GAT i.e. EAT link should point to GAT.
listpointer first,second;
first = malloc(sizeof(*first));
second = malloc(sizeof(*second));
first🡪data=10;
second🡪data=20;
first🡪link=second;
second🡪link=NULL;
return first;
}
C function to insert new node with data value 50 into the SLL by name first after the node X.
void insert(listpointer *first, listpointer X)
{
listpointer temp;
temp=malloc(sizeof(*temp));
temp🡪data = 50;
if(*first)
{
temp🡪 link = x🡪link;
x🡪link = temp;
}
else
{
temp🡪 link = NULL;
*first=temp;
}
}
Node to be inserted
temp
first🡪
● So, here we are passing the address of first, the second argument is the X.
2. LIST DELETION
Example deletes X from the list first , where trail is the preceding node of X.
void delete( listpointer *first, listpointer trail, listpointer X)
{
if(trail)
trail🡪link = x🡪link;
else
*first = (*first)🡪link;
free(x);
}
● In this example, the node x , which has to be deleted is the first node itself. so, after deleting that
node, resultant linked list should be like , next figure. so, we must change the value of first to
point to node with data value 50.
● In above example, deletion corresponds to the function call, delete (&first, y, y🡪link); where, y
is the trail node for the deleting node x, which is y🡪link, i.e, the next node after y. so deleting
node containing data 20 is performed and y🡪link set to NULL.
3. SEARCHING
● Searching operation performs the process of finding the node containing the desired value in
linked list.
● Searching starts from the first node of the linked list, so that the complete linked list can be
searched to find the element. if found search is successful, else unsuccessful.
Figure 5: DLL
● In singular linked list, it is possible to traverse in only one direction (forward) in the linked list.
● If we are pointing to a specific node say p, then we can move only in the direction of the links.
● To find a node before p, i.e. preceding node p is difficult unless we start from beginning to reach
its previous node.
● Same problem exists, when delete or insertion operations are done on any arbitrarily node in
SLL.
● These problems can be overcome using DLL, as they have both direction links, from any node p,
where we can find next node/ preceding node easily.
C Representation of DLL
A node in a doubly linked list has at least three fields, a left link field (llink), a data field(data), and a
right link field(rlink).
2. Deletion
It deleted the node from the list pointed to by node.
void delete(nodepointer node,nodepointer deleted)
{
if(node == deleted)
printf(“\n deletion of header node is not permitted”);
else
{
deleted🡪llink🡪rlink=deleted🡪rlink;
deleted🡪rlink🡪llink=deleted🡪llink;
free(deleted);
}
}
Figure 8: CSLL
In a singly linked circular list, the pointer field of the last node stores the address of the starting node In
the list. Hence it is easy to traverse the list given the address of any node in the list.
A doubly linked list whose last node rlink points to first node and first node llink points to last node,
making it is a circular called as circular DLL.
Figure 9: CDLL
To insert a new node into circular DLL at the end
void dinsert(nodepointer node,nodepointer newnode)
{
newnode🡪llink=node;
newnode🡪rlink=node🡪rlink;
node🡪rlink🡪llink=newnode;
node🡪rlink=newnode;
}
typedef struct
{
int key;
}Element;
typedef struct stack * stackPointer;
typedef struct
{
Element data;
stackPointer link;
}stack;
stackPointer top[MAX_STACKS];
● The initial condition for the stack is top[i]=NULL, 0<i<=MAX_STACKS.
● Boundary condition is top[i]=NULL if the ith stack is empty.
top[i] = temp;
}
● The above C function is to add item to the ith stack.
2) POP:-
Element pop(int i)
{
stackPointer temp = top[i];
Element item;
if(!temp)
return stackEmpty();
item = temp->data;
top[i] = temp->link;
free(temp);
return item;
}
● The above C function is used to delete top element from ith stack.
LINKED QUEUES:-
● To represent ‘m’ queues simultaneously, declarations are as follows:- where m<=MAX_QUEUES.
#define MAX_QUEUES 10
typedef struct queue *queuePointer;
typedef struct
{
Element data;
queuePointer link;
}queue;
queuePointer front[MAX_QUEUES], rear[MAX_QUEUES];
● In initial condition for the queue, front[i] = NULL, 0<=i<MAX_QUEUES and the boundary is
front[i] = NULL iff the ith queue is empty.
Operations of Linked queue:-
1) Insert:- add an item to the rear end of a linked queue.
void addq(i, item)
{
queuePointer temp;
temp = malloc(sizeof(*temp));
temp->data = item;
temp->link = NULL;
if(front[i])
rear[i]->link = temp;
else
front[i] = temp;
rear[i] = temp;
}
2) Delete:- Deletes an item from the front of a linked queue.
Element deleteq( int i)
{
queuePointer temp = front[i];
Element item;
if(!temp)
return queueEmpty();
item = temp->dtaa;
front[i] = temp->link;
free(temp);
return item;
}
a= 3x14+2x8+1, b = 8x14-3x10+10x6
3 14
2 8
1 0
3 10
8 14
10 6
Erasing Polynomials:-
● While using polynomials for different computations, temporary nodes which are having actually
waste data can be erased.
● Example:- For performing e(x) = a(x) * b(x) + d(x);
● Main function is as below:-
polyPointer a,b,d,e;
a=readPoly();
b=readPoly();
d=readPoly();
temp=pmult(a,b);
e=padd(temp,d);
printPoly(e);
● Here, temp is a node, which need to be erased. So, the following function is used to erase nodes.
void erase(polyPointer *ptr)
{
polyPointer temp;
while(*ptr)
{
temp=*ptr;
*ptr=(*ptr)->link;
free(temp);
}
}
● When we need a new node, freed nodes list is examined, if it is not empty, then use those nodes. If
not, use malloc() to create a new node.
● getNode() & retNode() functions are used to use a node and free the node as malloc() and free().
polyPointer getNode(void)
{
polyPointer node;
if(avail)
{
node=avail;
avail=avail->link;
}
else
MALLOC(node, sizeof(*node));
return node;
}
void retNode(polyPointer node)
{
/*return a node to the available list */
node->link=avail;
avail = node;
}
SPARSE MATRIX:-
● Sparse Matrix is a matrix with more number of zero enteries than non-zero enteries.
● Each non-zero term is represented by a node with 3 fields:- row, column and value.
● Linked list representation for sparse matrix are more efficient than array representation.
● In this represenation, each column of a sparse matrix is represented as a circularly linked list with a
header node.
● Similarly, representation is used for each row of the sparse matirx.
● Each node has a tag field, which distinguish between header nodes and entry nodes. Each header
node has 3 additional fields:- down, right & next.
o down field to link into a column list.
o right field to link into a row list.
o next field links the header nodes together.
● Each element entry node has 3 fields in addition to the tag field:- row, col, down, right value.
o down field to link to next non-zero term in the same column.
o right field to link to next non-zero term in the same row.
● Thus, if aij ≠ 0, there is a node into tag field = entry, value =aij, row=i & cal=j.
{
/* read in a matrix & sets up its linked representation */
int num Rows,numCols,numTerms,numHead,i;
int row,col,value,currentRow;
matrix pointer temp,last,node;
printf(“enter the number of rows,columns,non-zero terms”);
scanf(“%d%d%d”,&numRows,&numCols,&numTerms);
numHeads=(numcols>numRows) ? numCols:numRows;
node=newNode();
node🡪tag=entry;
node🡪u .entry.row=numRows;
node🡪u.entry.col=numCols;
if(!numHeads)
node🡪right=node;
else
/*initialize the header nodes8/
{
for(i=0;i<numHeads;i++)
{
temp=newNode;
hdnode[i]=temp;
hdnode[i]->tag = head;
hdnode[i]->right = temp;
hdnode[i]->u.next = temp;
}
currentRow = 0;
last = hdnode[0];
for(i=0;i<numTerms;i++)
{
printf(“Enter row, column & value”);
scanf(“%d %d %d”, & row, & col, & value);
if(row>currentRow)
{
last->right = hdnode[currentRow];
currentRow = row;
last=hdnode[row];
}
MALLOC(temp, sizeof(*temp));
temp->tag = entry;
temp->u.entry.row=row;
temp->u.entry.col=col;
temp->u.entry.value=value;
last->right = temp;
hdnode[col]->u.next->down= temp;
hdnode[col]->u.next = temp;
}
last->right = hdnode[currentRow];
for(i=0;i<numCols;i++)
hdnode[i]->u.next->down = hdnode[i];
hdnode[numHeads-1]->u.next=node;
node->right = hdnode[0];
}
return node;
}
6. Design, Develop and Implement a menu driven Program in C for the following operations
on Circular QUEUE of Characters (Array Implementation of Queue with maximum size
MAX)
e. Exit
Support the program with appropriate functions for each of the above operations
#include <stdio.h>
#include<stdlib.h>
#define qmax 5
char q[qmax];
int front=0,rear=-1;
void qinsert();
void qdelete();
void qdisplay();
void main()
{
int ch;
printf("\nCircular Queue operations\n");
printf("1.insert\n2.delete\n3.display\n4.exit\n");
while(1)
{
printf("Enter your choice:");
scanf("%d",&ch);
switch(ch)
{
case 1: qinsert(); break;
case 2: qdelete(); break;
case 3: qdisplay(); break;
case 4: exit(1);
default: printf("Invalid option\n");
}
}
}
void qinsert()
{
char x;
if((front==0&&rear==qmax-1)||(front>0&&rear==front-1))
printf("Queue is overflow\n");
else
{
printf("\nEnter element to be insert:");
scanf("\n%c",&x);
if(rear==qmax-1&&front>0)
{
rear=0;
q[rear]=x;
}
else
{
if((front==0&&rear==-1)||(rear!=front-1))
q[++rear]=x;
}
printf("%c is successfully inserted", x);
}
void qdelete()
{
char a;
if((front==0)&&(rear==-1))
{
printf("Queue is underflow\n");
return;
}
if(front==rear)
{
a=q[front];
rear=-1;
front=0;
}
else if(front==qmax-1)
{
a=q[front];
front=0;
}
else a=q[front++];
printf("Deleted element is:%c\n", a);
}
void qdisplay()
{
int i,j;
if(front==0&&rear==-1)
{
printf("Queue is underflow\n");
return;
}
if(front>rear)
{
for(i=0;i<=rear;i++)
printf("\t%c",q[i]);
for(j=front;j<=qmax-1;j++)
printf("\t%c",q[j]);
printf("\nrear is at %c\n",q[rear]);
printf("\nfront is at %c\n",q[front]);
}
else
{
for(i=front;i<=rear;i++)
printf("\t%c",q[i]);
printf("\nrear is at %c\n",q[rear]);
printf("\nfront is at %c\n",q[front]);
}
printf("\n");
}
7. Design, Develop and Implement a menu driven Program in C for the following operations
on Singly Linked List (SLL) of Student Data with the fields: USN, Name, Branch, Sem, PhNo
a. Create a SLL of N Students Data by using front insertion.
b. Display the status of SLL and count the number of nodes in it
c. Perform Insertion / Deletion at End of SLL
d. Perform Insertion / Deletion at Front of SLL(Demonstration of stack)
e. Exit
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
int count=0;
struct node
{
int sem;
char phno[10];
char name[20],branch[20],usn[10];
struct node *next;
}*first=NULL,*last=NULL,*temp=NULL;
void create()
{
int sem;
char name[20],usn[10],branch[20],phno[10];
temp=(struct node *)malloc(sizeof(struct node));
strcpy(temp->usn,usn);
strcpy(temp->name,name);
strcpy(temp->branch,branch);
strcpy(temp->phno,phno);
temp->sem=sem;
temp->next=NULL;
count++;
}
void deletefront()
{
temp=first;
if(first==NULL)
{
printf("\n list is empty");
return;
}
if(temp->next==NULL)
{
printf("The deleted node is \n");
printf("%s\t%s\t%s\t%d\t%s",temp->name,temp->usn,temp->branch,temp->sem,temp->phno);
free(temp);
first=NULL;
}
else
{
first=temp->next;
printf("The deleted node is \n");
printf("%s\t%s\t%s\t%d\t%s",temp->name,temp->usn,temp->branch,temp->sem,temp->phno);
free(temp);
}
count--;
}
void deleteatend()
{
temp=first;
if(first==NULL)
{
printf("\n list is empty");
return;
}
if(temp->next==NULL)
{
printf("The deleted node is \n");
printf("%s\t%s\t%s\t%d\t%s",temp->name,temp->usn,temp->branch,temp->sem,temp->phno);
free(temp);
first=NULL;
}
else
{
while(temp->next!=last)
temp=temp->next;
printf("The deleted node is \n");
printf("%s\t%s\t%s\t%d\t%s",last->name,last->usn,last->branch,last->sem,last->phno);
free(last);
last=temp;
last->next=NULL;
}
count--;
}
void insertatfirst()
{
create();
if(first==NULL)
{
first=temp;
last=first;
}
else
{
temp->next=first;
first=temp;
}
}
void insertatlast()
{
create();
if(first==NULL)
{
first=temp;
last=first;
}
else
{
last->next=temp;
last=temp;
}
}
void display()
{
if(first==NULL)
{
printf("\n list is empty");
}
else
{
temp=first;
printf("The node is \n");
while(temp!=NULL)
{
printf("%s\t%s\t%s\t%d\t%s--->",temp->name,temp->usn,temp->branch,temp->sem,temp->phno);
temp=temp->next;
printf("\n");
}
printf("\nThe number of nodes in the linked list is %d.",count);
}
}
void main()
{
int ch,i,n;
clrscr();
while(1)
{
printf("\n1.Insert n details student ");
printf("\n2.Insert at beginning");
printf("\n3.Insert at last");
printf("\n4.Delete from begining");
printf("\n5.Delete from last");
printf("\n6.Display");
printf("\n7.Exit");
printf("\nEneter your choice : ");
scanf("%d",&ch);
switch(ch)
{
case 1 : printf("\nEnter the value of n ");
scanf("%d",&n);
for(i=0;i<n;i++)
insertatfirst();
break;
case 2 : insertatfirst();
break;
case 3 : insertatlast();
break;
case 4 : deletefront();
break;
case 5 : deleteatend();
break;
case 6 : display();
break;
case 7 : exit(1);
default: printf("\n Wrong Input, try again");
}
}
}
8. Design, Develop and Implement a menu driven Program in C for the following operations
on Doubly Linked List (DLL) of Employee Data with the fields: SSN, Name, Dept,
Designation, Sal, PhNo
a. Create a DLL of N Employees Data by using end insertion.
b. Display the status of DLL and count the number of nodes in it
c. Perform Insertion and Deletion at End of DLL
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
int count=0;
struct node
{
struct node *prev;
int ssn;
char phno[10];
char name[20],dept[20],desg[10];
float sal;
struct node *next;
}*first=NULL,*last=NULL,*temp=NULL,*temp1=NULL;
void create()
{
temp=(struct node *)malloc(sizeof(struct node));
printf("\nEnter the employee details: ssn,name,dept,desg,sal,phno");
scanf("%d%s%s%s%f%s",&temp->ssn,temp->name,temp->dept,temp->desg,&temp->sal,temp->phno);
temp->prev=NULL;
temp->next=NULL;
count++;
}
void deleteatfirst()
{
temp=first;
if(first==NULL)
{
printf("\n DLL is empty");
return;
}
if(temp->next==NULL)
{
printf("\nDeleted node is:");
printf("%d\t%s\t%s\t%s\t%f\t%s",temp->ssn,temp->name,temp->dept,temp->desg,temp->sal,temp->ph
no);
free(temp);
first=NULL;
}
else
{
first=temp->next;
printf("%d\t%s\t%s\t%s\t%f\t%s",temp->ssn,temp->name,temp->dept,temp->desg,temp->sal,temp->ph
no);
free(temp);
first->prev=NULL;
}
count--;
}
void deleteatlast()
{
temp=first;
if(first==NULL) {
printf("\n DLL is empty");
return;
}
if(temp->next==NULL)
{
printf("\nDeleted node is:");
printf("%d\t%s\t%s\t%s\t%f\t%s",temp->ssn,temp->name,temp->dept,temp->desg,temp->sal,temp->ph
no);
free(temp);
first=NULL;
}
else
{
printf("\nThe deleted node is:");
temp1=last->prev;
printf("%d\t%s\t%s\t%s\t%d\t%s",last->ssn,last->name,last->dept,last->desg,last->sal,last->phno);
free(last);
last=temp1;
last->next=NULL;
}
count--;
}
void insertatfirst()
{
create();
if(first==NULL)
{
first=temp;
last=first;
}
else
{
first->prev=temp;
temp->next=first;
first=temp;
}
}
void insertatlast()
{
create();
if(first==NULL)
{
first=temp;
last=first;
}
else
{
last->next=temp;
temp->prev=last;
last=temp;
}
}
void display()
{
if(first==NULL)
{
printf("\nDLL is empty.");
return;
}
else
{
temp=first;
printf("\n DLL is\n");
while(temp!=NULL)
{
printf("%d\t%s\t%s\t%s\t%f\t%s\n",temp->ssn,temp->name,temp->dept,temp->desg,temp->sal,temp->p
hno);
temp=temp->next;
}
printf("\nThe number of nodes in the linked list is %d.",count);
}
}
void main()
{
int ch,i,n;
clrscr();
while(1)
{