0% found this document useful (0 votes)
20 views41 pages

m2&3 Linked List

l

Uploaded by

aloneliya64
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)
20 views41 pages

m2&3 Linked List

l

Uploaded by

aloneliya64
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/ 41

Data structures and Applications [BCS304]

MODULE-2 & MODULE -3 (Complete linked list)


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
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.

VGK Dept of ISE, RNSIT Page 1


Data structures and Applications [BCS304]

• 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.

3.1 LINKED LIST CONCEPTS


A linked list is a linear data structure, in which the elements are not stored at contiguous memory
locations. A linked list allocates space for each data in terms of node as shown in figure 1. Each node
contains a “data” part and a “link” part. For each node, memory is allocated from Heap/Dynamic
memory. Data part stores the value and link part contains address of the next node. The elements in a
linked list are linked using pointers as shown in the below image in the figure 2. Start pointer points to
the first node of the list.
DATA LINK/NEXT

Figure 1: Representation of node

Figure 2: Example of Linked list

Advantages of linked lists: Linked lists have many advantages. Some of the very important advantages
are:
• Linked lists are dynamic data structures. i.e., they can grow or shrink during the execution of a
program.
• Linked lists have efficient memory utilization. Here, memory is not pre-allocated. Memory is
allocated whenever it is required and it is de-allocated (removed) when it is no longer needed.

VGK Dept of ISE, RNSIT Page 2


Data structures and Applications [BCS304]

• Insertion and Deletions are easier and efficient. Linked lists provide flexibility in inserting a data
item at a specified position and deletion of the data item from the given position.
• Many complex applications can be easily carried out with linked lists.

Disadvantages of linked lists:


• It consumes more space because every node requires an additional pointer to store address of the
next node.
• Searching a particular element in list is difficult and also time consuming.

Comparison between array and linked list:

3.2 TYPES OF LINKED LISTS


Basically, there are four types.
1. Single Linked List.
2. Double Linked List.
3. Circular Linked List.
4. Circular Double Linked List.
• A single linked list is one in which all nodes are linked together in some sequential manner. Hence,
it is also called as linear linked list.

VGK Dept of ISE, RNSIT Page 3


Data structures and Applications [BCS304]

• A double linked list is one in which all nodes are linked together by multiple links which helps in
accessing both the successor node (next node) and predecessor node (previous node) from any
arbitrary node within the list. Therefore, each node in a double linked list has two link fields
(pointers) to point to the left node (previous) and the right node (next). This helps to traverse in
forward direction and backward direction.
• 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.3 SINGLE LINKED LIST:


Singly linked lists are the basic type of linked lists where each node has exactly one pointer field. A
singly linked list is comprised of zero/ more number of nodes when the number of nodes is zero, the list
is empty otherwise if the linked list is non-empty, the list is pictorially represented as 1st node links to
2nd node and 2nd node links to 3rd node and so on. the last node has zero link whose value of address is
set to NULL.

REPRESENTING SLL IN C LANGUAGE / MEMORY ALLOCATION


The following features are used to represent SLL. Use the following 3 steps to create a SLL.
1. Define node’s structure
To define a node, self-referential structures are used

2. Create a new node


malloc() or MALLOC macro is used to allocate memory for the defined structures nodes
of the size needed for structure node considered.

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.

VGK Dept of ISE, RNSIT Page 4


Data structures and Applications [BCS304]

struct sll
{
char data[4];
struct sll *link;
};

typedef struct sll node;

This definition will result into a node by name “node” containing character data field of size 4
and a field by name link, which is a pointer variable of type “node”,
Data

node *→ link
Figure 3: Defining a node
2. Create a new empty list

node *start = NULL;

• Here, start is a variable of type pointer i.e. node*, initially making it as NULL and hence, a new
list is created by name start and it is empty,

• To create a new node in list, malloc() function is used.

start = (node*)malloc(sizeof(node));

3. To assign the value to the fields of the node. Here, the operator → is used, which is referred as the
structure member operator.

strcpy(start→ data, ”BAT”);


start→link=NULL;
These statements are represented as below:

start→Data start→link

B A T \0 NULL
start→

Here,
B = start→ data [ 0 ];
A = start→ data [ 1 ];
T = start→ data [ 2 ];
\0 = start→ data [ 3 ];
start → link = NULL;

VGK Dept of ISE, RNSIT Page 5


Data structures and Applications [BCS304]

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.

• Thus, the memory is allocated from 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.

Garbage collection usually takes place in 2 steps:

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

The garbage collection is invisible to the programmer.

LINKED LIST OPERATIONS


The following operations are performed on the linked list

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.

start BAT CAT EAT FAT HAT \0

GAT newnode

VGK Dept of ISE, RNSIT Page 6


Data structures and Applications [BCS304]

Figure 4: Insertion Operation

Here, if we need to insert the data item GAT between FAT and HAT, the following steps are
followed.
• Get a newnode

• Set the data field to GAT

• Set the link field of newnode to point to the node after FAT, which contains HAT

• Set FAT link field to newnode

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.

• Use free() to delete FAT node.

Function to create a two-node SLL to store integer values


node* create2()
{
node *first,*second;
first =(node*) malloc(sizeof(node));
second = (node*)malloc(sizeof(node));
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 start after the node X.
void insert(node *start, node *x)
{
node *temp,*temp1;
temp=(node*)malloc(sizeof(node));
temp→data = 50;
if(start==NULL)
{
temp→ link = NULL;
start=temp;
}
else
{
temp1=start;
while(temp1!=x)
temp1=temp→next;
temp→ link = x→link;
x→link = temp;
}

VGK Dept of ISE, RNSIT Page 7


Data structures and Applications [BCS304]

from main function, call this function as insert( start , x);


50
Node to be inserted

temp

• If it is empty, then will be the first node in SLL first.

start→ 50 \0

• So, here we are passing the address of first, the second argument is the x.

X
start → 10 20 40 70 \0

50
2. LIST DELETION temp

Example deletes X from the list start, where trail is the preceding node of X.
void delete( node *start, node *trail, node *X)
{
if(trail)
trail→link = x→link;
else
start = start→link;
free(x);
}

From main function call this function as below:-

delete (&start, NULL, start);


OR
delete (&start, y, y→link);

• Any node is deleted from a linked list by another function delete.


• Assuming that we have 3 pointers, start which points to the start of the list, x points to the node
that we wish to delete, &trail points to the node that precedes x node

start 10 50 20 \0 first→ 50 20 \0
→ \0

VGK Dept of ISE, RNSIT Page 8


Data structures and Applications [BCS304]

• 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.
y
Start 10 50 20 \0 Start 10 50 \0
→→ \0 →→

• In above example, deletion corresponds to the function call, delete (&start, 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. TRAVESING/PRINTING THE LIST

To print the data fields of the nodes in a list. First print the contents of first’s data field. Then,
replace first with the address in its link field. So, continue printing out the data field and moving to
the next node until end of the list is reached.
void printlist (node *start)
{
node *temp;
printf(“\n The list contains”);
for( temp=start; temp!=NULL; temp=temp→link)
printf(“%4d”, first→data);
}

4. 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.

void search(node *start, int key)


{
int found = 0; node *temp=start;
while( temp!=NULL)
{
if (temp→data != key)
temp=temp→link;
else
{ printf(“Search key found in linked list”);
return;
}

VGK Dept of ISE, RNSIT Page 9


Data structures and Applications [BCS304]

}
printf(“Search key not found in linked list”);
}

Menu driven Program in C for the following operations on Singly Linked List (SLL) of Student
Data with the fields: USN, Name, Programme, 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

struct sll
{
char usn[10], name[20], branch[20];
int sem, pno;
struct sll *next;
};

typedef struct sll node;


node *start = NULL;

node* create()
{
node *new1;
new1 = (node*) malloc(sizeof(node));
printf(" Enter usn, name, branch, sem and pno\n ");
scanf("%s%s%s%d%d",new1->usn,new1->name,new1->branch,&new1->sem,&new1->pno);
new1->next = NULL;
return(new1);
}

void insert_front()
{
node *new1;
new1 = create();
if (start == NULL)
start = new1;
else
{
new1->next = start;
start = new1;
}
}

void create_nnodes()
{
int n, i;
printf("Enter No. of students\n");

VGK Dept of ISE, RNSIT Page 10


Data structures and Applications [BCS304]

scanf("%d",&n);
for(i = 1; i<=n; i++)
insert_front();
}

void insert_rear()
{
node *new1, *temp = start;
new1 = create();
if (start == NULL)
{
start = new1;
return;
}

while ( temp->next != NULL)


temp = temp->next;
temp->next = new1;
}

void delete_front()
{
node *temp = start;
if (start == NULL)
{
printf("List is empty\n");
return;
}
if (start ->next == NULL)
{
printf("Deleted student is = %s",start->usn);
free(temp);
start = NULL;
return;
}
start = start->next;
printf("deleted student is = %s", temp->usn);
free(temp);
}

void delete_rear()
{
node *temp = start , *prev;
if (start == NULL)
{
printf("List is empty\n");
return;
}
if (start ->next == NULL)
{
printf("Deleted student is = %s",start->usn);
free(temp);
start = NULL;

VGK Dept of ISE, RNSIT Page 11


Data structures and Applications [BCS304]

return;
}
while(temp->next != NULL)
{
prev = temp;
temp = temp->next;
}
printf("Deleted student is = %s",temp->usn);
prev->next = NULL;
free(temp);
}

void display()
{
node *temp = start; int ct = 0;

if (start == NULL)
{
printf("List is empty\n");
return;
}
printf("Contents of SLL are \n");
while(temp != NULL)
{
printf(" %s %s %s %d %d \n",temp->usn, temp->name, temp->branch, temp->sem, temp->pno);
temp = temp->next;
ct++;
}

printf("No. of nodes = %d",ct);


}

void main()
{
int ch;

for(;;)
{
printf("\n1.create_nnodes 2.display 3.Insert_rear 4.delete_rear 5.insert_front 6.delete_front 7:
exit\n");
printf("enter your choice\n");
scanf("%d",&ch);
switch(ch)
{
case 1: create_nnodes(); break;
case 2: display(); break;
case 3: insert_rear(); break;
case 4: delete_rear(); break;
case 5: insert_front(); break;
case 6: delete_front(); break;
default: printf("invalid choice\n"); exit(0);
}
}
}

VGK Dept of ISE, RNSIT Page 12


Data structures and Applications [BCS304]

Applications of Linked List:

Build Other ADTs/data structures: Singly Linked List is used to build other ADTs/data structures
such as queues and stacks, which are fundamentals to the field of computer science.

Avoiding Collision in HashMap: To avoid collisions between the data contained in the hash map, we
can use a singly linked list. The idea is to make each cell of hash table point to a linked list of records
that have same hash function value. It is called Separate Chaining.

Functionalities of Photo Gallery Applications: One of the applications of singly linked list is in
applications like a photo viewer, for watching similar photos in a continuous manner in the form of a
slide show.

File Allocation In Operating System: Strategy for file allocation schemes by Operating System.Singly
Linked List can be used to keep track of free space in the secondary disk. All the free spaces can be
linked together.

Advantages of Singly linked list:

1) Insertions and Deletions can be done easily.

2) It does not need movement of elements for insertion and deletion.

3) It space is not wasted as we can get space according to our requirements.

4) Its size is not fixed.


5) It can be extended or reduced according to requirements.

6) Elements may or may not be stored in consecutive memory available ,even then we can store the data
in computer.
Disadvantages of Singly linked list:

1) It requires more space as pointers are also stored with information.

2) Different amount of time is required to access each element.

3) If we have to go to a particular element then we have to go through all those elements that come
before that element.

4) Traversing of the list from last to first in not possible.

5) It is not easy to sort the elements stored in the linear linked list.

VGK Dept of ISE, RNSIT Page 13


Data structures and Applications [BCS304]

DOUBLY LINKED LISTS


• Doubly linked list is a linked data structure that consists of a set of sequentially linked records
called nodes. Each node contains at least three fields: two link fields (references to the previous
and to the next node in the sequence of nodes) and at least one data field. Figure 5 shows the
DLL

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).

struct dll
{ int info;
struct dll *lptr,*rptr;
};

typedef struct dll node;


node *head=NULL;
if ptr points to a node in a DLL, then ptr=ptr→llink→rlink= ptr→rlink→llink;

Operations performed on DLL


1. Insert at rear
void insert_rear()

VGK Dept of ISE, RNSIT Page 14


Data structures and Applications [BCS304]

{
node *new1, *temp = head;
new1 = create();
if (head == NULL)
{
head = new1; return;
}
while ( temp->rptr != NULL)
temp = temp->rptr;
temp->rptr = new1;
new1->lptr = temp;
}

Figure 6: Insertion at rear in DLL

2. Insert at front

Figure 7: Insertion at front in DLL

void insert_front()
{
node *new1;
new1 = create();
if (head == NULL)
head = new1;
else
{
new1->rptr = head;
head->lptr=new1;
head = new1;
}
}
VGK Dept of ISE, RNSIT Page 15
Data structures and Applications [BCS304]

void delete_front()
{
if (start == NULL)
{
printf("List is empty\n");
return;
}
if (start ->rptr == NULL)
{
printf("deleted item = %d",start->info);
free(start);
start = NULL;
return;
}
printf(" deleted item = %d", start->info);
start = start->rptr;
free(start->lptr);
start->lptr = NULL;
}

void delete_rear()
{
node *temp = start;
if (start == NULL)
{
printf("List is empty\n");
return;
}
if (start->rptr == NULL)
{
printf("deleted item = %d",start->info);
free(start);
start = NULL;
return;
}

while(temp->rptr != NULL)
temp = temp->rptr;
(temp->lptr)->rptr = NULL;
printf(" deleted item = %d", temp->info);
free(temp);
}

VGK Dept of ISE, RNSIT Page 16


Data structures and Applications [BCS304]

Advantages Of DLL:
• Reversing the doubly linked list is very easy.
• It can allocate or reallocate memory easily during its execution.
• The traversal of this doubly linked list is bidirectional which is not possible in a singly linked
list.
• Deletion of nodes is easy as compared to a Singly Linked List. A singly linked list deletion
requires a pointer to the node and previous node to be deleted but in the doubly linked list, it only
required the pointer which is to be deleted.

Disadvantages of DLL:
• It uses extra memory when compared to the array and singly linked list.
• Since elements in memory are stored randomly, therefore the elements are accessed sequentially
no direct access is allowed.

Applications of DLL:
• It is used in the navigation systems where front and back navigation is required.
• It is used by the browser to implement backward and forward navigation of visited web pages
that is a back and forward button.
• It is also used to represent a classic game deck of cards.
• It is also used by various applications to implement undo and redo functionality.
• Doubly Linked List is also used in constructing MRU/LRU (Most/least recently used) cache.
• Other data structures like stacks, Hash Tables, Binary trees can also be constructed or
programmed using a doubly-linked list.
• Also in many operating systems, the thread scheduler(the thing that chooses what process needs
to run at which time) maintains a doubly-linked list of all processes running at that time.

VGK Dept of ISE, RNSIT Page 17


Data structures and Applications [BCS304]

/*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
d. Perform Insertion and Deletion at Front of DLL
e. Demonstrate how this DLL can be used as Double Ended Queue.
f. Exit*/

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

struct dll
{
char ssn[10],name[20],dept[10],design[10];
int sal, pno;
struct dll *lptr,*rptr;
};

typedef struct dll node;


node *start = NULL;

node* create()
{
node *new1;
new1 = (node*)malloc(sizeof(node));
printf(" Enter ssn, name,dept,designsal and pno,");
scanf("%s%s%s%s%d%d",new1->ssn,new1->name,new1->dept,new1->design,&new1->sal,&new1-
>pno);
new1->lptr = new1->rptr = NULL;
return(new1);
}

void insert_front()
{
node *new1;
new1 = create();
if (start == NULL)
start = new1;
else
{
new1->rptr = start;
start = new1;
}
}

VGK Dept of ISE, RNSIT Page 18


Data structures and Applications [BCS304]

void insert_rear()
{
node *new1, *temp = start;
new1 = create();
if (start == NULL)
{
start = new1;
return;
}
while ( temp->rptr != NULL)
temp = temp->rptr;
temp->rptr = new1;
new1->lptr = temp;
}
void create_nnodes()
{
int n, i;
printf("Enter No. of Employees\n");
scanf("%d",&n);
for(i = 1; i<=n; i++)
insert_rear();
}

void delete_front()
{
if (start == NULL)
{
printf("List is empty\n");
return;
}

if (start ->rptr == NULL)


{
printf("deleted record with ssn = %s\n",start->ssn);
free(start);
start = NULL;
return;
}
printf("deleted record with ssn = %s\n",start->ssn);
start = start->rptr;
free(start->lptr);
start->lptr = NULL;
}

VGK Dept of ISE, RNSIT Page 19


Data structures and Applications [BCS304]

void delete_rear()
{
node *temp = start;
if (start == NULL)
{
printf("List is empty\n");
return;
}

if (start->rptr == NULL)
{
printf("deleted record with ssn = %s\n",start->ssn);
free(start);
start = NULL;
return;
}

while(temp->rptr != NULL)
temp = temp->rptr;

(temp->lptr)->rptr = NULL;
printf("deleted record with ssn = %s\n",start->ssn);
free(temp);
}

void display()
{
node *temp = start; int ct = 0;
if (start == NULL)
{
printf("List is empty\n");
return;
}
printf("Contents of DLL are \n");
while(temp != NULL)
{
printf(" %s %s %s %s %d %d\n ",temp->ssn, temp->name,temp->dept,temp->design,temp->sal,
temp->pno);
temp = temp->rptr;
ct++;
}
printf("\n no. of nodes = %d",ct);
}

VGK Dept of ISE, RNSIT Page 20


Data structures and Applications [BCS304]

void main()
{
int ch;
for(;;)
{
printf("\n1.insert_rear 2.delete_front 3.Insert_front 4.delete_rear 5.display 6: exit\n");
printf("enter your choice\n");
scanf("%d",&ch);
switch(ch)
{
case 1: create_nnodes();break;
case 2: insert_rear(); break;
case 3: delete_front(); break;
case 4: insert_front(); break;
case 5: delete_rear(); break;
case 6: display (); break;
default :printf("invalid choice\n"); exit(0);
}
}
}

CIRCULAR LINKED LISTS


A linked list whose last node points back to the first node instead of containing a null pointer is
called circular list.
1. Circular singly linked list

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.

2. Circular doubly linked 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

VGK Dept of ISE, RNSIT Page 21


Data structures and Applications [BCS304]

Advantages of CLL
• Linked list made as circular can connect to the first node easily.
• Insertion/deletion operations can be performed quickly.
• Accessing previous node of any node X, can be achieved from X→end of the list and end to that
particular node.
• Circular linked list even can be adapted for DLL, which are doubly linked CLL.

Applications of Circular Linked List

A Circular Linked List can be used for the following –

• Circular lists are used in applications where the entire list is accessed one-by-one in a loop.
• It is also used by the Operating system to share time for different users, generally uses a Round-
Robin time-sharing mechanism.
• Multiplayer games use a circular list to swap between players in a loop.
• Implementation of Advanced data structures like Fibonacci Heap
• The browser cache which allows you to hit the BACK button
• Undo functionality in Photoshop or Word
• Circular linked list used Most recent list (MRU LIST)

Circular Single list using Header nodes:( HEADER LINKED LIST)

A header linked list is a linked list which always contains a special node called the header node
at the beginning of the list. It is an extra node kept at the front of a list. Such a node does not represent
an item in the list. The information portion might be unused.
This header node allows us to perform operations more easily and also differentiates the nodes,
first/last especially when the list is circular. The header node may contain some useful about linked list
such as number of nodes in the list , address of last node/ some specific distinguishing information . the
address of starting node is refereed by header pointer.
Header node is also called dummy node, which is created first and deleted last. If no nodes are
present, then header node is present. Head->data field may be used to count no. of nodes.
There are two types of header list
1. Grounded header list: is a header list where the last node contains the null pointer.

VGK Dept of ISE, RNSIT Page 22


Data structures and Applications [BCS304]

2. Circular header list: is a header list where the last node points back to the header node.

Figure 10: Grounded and Circular header Linked List


Note: Normally Circular header list will be used.
/* C Program to demonstrate operations of Circular linked list with header node*/
/*Header node stores the number of nodes in the list*/

Figure 11: Insertion at front of Circular linked list with header node

/* Implementation of Circular Singly linked list using header nodes */

struct cll
{
int data;
struct cll *next;
};
typedef struct cll node;
node *head=NULL;
node* create()
{
node *new1;
new1=(node*) malloc(sizeof(node));
printf("Enter data to be stored in node\n");

VGK Dept of ISE, RNSIT Page 23


Data structures and Applications [BCS304]

scanf("%d",&new1->data);
new1->next=NULL;
return(new1);
}
void insert_front()
{
node *new1,*temp;
new1=create();
new1->next=head->next;
head->next=new1;
head->data=head->data+1;
}
void delete_front()
{ node *temp;
if(head->next==head)
{ printf("Empty list\n");
return;
}
temp=head->next;
printf("Deleted node data is %d",temp->data);
head->data=head->data-1;
head->next=temp->next;
free(temp);
}

void insert_rear()
{
node *temp,*new1;
new1=create();
if(head->next==head)
{
head->next=new1;
new1->next=head;
head->data=head->data+1;
return;
}
temp=head->next;
while(temp->next!=head)
temp=temp->next;
temp->next=new1;
new1->next=head;
head->data=head->data+1;
}
void delete_rear()
{
node *temp,*prev;
if(head->next==head)
{
printf("Empty list\n");

VGK Dept of ISE, RNSIT Page 24


Data structures and Applications [BCS304]

return;
}
prev=head;
temp=head->next;
while(temp->next!=head)
{
prev=temp;
temp=temp->next;
}
prev->next=head;
printf("Deleted node data is %d",temp->data);
free(temp);
head->data=head->data-1;
}
void display()
{
node *temp=head->next;
if(head->next==head)
{
printf("Empty list\n");
return;
}
while(temp!=head)
{
printf("%d\n",temp->data);
temp=temp->next;
}
printf("No. of nodes in list is %d",head->data);
}

void main()
{
int ch;
head=(node*)malloc(sizeof(node));
head->next=head;
head->data=0;
for(;;)
{
printf("\n1.insert_rear 2.delete_front 3.Insert_front 4.delete_rear 5.display 6: exit\n");
printf("enter your choice\n");
scanf("%d",&ch);
switch(ch)
{
case 1: insert_rear(); break;
case 2: delete_front(); break;
case 3: insert_front(); break;
case 4: delete_rear(); break;
case 5: display(); break;
default :printf("invalid choice\n"); exit(0);}}}

VGK Dept of ISE, RNSIT Page 25


Data structures and Applications [BCS304]

Linked Stacks and Queues: -

• To represent several queues and stacks sequentially, linked list is the efficient way.
• The linked stack and linked queue are pictorially shown below:

Figure 12: (a) Linked Stack and (b) Linked queue


• The directions of arrows in both stack queue representation help us to easily understand the
operations i.e insertion and deletion of nodes. i.e in stack, push/pop operation performed from the
top of the stack.
• In Figure (b) above, in linked queue, node is easily inserted and deleted using rear and front
respectively.
• C declarations to represent ‘n’, number of stacks in memory simultaneously, where
n<= MAX_STACKS.

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.

VGK Dept of ISE, RNSIT Page 26


Data structures and Applications [BCS304]

Operations on Mulitple stacks (Linked stack):-


1) PUSH:-
• The push function creates a new node by name temp & places item in the data field & top in the link
field. The variable top is then changed to point to temp.
void push(int i, Element item)
{
stackPointer temp;
temp = malloc(sizeof(*temp));
temp->data = item;
temp->link = tep[i];
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;

VGK Dept of ISE, RNSIT Page 27


Data structures and Applications [BCS304]

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;
}

APPLICATIONS OF LINKED LISTS

1) Polynomial Addition: -
• For adding 2 polynomials, the following terms are compared and checked starting at the nodes
pointed to by a & b.
o If the exponents are equal – add 2 coefficients and create new term for the result.
Move a & b to point to next nodes.
o If the exponent of the term in a is less than the exponent of current item in b, then,
▪ Create a duplicate term b.
▪ Attach this term to the result called c.
▪ Advance the pointer to the next term only in b.
o If the exponent of the term in a is greater then the exponent of curret item in b, then,
▪ Create a duplicate term a.
▪ Attach this term to the result, called c.
▪ Advance the pointer to next term only in a.
Polynomial is represented as:-
A(x) = am-1 x cm-1 + ... +a0xc0
where, ai are non zero co- efficient and the ci are non negative integer exponents such that cm-1 > cm-2
>...>c1>c0>=0.

C Declaration:-
typedef struct polyNode *polyPointer;

VGK Dept of ISE, RNSIT Page 28


Data structures and Applications [BCS304]

typedef struct
{
int coef;
int expon;
polyPointer link;
}polyNode;
polyPointer a, b;
polyNodes looks as:-
coef expon link

a= 3x14+2x8+1, b = 8x14-3x10+10x6
a 3 14 2 8 1 0

b 8 14 3 10 10 6

Figure 13: Representaion of a & b polynomials.

C Function for polynomial addition is given below:-


polyPointer padd(polyPointer a, polyPointer b)
{ /* return a polynomial which is the sum of a & b */
polyPointer c, rear, temp;
int sum;
MALLOC(rear, sizeof(*rear));
c=rear;
while(a && b)
switch(COMPARE (a->expon, b->expon))
{
case -1:/* a->expon < b->expon */
attach(b->coef, b->expon, & rear);
b=b->link;
break;
case 0: /*a->expon == b->expon */
sum = a->coef + b->coef;
if(sum)
attach(sum, a->expon, & rear);
a=a->link;
b=b->kink;
break;
case 1: /* a -> expon > b->expon */
attach(a->coef, a->expon, & rear);
a=a->link;
}
/* copy rest of the list a and then list b */
for(;a;a->link)
attach(a->coef, a->expon, & rear);
for(;b;b->link)
attach(b->coef, b->expon, & rear);
rear->link = NULL;

VGK Dept of ISE, RNSIT Page 29


Data structures and Applications [BCS304]

/* delete extra initial node */


temp = c;
c=c->link;
free(temp);
return c;
}
• The above function uses streaming process, that moves along the 2 polynomials, either copying
terms directly / adding them to the result.
• Thus, while loop has 3 cases, depending on whether next pair of elements are =, < or >.
• To create a new node and append it to the end of c, the above addition function uses attach().
void attach( float coefficient, int exponent, polyPointer *ptr)
{ /* create a new node with coef = coefficient & expon = exponent, attach is to the node pointed to
by ptr. ptr is updated to point to this new nodes */
polyPointer temp;
MALLOC(temp, sizeof(*temp));
temp->coef = coefficient;
temp->expon = exponent;
(*ptr)->link = temp;
*ptr = temp;
}

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);
}
}

VGK Dept of ISE, RNSIT Page 30


Data structures and Applications [BCS304]

Circular list representation of polynomials: -


• In a linked structure, the link of the last node points to the first node in the list, it is called as circular
list.
• Nodes of a polynomial can be freed efficiently if circular list representation is used.

3 14 2 8 1 0 last

Figure 14: Circular representation of 3x14+2x8+1


• Free nodes that is no longer in use can be reused by maintaining our own list of nodes that have been
freed.
• 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;
}

Erasing Circular list:-


• We can erase circular list in a fixed amount of time independent of the number of nodes in the list
using cerase() function
void cerase(polyPointer *ptr)
{
polyPointer temp;
if(*ptr)
temp=(*ptr)->link;
(*ptr)->link = avail;
avail = temp;
*ptr = NULL;
}

VGK Dept of ISE, RNSIT Page 31


Data structures and Applications [BCS304]

Circular lists with header nodes: -


• In order to handle the zero polynomial, each polynomial with a header node is introduced i.e. each
polynomial zero / non-zero contains 1 additional node.
• The expon & coef fields of this node are irrelavant.

-- --

Figure 15: Zero Polynomial

-- -- 3 14 2 8 1 0

Figure 16: Polynomial 3x14+2x8+1


polyPointer cpadd(polyPointer a, polyPointer b)
{
polyPointer startA, c, lastC;
int sum, done=FALSE;
startA=a;
a=a->link;
b=b->link;
c=getNode();
c->expon = -1, lastC=c;
do
{
switch(COMPARE(a->expon, b->expon))
{
case -1: attach(b->coef, b->expon, &lastC);
b=b->link;
break;
case 0: if(startA == a)
done = TRUE;
else
{
sum=a->coef+b->coef;
if(sum)
attach(sum, a->expon, &lastC);
a=a->link;
b=b->link;
}
break;
case 1: attach(a->coef, a->expon, lastC);
a=a->link;
}
}while(!done);
lastC->link=c;
return c;
}

VGK Dept of ISE, RNSIT Page 32


Data structures and Applications [BCS304]

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.

C declarations to represent sparse matrix using linked list.


#define MAX_SIZE 50
typedef Enum {head,entry} tagfield;
typedef struct matrixNode *matrixpointer;
typedef struct
{
int row;
int col;
int value;
} entryNode;
typedef struct
{
matrix pointer down;
matrix pointer right;
tag field tag;
union
{
matrix pointer next;
entry nodes entry;
}u;
}matrix Node;
matrix pointer hnode[MAX_SIZE];

VGK Dept of ISE, RNSIT Page 33


Data structures and Applications [BCS304]

The figure shows linked representation of sparse matrix for the following sparse matrix shown
below:-
000060
040000
400800
000004
007000

Figure 17:-Linked representation of the sparse matrix

Sparse Matrix Operations:- Input, Output & Erase.


1. Sparse Matrix Input:-
• The first operation is of reading in a sparse matrix and obtaining it’s linked representation. The
first input line consists of the number of rows, number of columns and the number of non zero
terms. This line is followed by numTerms, lines of input, each of which is of the form:- row, col,
value.
• The sample input for sparse matrix is given below:-
next row col value
down right down right

VGK Dept of ISE, RNSIT Page 34


Data structures and Applications [BCS304]

(a) Header Node (b) Element Node


Figure 18:- Node Structure for sparse Matrices

• The function mread first sets up the header nodes & then sets up each row list while
simultaneously building the column lists. The next field of a header node,i,is initially used to
keep track of the last node in column i.
matrixPointer mread(void)
{
/* 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;

VGK Dept of ISE, RNSIT Page 35


Data structures and Applications [BCS304]

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;
}

2. Sparse Matrix Output:-


To print out the contents of a sparse matrix in a form. The function mwrite is written as below:
void mwrite(matrixPointer node)
{
/*print out the matrix in row major form */
int i;
matrixPointer temp, head=node->right;
printf(“numRows=%d, numCols=%d\n”, node->u.entry.row, node->u.entry.col);
for(i=0;i<node->u.entry.row;i++)
{
for(temp=head->right;temp!=head;temp=temp->right)
printf(“%5d %5d %5d\n”, temp->u.entry.row, temp->u.entry.col,
temp->u.entry.value);
head=head->u.next;
}
}

3. Erasing a Sparse Matrix


To return all the nodes of a sparse matrix to system memory, one at a time using free(), is given
below:-
void merase(matrixPointer * node)
{
matrixPointer x,y,head=(*node)->right;
int i;
for(i=0;i<(*node)->u.entry.row;i++)
{
y=head->right;
while(y!=head)
{
x=y;
y=y->right;
free(x);
}
x=head;head=head->u.next;free(x);

VGK Dept of ISE, RNSIT Page 36


Data structures and Applications [BCS304]

}
y=head;
while(y!=*node)
{ x=y;y=y->u.next;free(x); }
}
free(*node);
*node=NULL;
}

VGK Dept of ISE, RNSIT Page 37


Data structures and Applications [BCS304]

/*Design, Develop and Implement a Program in C for the following operationson Singly
Circular Linked List (SCLL) with header nodes
a. Represent and Evaluate a Polynomial P(x,y,z) = 6x2y2z-4yz5+3x3yz+2xy5z-2xyz3
b. Find the sum of two polynomials POLY1(x,y,z) and POLY2(x,y,z) and store the
result in POLYSUM(x,y,z)
Support the program with appropriate functions for each of the above operations */
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

struct poly
{ int cf, px, py, pz, flag;
struct poly *next;
};

typedef struct poly node;

node* getnode()
{ node *new1;
new1 = (node*) malloc(sizeof(node));
new1->next = new1;
return new1;
}

void display(node *head)


{ node *temp = head->next;
if(head->next == head)
{ printf("Polynomial does not exist\n");
return;
}

while(temp != head)
{ printf("\n %d x^%d y^%d z^%d",temp->cf,temp->px,temp->py,temp->pz);
if(temp->next != head)
printf(" + ");
temp=temp->next;
}
printf("\n");
}

VGK Dept of ISE, RNSIT Page 38


Data structures and Applications [BCS304]

node* insert_rear(int f,int x,int y,int z,node *head)


{ node *new1,*temp;
new1 = getnode();
new1->cf = f;
new1->px = x;
new1->py = y;
new1->pz = z;
new1->flag = 0;
temp = head->next;
while(temp->next != head)
{ temp = temp->next;
}
temp->next = new1;
new1->next = head;
return head;
}

node* read_poly(node *head)


{ int px, py, pz, cf, ch;
do
{ printf("\nEnter coeff: ");
scanf("%d",&cf);
printf("\nEnter x, y, z powers(0-indiacate NO term): ");
scanf("%d%d%d",&px,&py,&pz);
head = insert_rear(cf,px,py,pz,head);
printf("\nIf you wish to continue press 1 otherwise 0: ");
scanf("%d",&ch);
} while(ch != 0);
return head;
}

node* add_poly(node *h1, node *h2, node *h3)


{ node *p1,*p2;
p1 = h1->next;

while(p1 != h1)
{ p2 = h2->next;
while(p2 != h2)
{ if( p1->px == p2->px && p1->py == p2->py && p1->pz==p2->pz)
{ h3 = insert_rear(p1->cf + p2->cf, p2->px,p2->py, p2->pz,h3);
p1->flag = 1;
p2->flag = 1;
break;
}
p2 = p2->next;

VGK Dept of ISE, RNSIT Page 39


Data structures and Applications [BCS304]

if ( p1->flag ==0 )
{ h3 = insert_rear(p1->cf, p1->px, p1->py, p1->pz, h3);
}
p1 = p1->next;
}

p2 = h2->next;

while(p2 != h2)
{ if ( p2->flag ==0 )
{
h3 = insert_rear(p2->cf, p2->px,p2->py, p2->pz,h3);
}
p2 = p2->next;
}
return (h3);
}

void evaluate(node *he)


{ node *temp = he;
int x, y, z;
float result = 0.0;
printf("\nEnter x, y, z, terms to evaluate:\n");
scanf("%d%d%d",&x,&y,&z);
temp = temp->next;
while(temp != he)
{ result = result + (temp->cf * pow(x,temp->px) * pow(y,temp->py) * pow(z,temp->pz));
temp = temp->next;
}
printf("\nPolynomial result is: %f", result);
}

void main()
{ node *h1,*h2,*h3,*he;
int ch;
while(1)
{ printf("\n\n1.Evaluate polynomial\n2.Add two polynomials\n3.Exit\n");
printf("Enter your choice: ");
scanf("%d",&ch);
switch(ch)
{ case 1: he = getnode();
printf("\nEnter polynomial to evaluate:\n");
he = read_poly(he);

VGK Dept of ISE, RNSIT Page 40


Data structures and Applications [BCS304]

display(he);
evaluate(he);
free(he);
break;
case 2: h1 = getnode();
h2 = getnode();
h3 = getnode();
printf("\nEnter the first polynomial:");
h1 = read_poly(h1);
printf("\nEnter the second polynomial:");
h2 = read_poly(h2);
h3 = add_poly(h1,h2,h3);
printf("\nFirst polynomial is: ");
display(h1);
printf("\nSecond polynomial is: ");
display(h2);
printf("\nThe sum of 2 polynomials is: ");
display(h3);
break;
case 3: exit(0);
break;
default: printf("\nInvalid entry");
break;
}
}
}

VGK Dept of ISE, RNSIT Page 41

You might also like