CHAPTER2 Link List
CHAPTER2 Link List
8.1 Introduction
In the previous chapters, we have seen various types of linear data structures such as
stacks, queues and their representations and implementations using sequential
allocation technique i.e., using arrays. Let us see, “What are various advantages of
using arrays?” The advantages of using arrays in implementing various data structures
are shown below:
Data accessing is faster: Using arrays, the data can be accessed very efficiently
just by specifying the array name and the corresponding index. For example, we
can access ith item in the array A by specifying A[i]. The time taken to access a[0]
is same as the time taken to access a[10000].
Simple: Arrays are simple to understand and use.
Now, let us see “What are the disadvantages of arrays?” Even though arrays are very
useful in implementing various data structures, there are some disadvantages:
The size of the array is fixed: The size of the array is fixed during compilation
time only.
Insertion and deletion operations involving arrays is tedious job: Consider an
array consisting of 200 elements. If item has to be inserted at 1st position, all 200
elements must be moved to their next immediate positions, making room for the
new item. Then item has to be inserted at the 1st position. Similarly, deleting an
item at a given position consumes time.
The above disadvantages can be overcome using linked lists.
8.2 Linked Lists
Definition: A linked list is a data structure which is collection of zero or more nodes
where each node is connected to one or more nodes. If each node in the list has only
one link, it is called singly linked list. If it has two links one containing the address of
the next node and other link containing the address of the previous node it is called
doubly linked list. Each node in the singly list has two fields namely:
info – This field is used to store the data or information to be manipulated
link – This field contains address of the next node.
The pictorial representation of a singly linked list where each node is connected to the
next node is shown below:
first
20 30 10 60 \0
The above list consists of four nodes with info fields containing the data items 20, 30,
10 and 60.
Note: Given the address of a node, we can easily obtain addresses of subsequent
nodes using link fields. Thus, the adjacency between the nodes is maintained by
means of links.
Analogy: A linked list can be compared to train having zero or more coaches.
The people sitting inside each coach represent the data part of the linked list
The connection between the coaches using iron links represent the address field of
linked list. The link field contains address of the next node.
As we can move from one coach to other coach, we can go from one node to other
node.
As coaches can be attached or detached easily, in linked list also a node can be
inserted or a node can be deleted.
Now, let us see “What are the different types of linked list?” The linked lists are
classified as shown below:
Data Structures using C - 8.3
Definition: A singly linked list is a collection of zero or more nodes where each node
has two or more fields but only one link field which contains address of the next
node. Each node in the list can be accessed using the link field which contains address
of the next node.
For example, a singly linked list consisting of the items 50, 20, 45, 10 and 80 is
shown below:
2004 1020 5012 1008 6016
50 20 45 10 80 \0
info link
Note: The variable first contains address of the first node. The link
first field of the last node contains \0 (NULL) indicating it is the last node.
Note: Observing the addresses of nodes i.e., 2004, 1020, 5012, 1008 and 6016, we
know that they are physically far apart (they are not adjacent. One node starts at
2004, other starts at 1020 and so on). But, using link field we can obtain each node
in the list in the order specified and hence we say they are logically adjacent.
8.4 Linked Lists
The link field of each node contains address of the next node. For example,
consider the second node. The link field of second node contains 5012 which is
address of the next node. It is denoted by an arrow originating at the link field and
ending at next node.
The variable first contains the address of the first node of the list. So, the entire list
can be identified by the name first.
Using the variable first, we can access any node in the list.
The link field of a last node contains \0 (null).
Definition: An empty linked list is a pointer variable which contains NULL (\0). This
indicates that linked list does not exist. For example, an empty list can be written as
shown below:
first \0
The nodes in a linked list are self-referential structures. So, let us see “What are self-
referential structures? How to define a node in C language?”
struct node
{
int info;
struct node *link;
};
Observe from the above structure definition that a node has two fields:
info – It is an integer field which contains the information.
link – It is a pointer field and hence it should contain the address. The link field
contains the address of the next node in the list whose type is same as the link
field.
Now, let us see “How to define a self-referential structure?” The self-referential
structure can be defined as shown below:
Data Structures using C - 8.5
Example 8.1: Structure definition of a node along with declaration
Note: Both the declarations are same, since NODE and struct node * can be
interchangeably used because of above typedef.
8.1.5 Create an empty list
Now, let us see “How to create an empty list?” An empty list is can be created by
assigning NULL to a self-referential structure variable.
For example, consider the following code:
struct node
{
int info;
struct node *link
};
x = (data_type *) malloc(size);
On successful allocation, the function returns the address of first byte of allocated
memory. Since address is returned, the return type is a void pointer. By type
casting appropriately we can use it to point to any desired data type.
It x is not NULL it means, a node is successfully created and we can return the node
using the statement:
return x;
Example 8.2: C Function to get a new node from the availability list
NODE getnode()
{
NODE x;
Data Structures using C - 8.7
x = ( NODE ) malloc(sizeof(struct node)); /* allocate the memory space */
Note: The return type of getnode() is NODE and it is defined in previous section.
Step 1: get a node: A node which is identified by variable first with two fields: info
and link fields can be created using getnode() function (described in previous section)
as shown below:
first
*first
first = getnode();
info link
Note: Observe from the above figure that:
Using the variable first we can access the address of the node
Using *first we can access entire contents of node
Using (*first).info or first->info, we can access the data stored in info field
Using (*first).link or first->link, we can access the link field.
Step 2: Store the item: The data item 10 can be stored in the info field using the
following statement:
first
*first
first->info = 10;
or 10
(*first).info = 10; info link
After executing the above statement, the data item 10 is stored in info field of first as
shown in above figure.
8.8 Linked Lists
Step 3: Store NULL character: After creating the above node, if we do not want link
field to contain address of any other node, we can store ‘\0’ (NULL) in link field as
shown below:
first->link = NULL; first
*first
or
(*first).link = NULL; 10 \0
info link
Thus, using above three steps we can create a node with specified data item as
shown in above figure.
In this section, let us see “How to insert a node at the front end of the list?”
Data Structures using C - 8.9
Design: To design the function easily, let us consider a linked list with 4 nodes. Here,
pointer variable first contains address of the first node of the list as shown below:
first
20 30 10 60 \0
Let us try to insert the item 50 at the front end of the above list. The sequence of steps
to be followed are shown below:
1 temp = getnode()
Step 2: Copy the item 50 into info field of temp using the following statement:
2 temp->info = item;
temp first
2 50 20 30 10 60 \0
Step 3: Copy address of the first node of the list stored in pointer variable first into
link field of temp using the statement:
3 temp->link = first;
Step 4: Now, a node temp has been inserted and observe from the figure that temp is
the first node. Let us always return address of the first node using the statement:
4 return temp;
The complete function is shown below:
Example 8.3: C Function to insert an item at the front end of the list
The above function should be called in the calling function as shown below:
After executing the above statement, the variable first in the calling function contains
address of the first of the list as shown below:
first first
50 20 30 10 60 \0
The variable first shown using dotted lines contains the address of the first node of the
list before insertion whereas the variable first shown using thick lines contains the
address of the first node of the list after insertion.
Thus, if the function insert_front() is called n times, we have a list with n nodes.
Note: Thus, repeatedly inserting an element at the front end of the list we can create a
linked list.
Consider the following singly linked list where the variable first contains address of
the first node of the list.
first
1004 1008 1048 1026
20 30 10 60 \0
We need to find the address of the last node. For this to happen, we have to start from
the first node. Instead of updating first, let us use another variable say cur. To start
with, the variable cur should contain the address of the first node. This is achieved
using the statement:
cur = first;
8.12 Linked Lists
first
1004 1008 1048 1026
20 30 10 60 \0
cur link
Note: What is first->info and cur->info? It is 20. What is first->link and cur->link? It
is 1008 (which is the address of the next node)
Let us update cur so that it contains address of the next node. This can be done by
copying cur->link (i.e, 1008) to cur using the following code:
cur = cur->link;
After executing the above instruction, cur contains address of the next node as shown
below:
first
1004 1008 1048 1026
20 30 10 60 \0
cur
If we execute the instruction “cur = cur->link” again, cur contains address of the next
node as shown below:
first
1004 1008 1048 1026
20 30 10 60 \0
cur
If we execute the instruction “cur = cur->link” again, cur contains address of the next
node as shown below:
first
1004 1008 1048 1026
20 30 10 60 \0
cur
Note: Observe that, now the variable cur contains address of the last node of the list.
Data Structures using C - 8.13
Now the question is “When we say that given node is the last node of the list?” If link
field of a node contains NULL, then that node is the last node of that list. In the above
list, cur->link is NULL. So, cur is the last node of the above list.
So, if cur contains the address of the first node, keep updating cur as long as link field
of cur is not NULL as shown in figure below:
while ( cur->link != NULL)
{
cur = cur->link; cur = cur->link
}
Now, given the variable first which contains address of the first node, we can find
address of the last node as shown below:
8.2.4 How to find last node and last but one in the list
Consider the following list:
first
1004 1008 1048 1026
20 30 10 60 \0
prev \0 cur
If cur contains address of the first node of the list, what is the previous node? The
previous node does not exit and so we say prev is NULL. The code for the above
situation can be written as shown below:
prev = NULL;
cur = first;
Now, we know how to update cur to get the address of the last node. The code for this
can be written as shown below: (see previous section)
8.14 Linked Lists
Now, before updating cur inside the loop using “cur = cur->link”, let us copy cur to
prev. The above code can be modifies as shown below:
After the loop, the variable cur contains address of the last node and the variable prev
contains address of the prev node. Now, the complete code to find the address of the
last node and last but one node is shown below:
The given linked list after executing the above code can be written as shown below:
first
1004 1008 1048 1026
20 30 10 60 \0
prev cur
Note: The variable first contains address of the first node, the variable cur contains
address of the last node, the variable prev contains address of last but one node.
Case 1: List is empty: If the list is empty, it is not possible to display the contents of
the list. The code for this can be written as shown below:
if (first == NULL)
{
printf(“List is empty\n”);
return;
}
Case 2: List is exiting: Consider the linked list shown below with four nodes where
the variable first contains address of the first node of the list.
first
1004 1008 1048 1026
20 30 10 60 \0
Initialization: Use another variable say cur to point to the beginning of the list. This
can be done by copying first to cur as shown below:
cur = first;
first
1004 1008 1048 1026
20 30 10 60 \0
cur
Display: Now, display info field of cur node and update cur as shown below:
first
1004 1008 1048 1026
20 30 10 60 \0
cur
Now, display info field of cur node and update cur as shown below:
first
1004 1008 1048 1026
20 30 10 60 \0
cur
Now, display info field of cur node and update cur as shown below:
first
1004 1008 1048 1026
20 30 10 60 \0
cur
Now, display info field of cur node and update cur as shown below:
Finally, observe that cur is NULL indicating no more nodes are there to display.
Observe that the following statements are repeatedly executed:
printf(“%d “, cur->info);
cur = cur->link;
Data Structures using C - 8.17
as long as cur is not NULL. Once cur is NULL, the displaying of all the nodes is
over. The code for this can be written as shown below:
Now, the complete C function to display the contents of the list is shown below:
Now, let us see “How to delete a node from the front end of the list?”
Design: A node from the front end of the list can be deleted by considering various
cases as shown below:
8.18 Linked Lists
Case 1: List is empty: If the list is empty, it is not possible to delete a node from the
list. In such case, we display “List is empty” and return NULL. The code for this can
be written as shown below:
if (first == NULL)
{
printf (“List is empty\n”);
return NULL;
}
Case 2: List is exiting: Consider the list with five nodes where the variable first
contains address of the first node of the list.
first
50 20 45 10 80 \0
Given the address of the first node of the list, we need to know the address of the
second node of the list. This is because, after deleting the first node, the second node
will be the first node of the list. The sequences of steps to be followed while deleting
an element are shown below:
Step 1: Use a pointer variable temp and store the address of the first node of the list as
shown in figure below. This is achieved using the following statement:
1 temp = first;
Now, the list can be written as shown below where temp and first points to first node.
first temp
1
50 20 45 10 80 \0
Step 2: Update the pointer temp so that the variable temp contains address of the
second node. This is achieved using the statement:
2 temp = temp->link;
Now, the list can be written as shown below where temp points to second node.
Data Structures using C - 8.19
first temp
50 20 45 10 80 \0
Step 3: Note that variable first points to first node of the list and temp points to the
second node of the list. Now, display info field of the node first node to be deleted
and de-allocate the memory as shown below:
50 20 45 10 80 \0
3
Step 4: Once the node first is deleted, observe that node temp is the first node (see
above list). So, return temp as the first node to the calling function using the
statement:
return temp;
Now, the complete algorithm in C can be written as shown below:
Example 8.5: C function to delete an item from the front end of the list
NODE delete_front(NODE first)
{
NODE temp;
if ( first == NULL ) /* Check for empty list */
{
printf("List is empty cannot delete\n");
return NULL; // We can replace NULL with first also
}
temp = first; /* Retain address of the node to be deleted */
8.20 Linked Lists
50 50 \0
info link info link info link
Step 2: If list is empty, the above node can be returned as the first node of the list.
This can be done using the statement:
if (first == NULL) return temp;
Step 3: If the list is existing, we have to insert temp at the end of the list
first temp
20 30 10 60 \0 50 \0
Existing list Node to be inserted
To insert at the end, we have to find address of the last node. The code to find the
address of the last node can be written (for details see section 8.2.3) as shown below:
Data Structures using C - 8.21
/* Find the address of the last node */
cur = first;
while (cur->link != NULL)
{
cur = cur->link;
}
The pictorial representation of the list after executing the above code can be written as
shown below:
20 30 10 60 \0 50 \0
Step 4: Insert node at the end: Looking at the above list, we can easily insert temp
at the end of cur. This is achieved by copying temp to cur->link as shown below:
cur->link = temp; 1
The list obtained after executing the above code can be written as shown below:
Step 5: Observe from the above list that first contains address of the first node of the
list. So, we return first
return first; 2
Now, the complete list after inserting at the rear end is shown below:
first 2
20 30 10 60 50 \0
8.22 Linked Lists
The complete C function to insert an item at the rear end of the list is below:
Example 8.6: Function to insert an item at the rear end of the list
NODE insert_rear(int item, NODE first)
{
NODE temp; /* Points to newly created node */
NODE cur; /* To hold the address of the last node */
Now, let us see “How to delete a node from the rear end of the list?”
Design: A node from the rear end of the list can be deleted by considering various
cases as shown below:
Case 1: List is empty: If the list is empty, it is not possible to delete the contents of
the list. In such case we display appropriate message and return. The code for this can
be written as shown below:
Data Structures using C - 8.23
if (first == NULL)
{
printf(“List is empty\n”);
return NULL;
}
Case 2: List contains only one node: Consider a list with single node shown in
figure below:
first \0 first
empty list
10 \0
Before deleting After deleting
Note: If link field of first contains NULL, it indicates that there is only one node.
If only one node is present, it can be deleted using free() function. Then, we return
NULL indicating list is empty. The code for this case is shown below.
first
50 20 30 10 60 \0
Step 1: To delete the last node, we should know the address of the last node and last
but one node. For this reason, we use two pointer variables: cur and prev. Initially,
cur points to the first node and prev points to \0 (null). This is achieved using the
following statements:
prev = NULL;
cur = first;
8.24 Linked Lists
first cur
\0 50 20 30 10 60 \0
prev
Step 2: Now, update cur and prev so that cur contains address of the last node and
prev contains address of the last but one node. This can be achieved by using the
following statements (see section 8.2.4 for detailed explanation).
After executing the above loop, the variable cur contains address of the last node and
prev contains address of last but one node as shown in figure below:
Step 3: To delete the last node pointed to by cur, the function free() is used as shown
below:
printf(“Item deleted = %d\n”, cur->info); // Item deleted = 60
3
free(cur);
After executing the above statements, the last node is deleted and the list is shown
below:
Step 4: Once the last node is deleted (the node shown using cross symbol in above
figure), the node pointed to by prev should be the last node. This is achieved by
copying NULL to link field of prev as shown below:
4 prev->link = NULL; /* Node pointed to by prev is the last node */
Data Structures using C - 8.25
After executing the above statement, the list shown in previous step can be written as
shown below:
first prev
50 20 30 10 \0
4
Step 5: Finally return address of the first node.
Now, the linked list as seen from the calling function is shown below:
5 first
50 20 30 10 \0
The complete C function to delete a node from the rear end of the list is shown below:
Example 8.7: Function to delete an item from the rear end of the list
/* Obtain address of the last node and just previous to that */ Case 3
prev = NULL;
cur = first;
while( cur->link != NULL )
{
prev = cur;
cur = cur->link;
}
printf(“The item deleted is %d\n”,cur->info);
free(cur); /* delete the last node */
prev->link = NULL; /* Make last but one node as the last node */
return first; /* return address of the first node */
}
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
struct node
{
int info;
struct node *link;
};
Data Structures using C - 8.27
typedef struct node* NODE;
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.3: Function to insert an item at the front end of the list*/
/* Include: Example 8.4: Function to display the contents of the list */
/* Include: Example 8.5: Function to delete an item from the front end of the list */
void main()
{
NODE first;
int choice, item;
first = NULL;
for (;;)
{
printf("1:Insert_Front 2:Delete_Front\n");
printf("3:Display 4:Exit\n");
printf("Enter the choice\n");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the item to be inserted\n");
scanf("%d", &item);
first = insert_front (item, first);
break;
case 2:
first = delete_front(first);
break;
case 3:
display(first);
break;
default:
exit(0);
}
}
}
8.28 Linked Lists
Note: In the function main(), we can use insert_rear() and delete_rear() functions and
still implement stack operations using linked list.
We know that queue is a special type of data structure where elements are inserted at
one end and elements are deleted at the other end. It is a FIFO data structure as we
have already seen in previous chapter. That is, if an element is inserted at front end,
an element has to be deleted from rear end. If an element is inserted at rear end, an
element has to be deleted from the front end. Thus, a queue can be implemented
using the following functions:
insert_front()
insert_rear()
delete_rear() OR
delete_front()
display()
display()
The C program to implement queues using singly linked list with the help of
insert_rear(), delete_front() and display() functions is below:
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
struct node
{
int info;
struct node *link;
};
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.4: Function to display the contents of the list */
/* Include: Example 8.5: Function to delete an item from the front end of the list */
/* Include: Example 8.6: Function to insert an item at the rear end of the list*/
void main()
{
NODE first;
int choice, item;
Data Structures using C - 8.29
first = NULL;
for (;;)
{
printf("1:Insert_Front 2:Delete_Front\n");
printf("3:Display 4:Exit\n");
printf("Enter the choice\n");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the item to be inserted\n");
scanf("%d", &item);
first = insert_rear (item, first);
break;
case 2:
first = delete_front(first);
break;
case 3:
display(first);
break;
default:
exit(0);
}
}
}
Note: In the above function main(), we can use insert_front() and delete_rear()
functions and still implement queue operations using linked list.
Note: Let us see “What is enqueuer operation? What is dequeuer operation?”
Inserting an element into queue is called enqueue operation and deleting an element
from queue is called dequeue operation. But, there is a difference between dequeue
operation and dequeue. Simply dequeue means is a double ended queue.
8.5 Double ended queue using linked lists
We know that double ended queue is a special type of data structure where elements
can be inserted either from front end or rear end and elements can be deleted from
front end and rear end. That is, insertions and deletions are possible from both ends.
8.30 Linked Lists
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *link;
};
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.3: Function to insert an item at the front end of the list*/
/* Include: Example 8.4: Function to display the contents of the list */
/* Include: Example 8.5: Function to delete an item from the front end of the list */
/* Include: Example 8.6: Function to insert an item at the rear end of the list*/
/* Include: Example 8.7: Function to delete an item from the rear end of the list*/
void main()
{
NODE first;
int choice, item;
first = NULL;
for (;;)
{
printf("1:Insert_Front 2:Insert_Rear\n");
printf(“3:Delete_Front 4:Delete_Rear\n”);
printf("5:Display 6:Exit\n");
printf("Enter the choice\n");
scanf("%d", &choice);
Data Structures using C - 8.31
switch(choice)
{
case 1:
printf("Enter the item to be inserted\n");
scanf("%d", &item);
first = insert_front (item, first);
break;
case 2:
printf("Enter the item to be inserted\n");
scanf("%d", &item);
first = insert_rear (item, first);
break;
case 3:
first = delete_front(first);
break;
case 4:
first = delete_rear(first);
break;
case 5:
display(first);
break;
default:
exit(0);
}
}
}
Now, let us see “How to find the length of linked list or number of nodes present in
the linked list?” The solution is very simple and straight forward technique. Now, tell
me what the following code does?
8.32 Linked Lists
cur = first;
while (cur != NULL) /* As long as no end of list */
{
printf(“%d\n”, cur->info); /* Display the info of a node */
cur = cur->link; /* point cur to the next node */
}
The above code displays the info field of each node in the list. But, we are supposed
to find the number of nodes in the list. This can be achieved very easily by replacing
printf statement by count++ and initialize count to 0 before the loop. Now, the
complete function can be written as shown below:
When control comes out of the loop, if cur is still NULL then key not found.
Otherwise, key found. The partial code to check for an item in the list can be written
as shown below:
cur = first;
while (cur != NULL) /* As long as no end of list */
{
if (key == cur->info) break; /* key found */
cur = cur->link; /* point cur to the next node */
}
if (cur == NULL) /* If end of list, key not found */
{
printf(“Search is unsuccessful\n”);
return;
}
printf(“Serach is successful\n”); /* Yes, key found */
If item not found, instead of displaying the message “Item not found” return
NULL.
Now, let us see “How to delete a node whose info field is specified?”
Design: To design the function easily, let us follow the sequence of steps shown
below:
Step 1: Check for empty list. The equivalent code can be written as shown below:
if (first == NULL)
{
printf(“List empty, Search fails\n”);
return NULL;
}
Step 2: Check for key in the first node in the list. If key matches with the first node of
the list, the node at the front end of the list has to be deleted as shown below:
first
key = 50 50 20 30 10 60 \0
Now, save the address of first node into cur using the statement:
cur = first; 1
and update first to point to the next node using the statement:
2 first
50 20 30 10 60 \0
1
cur
8.36 Linked Lists
Now, delete the first node pointed to by cur. This can be done using the statement:
free (cur); 3
return first; 4
After executing the above two statements, the list can be pictorially represented as
shown below:
4 first
50 20 30 10 60 \0
3
cur
Thus, if key matches with first node of the list, the first node can be deleted and the
corresponding code can be written as shown below:
if ( key == first->info )
{
cur = first; /* Save the address of the first node */
first = first->link; /* Point first to second node in the list */
free(cur); /* Delete the first node */
return first; /* Return second node as the first node */
}
Step 3: Search for the key: Control comes to step 3, if key is not present in the first
node of the list. It may be present or may not be present in subsequent nodes. So, we
have to search for key in the list. The search code given in previous section is repeated
for convenience.
cur = first;
while (cur != NULL) /* As long as no end of list */
{
if (key == cur->info) break; /* If found go out of the loop */
prev = cur; /* Save the address of cur node */
cur = cur->link; /* point cur to the next node */
}
Data Structures using C - 8.37
if (cur == NULL) /* If end of list, key not found */
{
printf(“Search is unsuccessful\n”);
return first;
}
printf(“Serach is successful\n”); /* Yes, key found */
Note: Observe that the statement:
prev = cur;
is added inside the while loop, just before updating cur to the next node. This is
necessary to delete the cur node.
Now, if 10 is the item to be deleted, after executing the above statements, we get the
message “Search is successful” and at this instant, the linked list looks as shown
below:
Observe that cur contains address of the node to be deleted and prev contains address
of predecessor of the node to be deleted.
Step 4: Delete the node: Before deleting the cur node we need to adjust the pointers.
That is, copy “cur->link” to “prev->link” as shown below:
prev->link = cur->link; 5
8.38 Linked Lists
After executing the above statement, prev->link points to node containing 60 and
thus, cur node is isolated from the list and the linked list can be pictorially represented
as shown below:
Now, the node cur can be removed using free() function as shown below:
free (cur); 6
Step 5: Finally return the address of the first node. The code for this is shown below.
return first; 7
Definition: Concatenation of two lists is nothing but joining the second list at the end
of the first list.
Design: Concatenation of two lists is possible if two lists exist. If one of the lists is
empty, return the address of the first node of the non-empty list as shown below:
Once, control comes out of second if-statement it means both lists are existing. The
pictorial representation of both lists are shown below:
first second
50 20 30 10 \0 50 20 \0
If both lists exist, obtain the address of the last node of the first list. The code to
obtain address of the last node of the first list is shown below:
cur = first;
while (cur->link != NULL) /*Traverse till the end */
cur = cur->link;
Once control comes out of the loop, pointer cur contains address of the last node of
the first list (see the figure below).
Now, attach address of the first node of the second list identified by second to cur
node using the following code:
cur->link = second;
The resulting list after executing the above statement is shown below:
Now, first contains the address of the first node of the concatenated list and return this
node to the calling function using the statement:
return first;
Data Structures using C - 8.41
The corresponding C function is shown below:
cur->link = sec; /* Attach first node of second list to end of first list */
return first; /* Return the first node of the concatenated list */
}
first
10 20 30 40 50 \0
If we display the above list, the output is: 10 20 30 40 50. After reversing the list, the
list is shown below:
first
10 \0 20 30 40 50
Design: Assume that the given list is divided into two sub lists such that the first list
with two nodes is reversed and the second list with three nodes is yet to be reversed as
shown below:
cur first
10 \0 20 30 40 50 \0
With this situation in mind, let us try to reverse the list to be processed.
Step 1: Obtain the address of the second node of the list to be reversed. This can be
achieved using:
temp = first->link;
After executing the above statement, the list can be written as shown below:
10 \0 20 30 40 50 \0
Step 2: Attach the first node of the list to be reversed, to the front end of the partially
reversed list. This can be achieved using:
first->link = cur;
After executing the above statement, the list can be written as shown below:
cur first temp
10 \0 20 30 40 50 \0
Data Structures using C - 8.43
Step 3: The pointer variable cur always should contain address of the first node of the
reversed list and first should contain address of first node of the list to be reversed.
This can be achieved using the following statements:
cur = first;
first = temp;
After executing the above statement, the list can be written as shown below:
cur first
10 \0 20 30 40 50 \0
The complete C function to insert an item into an ordered linked list is below:
Definition: A linked list in which the items are stored in some specific order is an
ordered linked list. The elements in an ordered linked list can be in ascending or
descending order or based on key information. A key is one or more fields within a
structure that are used to identify the data. For example, an ordered linked list shown
below:
first
10 20 30 40 \0
first
10 20 30 40 \0
Here, the variable first contains address of the first node of the list.
Data Structures using C - 8.45
After inserting any item into the above list, the order of list should be maintained i.e.,
the items in the list should be arranged in ascending/descending order only. We
should see that the variable first always contains the address of the first node of the
list. To insert an item into the list, the sequence of steps to be followed are:
Step 1: Create a node to be inserted and insert the item using the following
statements:
temp = getnode();
temp->info = item;
temp->link = NULL;
Step 2: If the node temp is inserted into the list for the first time (i.e., into the empty
llist), then return temp itself as the first node using the following code.
if (first == NULL) return temp;
When control comes out of the above if statement, it means that the list is already
existing and node temp has to be inserted at the appropriate place so that after
inserting temp, the list must be arranged in ascending order. This results in following
two cases: item has to be inserted at the front end or in the middle.
Step 3: Inserting an item at the front end of the list: This case occurs, when the node
to be inserted is less than the first node of the list as shown below:
temp first
5 \0 10 20 30 40 \0
item = 5
Suppose, item is 5. Can you tell me where it has to be inserted? It has to be inserted at
the front end of the list so that the list is arranged in ascending order. This can be
done by copying first into link field of temp as shown below:
temp->link = first.
5 10 20 30 40 \0
8.46 Linked Lists
After inserting as shown in figure, we return temp since temp is the new first node of
the list as shown below:
return temp;
The above two statement should be executed if and only if item is less than the first
node of the list. Now, the code can be written as shown below:
Step 4: Inserting somewhere in the middle of the list: Suppose item 35 has to be
inserted into the list shown below:
first
item = 35 10 20 30 40 \0
5 \0
temp
To create an ordered list, node temp has to be inserted in between 30 and 40. So, let
us find the appropriate place so that the list remains in order. The code to find the
appropriate place can be written as shown below:
prev = NULL;
cur = first;
while (cur != NULL && item > cur->info)
{
prev = cur;
cur = cur=>link
}
Data Structures using C - 8.47
Now, after executing the above code, the linked list can be written as shown below:
5 \0
temp
Step 5: Insert at middle/end: By looking at the above list, observe that temp has to
be inserted between prev and cur. The corresponding code is shown below:
After executing the above statements, the linked list can be written as shown below:
temp
Step 6: Always we return the address of the first node as shown below:
Now, the complete function to create an ordered linked list can be written as shown
below:
struct node
{
int info;
struct node *link;
};
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.3: Function to insert an item at the front end of the list*/
/* Include: Example 8.4: Function to display the contents of the list */
/* Include: Example 8.11: Function to find the length of the linked list */
/* Include: Example 8.12: Function to search for key item in the list */
/* Include: Example 8.14: Function to delete a node whose info field is specified */
/* Include: Example 8.16: Function to reverse a list */
void main()
{
NODE first;
int choice, item, key;
first = NULL;
for (;;)
{
printf("1:Insert_Front 2:Length of list\n");
printf(“3:Serach 4:Delete item\n”);
printf("5:Reverse 6:Display\n");
printf(“7: Exit\n”);
printf("Enter the choice\n");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the item to be inserted\n");
scanf("%d", &item);
first = insert_front (item, first);
break;
8.50 Linked Lists
case 2:
printf("Length of list = %d\n”, Length(first));
break;
case 3:
printf(“Enter the item to be searched\n”);
scanf(“%d”, &key);
search(key, first);
break;
case 4:
printf(“Enter the item to be deleted\n”);
scanf(“%d”, &key);
first = delete_info(key, first);
break;
case 5:
first = reverse(first);
break;
case 6:
display(first);
break;
default:
exit(0);
}
}
}
Definition: A header node in a linked list is a special node whose link field always
contains address of the first node of the list. Using header node, any node in the list
can be accessed. The info field of header node usually does not contain any
information and such a node does not represent an item in the list. Sometimes, useful
information such as, number of nodes in the list can be stored in the info field. If the
list is empty, then link field of header node contains \0 (null).
Data Structures using C - 8.51
Example 1: An empty list using header is represented as shown below:
Head
\0
If we display the above list, list is empty.
Example 2: The non-empty list using header node is represented as shown below:
Head
20 30 10 40 50 \0
Example 3: The non-empty list using header node with valid information in header
node is represented as shown below:
Head
5 20 30 10 40 50 \0
In the above list, the info field of the header node contains the number of nodes in the
list.
Now, let us see “What are the advantages of a list with a header node?” The
advantages of a header node are shown below:
Simplifies Insertion and deletion operations
Avoid the usage of various cases such as “if only one node is present what to do”
Designing of program will be very simple
Circular lists with header node are frequently used instead of ordinary linked lists
because many operations can be easily implemented
8.52 Linked Lists
20 30 10 40 \0
An item 50 can be inserted at the front end of the list using the following sequence of
steps:
Step 1: Create a node: This can be done by using getnode() function and copying item
into the info field as shown below:
temp = getnode()
1
temp->info = item;
The list after executing above statements can be written as shown below:
temp
1
Head 50
20 30 10 40 \0
Step 2: Obtain the address of the first node: The first node can be accessed using
“head->link” and copy this into first as shown below:
2 first = head->link;
Now, the variable first contains address of the first node and the linked list can be
written as shown below:
temp
Head 50 first
2
20 30 10 40 \0
Data Structures using C - 8.53
Step 3: Make the new node created as the first node: This can be done by inserting
the node temp between head and first. This can be achieved using the following code:
3 head->link = temp;
4 temp->link = first;
The list obtained after executing the above statements can be written as shown below:
temp
Head 50 first
3 4
20 30 10 40 \0
Step 4: Finally return the address of the header node using the following statement:
return head;
The list as seen from the calling function can be written as shown below:
Head
50 20 30 10 40 \0
4 temp->link = first;
return head; /* Return the header node */
}
8.54 Linked Lists
Now, let us see “How to insert an item at the rear end?” Consider the circular list
with a header node shown in figure below.
Head
20 30 10 40 \0
An item 50 can be inserted at the rear end of the list using the following sequence of
steps:
Step 1: Create a node: This can be done by using getnode() function and copying item
into the info field as shown below:
temp = getnode()
1 temp->info = item;
temp->link = NULL
The list after executing above statements can be written as shown below:
Head temp
1
20 30 10 40 \0 50 \0
Step 2: Obtain the address of the first node: The first node can be accessed using
“head->link” and copy this into cur as shown below:
2 cur = head->link;
Now, the variable cur contains address of the first node and the linked list can be
written as shown below:
Head cur temp
2
20 30 10 40 \0 50 \0
Data Structures using C - 8.55
Step 4: Obtain the address of the last node: This can be done by updating cur
repeatedly to contain address of the next node till cur->link is not NULL. This can be
achieved using the following code:
Once control comes out of the loop, the variable cur contains address of the last node.
Now, the linked list obtained can be written as shown below:
Head cur temp
3
20 30 10 40 \0 50 \0
Step 4: Make the new node created as the last node: This can be done by inserting the
node temp after cur. This can be done by copying temp to link field of cur node as
shown below:
4 cur->link = temp;
The list obtained after executing the above statements can be written as shown below:
Step 4: Finally return the address of the header node using the following statement:
return head;
The list as seen from the calling function can be written as shown below:
Head
20 30 10 40 50 \0
Now, the complete code to insert an element at the rear end of the list can be written
as shown below:
8.56 Linked Lists
return head;
}
if (head->link == NULL)
{
1 printf(“List is empty\n”);
return head;
}
When control comes out of the above if-statement, it means list is already existing
and it can be pictorially represented as shown below:
Data Structures using C - 8.57
Head
20 30 10 40 50 \0
Step 2: Get the address of the first node and its previous:
The link field of node head is the address of the first node and head is the previous
node. The first node and its predecessor can be obtained using the following
statements:
prev = head; // Previous to first node
2
cur = head->link; // Obtain the first node
After executing the above statements, the linked list looks as shown below:
20 30 10 40 50 \0
Step 3: Get the address of last node and its previous node: Keep updating prev and
cur as long as link field of cur is not NULL. The code corresponding to this can be
written as shown below:
After executing the above part of the code, the linked list can be written as shown
below:
20 30 10 40 50 \0
8.58 Linked Lists
Step 4: Make last but one node as the last node: This is achieved by copying NULL
to link field of prev node. This can be done using the statement:
4 prev->link = NULL;
After executing the above statement, the last node cur is isolated and the linked list
looks as shown below:
20 30 10 40 \0 50 \0
4
Note that prev is the last node of the above list.
Step 5: Delete the last node: First, display the info field of last node and then delete it.
This can be done using the statement:
After executing the above statements, the linked list looks as shown below:
20 30 10 40 \0 50 \0
Step 6: Return the header node: This can be done using the statement:
return head;
The final list as seen from the calling function is shown below:
Head
20 30 10 40 \0
Thus, the last node of the list can be removed. The code to delete an element from the
rear end can be written as shown below:
Data Structures using C - 8.59
Example 8.21: Function to delete an element from the rear end
if (head->link == NULL)
{
printf(“List is empty\n”);
1
return head;
}
while (cur->link != NULL) // Obtain address of last node and last but one */
{
3 prev = cur;
cur = cur->link;
}
4 prev->link = NULL; // Make last but one node as the last node
return head;
}
Step 1: Check for an empty list: An empty list is pictorially represented as shown
below:
Head
1
\0
The code for the above case can be written as shown below:
8.60 Linked Lists
if (head->link == NULL)
{
printf(“List is empty\n”);
1
return head;
}
When control comes out of the above if-statement, it means list is already existing
and it can be pictorially represented as shown below:
Head
20 30 10 40 50 \0
Step 2: Get the address of the first node: The link field of node head is the address of
the first node and it can be obtained using the following statement:
Head first
2
20 30 10 40 50 \0
Step 3: Get the address of the second node: The link field of node first is the address
of the second node and it can be obtained using the following statement:
After executing the above instruction, the linked list looks as shown below:
20 30 10 40 50 \0
Step 5: Make second node as the first node: This can be done by copying second into
link field of head using the statement:
Data Structures using C - 8.61
20 30 10 40 50 \0
4
Step 6: Remove the first node: The node first can be removed using the following
code:
printf(“Item deleted = %d\n”, first->info); // Item deleted = 20
5 free(first);
After executing the above instruction, the linked list looks as shown below:
Step 7: Return the header node: This can be done using the following code:
return head;
Now, the linked list as seen from the calling function is shown below:
Head
30 10 40 50 \0
The final function to delete an element from the front end can be written as shown
below:
if (head->link == NULL)
{
1 printf(“List is empty\n”);
return head;
}
return head;
}
The double ended queue can be implemented using singly linked list with a header
node using five functions: insert_front(), insert_rear(), delete_front(), delete_rear()
and display() functions. The C program to implement deque is shown below:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *link;
};
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.19: Function to insert at the front end of the list */
/* Include: Example 8.20: Function to insert at the front end of the list */
/* Include: Example 8.21: Function to delete an element from the rear end */
/* Include: Example 8.22: Function to delete an element from the front end */
/* Include: Example 8.4: C function to display the contents of linked list */
void main()
{
NODE head;
int choice, item;
head = getnode();
head->link = NULL;
for (;;)
{
printf("1:Insert_Front 2:Insert_Rear\n");
printf(“3:Delete_Front 4:Delete_Rear\n”);
printf("5:Display 6:Exit\n");
printf("Enter the choice\n");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the item to be inserted\n");
scanf("%d", &item);
head = insert_front (item, head);
break;
case 2:
printf("Enter the item to be inserted\n");
scanf("%d", &item);
head = insert_rear (item, head);
break;
case 3:
head = delete_front (item, head);
break;
8.64 Linked Lists
case 4:
head = delete_rear (item, head);
break;
case 5:
display(head->link);
break;
default:
exit(0);
}
}
}
Now, let us “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”
1. Create a SLL of N Students Data by using front insertion.
2. Display the status of SLL and count the number of nodes in it
3. Perform Insertion and Deletion at End of SLL
4. Perform Insertion and Deletion at Front of SLL
5. Demonstrate how this SLL can be used as STACK and QUEUE
6. Exit
typedef struct
{
int usn;
char name[20];
char branch[20];
int sem;
char phone[20];
struct
} STUDENT;
The design details are given in section 8.2. Creating a list is nothing but repeated
insertion of items into the list. The insert front function (example 8.3) and insert rear
function (example 8.6) are modified to incorporate the above details.
Data Structures using C - 8.65
The C function to insert a node at the front end can be written as shown below:
Example 8.24: C Function to insert an item at the front end of the list
if (first == NULL) return temp; /* Insert a node for the first time */
The C function to insert a node at the rear end can be written as shown below:
Example 8.25: C Function to insert various items at the rear end of the list
if (first == NULL) return temp; /* Insert a node for the first time */
8.66 Linked Lists
The function to delete an element from the front end given in example 8.5 can be
modified as shown below:
Example 8.26: C function to delete an item from the front end of the list
NODE delete_front(NODE first)
{
NODE temp;
if ( first == NULL ) /* Check for empty list */
{
printf("student list is empty cannot delete\n");
return NULL; // We can replace NULL with first also
}
temp = first; /* Retain address of the node to be deleted */
temp = temp->link; /* Obtain address of the second node */
printf("Delete student record: USN = %d\n", first->usn);
free(first); /* delete the front node */
Example 8.27: Function to delete an item from the rear end of the list
prev->link = NULL; /* Make last but one node as the last node */
Example 8.27: Program to implement dequeues using singly linked list (student)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int usn;
char name[20];
char branch[20];
int sem;
char phone[20];
} STUDENT;
Data Structures using C - 8.69
struct node
{
int usn;
char name[20];
char branch[20];
int sem;
char phone[20];
struct node *link;
};
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.24: Function to insert an item at the front end of the list */
/* Include: Example 8.25: Function to insert an item at the rear end of the list */
/* Include: Example 8.26: Function to delete an item from the front end of the list */
/* Include: Example 8.27: Function to delete an item from the rear end of the list */
/* Include: Example 8.28: Function to display the contents of linked list */
void main()
{
NODE first;
int choice;
STUDENT item;
first = NULL;
for (;;)
{
printf("1:Insert_Front 2: Insert_Rear\n");
printf("3:Delete_Front 4: Delete_Rear\n");
printf(“5:Display 6: Exit\n”);
switch(choice)
{
case 1:
printf("usn :"); scanf(“%d”,&item.usn);
printf("name :"); scanf(“%s”,item.name);
printf("branch :"); scanf(“%s”,item.branch);
printf("semester :"); scanf(“%d”,&item.sem);
printf("phone :"); scanf(“%s”,item.phone);
first = insert_front (item, first);
break;
case 2:
printf("usn :"); scanf(“%d”,&item.usn);
printf("name :"); scanf(“%s”,item.name);
printf("branch :"); scanf(“%s”,item.branch);
printf("semester :"); scanf(“%d”,&item.sem);
printf("phone :"); scanf(“%s”,item.phone);
first = insert_rear (item, first);
break;
case 3:
first = delete_front(first);
break;
case 4:
first = delete_rear(first);
break;
case 5:
display(first);
break;
default:
exit(0);
}
}
}
8.9 Other operations on linked list
In this section, let us see how to implement the following operations on linked lists:
Remove duplicate elements in the list
Union and intersection operation on two lists
Multiple stacks
Multiple queues
Data Structures using C - 8.71
The first two operations require that an item has to be searched in the list. If item is
present in the list, we return 1, otherwise, we return 0. The code already designed in
section 8.6.2 (i.e., example 8.12) can be modified only in returning the values using
the return statement. The modified code can be written as shown below:
Now, let us see, how the above function is helpful in designing the solution for next
three operations discussed.
8.9.1 Remove duplicate elements
In this section, let us remove duplicate elements in the given linked list. This can be
done as shown below:
Step 1: Empty list: If list is empty return NULL indicating the resulting list is also
empty. The code for this case can be written as shown below:
if (first == NULL) return NULL;
Step 2: List is existing: If the list is existing then duplicate elements have to be
removed. This can be explained by considering the following list:
40 20 30 40 30 40 \0
8.72 Linked Lists
Instead of using the variable first, let us use another variable a which points to the
beginning of the list as shown below:
first
a
40 20 30 40 30 40 \0
The above situation can be achieved by executing the following statement:
a = first;
Each item in the above list has to be accessed and a new list without duplicates has to
be created. Each item in the list can be accessed using the following code:
a = first;
while (a != NULL)
{
a->info; // access each item in the list
a = a->link; // get the address of the next node
}
Now, as you access using a->info, search for a->info in the second list b. If not
found, insert a->info at the end of the list b. Now, the above partial code can be
written as shown below:
a = first;
while (a != NULL)
{
/* search for a->info in list b */
found = search(a->info, b) ;
/* If a->info not found in b, insert a->info at the end of list b */
if (found == 0) b = insert_rear(a->info, b);
a = a->link;
}
Step 3: Return final list: This can be done by returning b which contains address of
the list. This can be done using the statement:
return b;
Now, the final code can be written as shown below:
Data Structures using C - 8.73
Example 8.29: Function to remove duplicate elements from the list
first
40 20 30 50 \0
second
60 20 30 50 40 70 \0
8.74 Linked Lists
40 20 30 50 60 70 \0
The above activity can be achieved using the following three steps:
Step 1: Add all elements of first list to the resultant list: This can be done by
accessing each item from first list and adding at the end of the resultant list identified
by variable third. The pictorial representation of three lists now can be written as
shown below:
first
First list
40 20 30 50 \0
second
Second list
60 20 30 50 40 70 \0
third
Resultant list
40 20 30 50 \0
The code for this activity can be written as shown below:
40 20 30 50 \0
second
Second list
60 20 30 50 40 70 \0
third
Resultant list (Union of two lists)
40 20 30 50 60 70 \0
This can be done using the statements shown in dotted lines in example 8.29 in
previous section. But, replace the variable first by second. The code is re-written as
shown below:
/* search for each item of 2nd list in 3rd list. If not found add into 3rd list */
a = second; /* existing list */
while (a != NULL) /* Traverse entire second list */
{
flag = search(a->info, third); /* search for item in new list b */
/* if not found insert into resultant list*/
if (flag == 0) third = insert_rear(a->info, third);
a = a->link; /* access next item in the list a */
}
return third; /* return the resultant result */
}
The intersection of two linked lists is much easier. To start with initialize resultant list
to NULL. This can be done as shown below:
third = NULL;
Traverse the first list till the end. During this process search for each item of the first
list in the second list. If the element is present then add the element to the resultant
Data Structures using C - 8.77
list. This can be done by changing the if-statement inside the loop given in example
8.29 shown using dotted lines (section 8.9.1). In the if-statement check for flag to 1.
The code is re-written with modification as shown below:
Now, given the two lists we can get the third list which is intersection of first two
lists using the above code as shown below:
first
First list
20 10 40 80 \0
0
second
Second list
60 20 30 50 40 70 \0
third
Resultant list (Intersection of two lists)
20 40 \0
Now, the functions to remove duplicate elements, to find union and intersection of
two lists can be invoked using function main which can be written as shown below:
Example 8.32: Program to remove duplicate items, find union and intersection of 2 lists
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *link;
};
typedef struct node* NODE;
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.4: Function to display the contents of the list */
/* Include: Example 8.6: Function to insert an item at the rear end of the list*/
/* Include: Example 8.28: Function to search for key in the list*/
Data Structures using C - 8.79
void main()
{
NODE first, second, third;
int choice, item, i, n;
for (;;)
{
printf("1:Create first list 2:Create second list\n”);
printf(“3:Remov duplicates of list 1 4:Remov duplicates of list 2\n”);
printf("5:Union of two lists 6:Intersection of two lists\n");
printf("7:Exit\n”);
first = NULL;
break;
case 2:
printf("Enter the number of nodes in second list\n");
scanf("%d", &n);
second = NULL;
8.80 Linked Lists
case 3:
printf(“The first list before removing duplicates\n”);
display(first);
first = remove_duplicate (first);
printf(“The first list after removing duplicates\n”);
display(first);
break;
case 4:
printf(“The second list before removing duplicates\n”);
display(second);
second = remove_duplicate (second);
printf(“The second list after removing duplicates\n”);
display(second);
break;
case 5:
printf(“The first list \n”);
display(first);
printf(“The second list \n”);
display(second);
third = union_of_list (first, second);
printf(“The union of two lists \n”);
display(third);
break;
case 6:
printf(“The first list \n”);
display(first);
Data Structures using C - 8.81
printf(“The second list \n”);
display(second);
third = intersection_of_list (first, second);
printf(“The intersection of two lists \n”);
display(third);
break;
default:
exit(0);
}
}
}
Now, let us “Implement multiple queues using array of queues with the help of singly
linked lists”
Design: Multiple queues can be implemented using array of linked lists as shown
below:
Let us fix the number of queues to 5. This can be done using the statement:
#define MAX_QUES 5
A queue can be implemented using linked list as shown in previous section. The
structure definition for a node can be written as:
struct node
{
int info;
struct node *link;
};
NODE a[MAX_QUES];
8.82 Linked Lists
Initially, all queues are empty. This can be done by assigning NULL to each of the
queue stored in the array as shown below:
To insert an item into ith queue: Invoke the function insert_rear() (example 8.6)
using item and a[i] as shown below:
To delete an item from ith queue: Invoke the function delete_front() (example 8.5)
using the following statement:
To display contents of ith queue: Invoke the function display() (example 8.4) using
the following statement:
display(a[i]);
Example 8.33: Program to implement multiple queues using singly linked lists
Data Structures using C - 8.83
#include <stdio.h>
#include <stdlib.h>
#define MAX_QUES 5
struct node
{
int info;
struct node *link;
};
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.6: Function to insert an item at the rear end of the list */
/* Include: Example 8.5: Function to delete an item from the front end of the list */
/* Include: Example 8.4: Function to display the contents of the list */
void main()
{
NODE a[MAX_QUES];
int choice, item, i;
for (;;)
{
printf(“Enter queue number: 0, 1, 2, 3, 4 : “);
scanf(“%d”, &i);
switch ( choice )
{
case 1:
printf("Enter the item to be inserted\n");
scanf("%d",&item);
a[i] = insert_rear(item, a[i]);
break;
case 2:
a[i] = delete_front(a[i]);
break;
case 3:
display(a[i]);
break;
default:
exit(0);
}
}
}
Now, let us “Implement multiple stacks using array of singly linked lists”
Let us fix the number of stacks to 5. This can be done using the statement:
#define MAX_STACKS 5
A stack can be implemented using linked list as shown in previous section. The
structure definition for a node can be written as:
struct node
{
int info;
struct node *link;
};
NODE a[MAX_STACKS];
Initially, all stacks are empty. This can be done by assigning NULL to each of the
stack stored in the array as shown below:
To insert an item into ith stack: Invoke the function insert_front() (example 8.3)
using item and a[i] as shown below:
a[i] = insert_rear(item, a[i]);
To delete an item from ith stack: Invoke the function delete_front() (example 8.5)
using the following statement:
a[i] = delete_front( a[i] );
To display contents of ith stack: Invoke the function display() (example 8.4) using
the following statement:
display(a[i]);
Now, the complete algorithm in C can be written as shown below:
8.86 Linked Lists
Example 8.34: Program for multiple stacks using array of singly linked lists
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *link;
};
typedef struct node* NODE;
#define MAX_STACKS 5
/* Include: Example 8.2: Function to get a new node from the operating system */
/* Include: Example 8.3: Function to insert an item at the front end of the list*/
/* Include: Example 8.5: Function to delete an item from the front end of the list */
/* Include: Example 8.4: Function to display the contents of the list */
void main()
{
NODE a[MAX_STACKS];
int choice, item, i;
for (;;)
{
printf(“Enter stack number: 0, 1, 2, 3, 4 : “);
scanf(“%d”, &i);
case 3:
display(a[i]);
break;
default:
exit(0);
}
}
}
Definition: The process of reserving the memory space to store the data is called
memory allocation. The memory space is allocated for variables in the following
situations:
For all global variables and static variables, memory is allocated during program
startup. The BSS segment in the memory contains all global variables and static
variables that are initialized to zero or do not have explicit initialization in source
code. When the program is terminated, the memory is freed and returned to the
free space available.
For all local variables, memory is allocated as and when the control enters into
the function. The memory space for all local variables is reserved on the stack
area in memory. Before control goes out of the function, the memory reserved for
all local variables is freed and returned to the free space available.
Memory can be allocated during run time (execution time) dynamically using
memory allocation functions such as malloc(), calloc() and realloc() in C
8.88 Linked Lists
language. The memory space for all dynamically variables is reserved in the heap
area. Once, memory space is used and no longer required, we can free the
memory space using free() function in C language.
When the memory is allocated dynamically and when it is not freed when not
required, this memory space cannot be used by any program. Thus memory space is
wasted. If too much memory space is wasted, soon the system may crash. So, it is
necessary to identify the unused space and return this unused space to the operating
system so that it can be allocated other programs which require memory space to store
the data. For this reason, we require garbage collector. Now, let us see “What is
garbage collector?”
EXERCISES
22. What are the shortcomings of a singly linked list? How these are eliminated in
circular list?
23. Write a C function to find the length of the linked list
24. Write a C function to search for key item in the list
25. Write a C function to delete a node whose info field is specified
26. Write a C function to create an ordered linked list?
27. What is a header node? What are the advantages of a list with a header node?”
28. How to implement dequeue operations using C functions.
29. Write a C function to remove duplicate elements from the list
30. Write a C function to find union of two lists
31. Write a C function to find intersection of two lists
32. Write a C function to implement multiple queues using array of queues with the
help of singly linked lists
33. Write a C function to implement multiple stacks using array of singly linked lists
34. What is garbage collection? How it is done?