0% found this document useful (0 votes)
13 views90 pages

CHAPTER2 Link List

Chapter 2 covers linked lists, including their definition, operations (traversing, searching, insertion, deletion), and types (singly, doubly, circular). It discusses the advantages and disadvantages of arrays compared to linked lists, and provides programming examples for creating and manipulating linked lists in C. The chapter emphasizes memory allocation and garbage collection as key aspects of linked list management.

Uploaded by

Awal Mamane
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)
13 views90 pages

CHAPTER2 Link List

Chapter 2 covers linked lists, including their definition, operations (traversing, searching, insertion, deletion), and types (singly, doubly, circular). It discusses the advantages and disadvantages of arrays compared to linked lists, and provides programming examples for creating and manipulating linked lists in C. The chapter emphasizes memory allocation and garbage collection as key aspects of linked list management.

Uploaded by

Awal Mamane
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/ 90

Chapter 2: Linked Lists

What are we studying in this chapter?


 Definition, Representation of linked lists in Memory
 Linked list operations: Traversing, Searching, Insertion, Deletion.
 Linked Stacks and Queues
 Doubly Linked lists
 Circular linked lists
 header linked lists.
 Applications of Linked lists, Polynomials, Sparse matrix representation.
 Memory allocation; Garbage Collection.
 Programming Examples

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

8.1.1 Linked list

Now, let us see “What is a linked list?”

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.

8.1.2 Types of Linked list

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

Singly linked lists


Doubly linked lists
Types of linked lists
Circular singly linked lists
Circular doubly linked lists

8.1.3 Singly linked lists

Now, let us see “What is a singly linked list?”

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.

Observe from above figure that:


 This list contains 5 nodes and each node consists of two fields, info and link.
 The info field of each node contains the data. In this list, the items 50, 20, 45, 10
and 80 represent the data.
 The numbers on top of each node i.e., 2004, 1020, 5012, 1008 and 6016 represent
the address of each node in the memory.

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

Now, let us “Define an empty linked list”

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

8.1.4 Representing a node of linked list

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?”

Definition: A structure is a collection of one or more fields which are of same or


different types. A self-referential structure is a structure which has at least one field
which is a pointer to itself. For example, consider the following structure definition:

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

/* Structure definition for a node */


struct node
{
int info;
struct node *link
};
typedef struct node *NODE;
Observe that the above structure is a tagged structure. Using the keyword typedef the
type “struct node *” is given the alternate name as NODE. So, wherever we use
“struct node *” we can replace with NODE.
A pointer variable first can be declared as shown below:

Method 1: NODE first;


or
Method 2: struct node * first;

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

typedef struct node *NODE;


NODE first; // first is self-referential structure variable.
first = NULL; // empty list by name first is created
8.6  Linked Lists

An empty list identified by the variable first is pictorially represented as shown


below:
NULL
first
8.1.6 Create a node
Now, let us see “How to create a node of the linked list?”

In C language, we can use malloc() function to allocate memory explicitly as and


when required and exact amount of memory space needed during execution. This can
be done using the statement:

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.

 If specified size of memory is not available, the condition is called “overflow of


memory”. In such case, the function returns NULL. It is the responsibility of the
programmer to check whether the sufficient memory is allocated or not as shown
below:
if (x == NULL)
{
printf(“Insufficient memory\n”);
exit(0);
}

It x is not NULL it means, a node is successfully created and we can return the node
using the statement:
return x;

Thus, the C function to get a node can be written as shown below:

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 */

if ( x == NULL ) /* Free nodes don’t exist */


{
printf("Out of memory\n"); /* Allocation failed */
exit(0); /* Terminate the program */
}

return x; /* allocation successful */


}

Note: The return type of getnode() is NODE and it is defined in previous section.

8.1.7 Create a node with specified item


Now, using the function getnode(), let us see “How to create a node with specified
item?” This can be done using the following steps.

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.

8.1.8 Delete a node


A node which is no longer required can be deleted using free() function in C as shown
below:
free (variable);
For example, when above statement is executed, the memory space allocated for the
node is de-allocated and returned to operating system so that it can be used by some
other program. The memory de-allocated after executing:
first
free(first); *first
10 \0
can be pictorially represented on the right hand side. info link

8.2 Operations on singly linked lists


Now, let us see “What are the various operations that can be performed on singly
linked lists?” The basic operations that can be performed on a linked list are shown
below:
Inserting a node into the list
Deleting a node from the list
Various Operations of linked lists
Search in a list
Display the contents of list
8.2.1 Insert a node at the front end

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:

Step 1: Create a node using getnode() function as shown below:

1 temp = getnode()

The pictorial representation after executing above statement is shown below:


temp first
1 20 30 10 60 \0

Step 2: Copy the item 50 into info field of temp using the following statement:

2 temp->info = item;

The pictorial representation after executing above statement is shown below:

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;

The pictorial representation after executing above statement is shown below:


temp first
3
50 20 30 10 60 \0
8.10  Linked Lists

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

NODE insert_front(int item, NODE first)


{
NODE temp;

temp = getnode(); /*obtain a node from the available list*/

temp->info = item; /* Insert an item into new node */

temp->link = first; /* insert new node at the front of list */

return temp; /* return the new first node */


}

The above function should be called in the calling function as shown below:

first = insert_front(item, first);

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.

8.2.2 Create a linked list

Now, the question is “How to create a linked list?”


 Data Structures using C - 8.11
The answer is very simple. Call the insert_front() function described in previous
section repeatedly as shown below:

first = insert_front(item, first);

 If first is NULL and item is 10, when above first


statement is executed, a linked list with only one
node is created as shown in figure on right hand 10 \0
side:
 If above statement is executed for the second time
with item 20, a new node is inserted at the front end first
and there by number of nodes in the list is 2 as
shown in figure: 20 10 \0

 If above statement is executed for the first


third time with item 30, a new node is
inserted at the front end and there by 30 20 10 \0
number of nodes in the list is 3 as
shown in figure:

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

8.2.3 How to find address of last node in the 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

Now, the list can be represented as shown below:

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:

// find the address of last node of the list


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

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

while (cur->link != NULL)


{
cur = cur->link;
}

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:

while (cur->link != NULL)


{
prev = cur;
cur = cur->link;
}

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:

/* Find address of last node and last but one node */


prev = NULL;
cur = first;
while (cur->link != NULL)
{
prev = cur;
cur = cur->link;
}

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.

8.2.5 Display singly linked list


Now, let us see “How to display the contents of the list?”
 Data Structures using C - 8.15
Design: The C function for this can be designed by considering two cases as shown
below:

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;

The resulting list can be written as shown below:

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:

printf(“%d “, cur->info); // Output: 20


cur = cur->link; // cur = 1008

The resulting list is shown below:


8.16  Linked Lists

first
1004 1008 1048 1026
20 30 10 60 \0
cur
Now, display info field of cur node and update cur as shown below:

printf(“%d “, cur->info); // Output: 30


cur = cur->link; // cur = 1048

The resulting list is 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:

printf(“%d “, cur->info); // Output: 10


cur = cur->link; // cur = 1026

The resulting list is 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:

printf(“%d “, cur->info); // Output: 60


cur = cur->link; // cur = NULL

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:

while (cur != NULL)


{
printf(“%d “, cur->info); printf(“%d “, cur->info);
cur = cur->link; cur = cur->link;
}

Now, the complete C function to display the contents of the list is shown below:

Example 8.4: C function to display the contents of linked list

void display(NODE first)


{
NODE cur;

if ( first == NULL ) /* Check for empty list */


{
printf("List is empty\n"); Case 1
return;
}
printf("The contents of singly linked list\n"); Case 2
cur = first; /* Holds address of the first node */
while ( cur != NULL ) /* As long as no end of list */
{
printf("%d ",cur->info); /* Display the info field of node */
cur = cur->link; /* Point to the next node */
}
printf("\n");
}

8.2.6 Delete a node from the front end

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:

printf(“Item deleted = %d\n”, first->info);


3 free (first);
After executing the above statement, the node pointed to by first is deleted and is
returned to operating system. The resulting linked list is shown in fig. below:
first temp

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

temp = temp->link; /* Obtain address of the second node */


printf("Item deleted = %d\n",first->info); /* access first node */
free(first); /* delete the front node */

return temp; /* return address of the first node */


}

8.2.7 Insert a node at the rear end


Now, let us see “How to insert a node from the rear end of the list?”
Design: Let us try to insert the item 50 at the rear end of the list. The sequence of
steps to be followed are shown below:
Step 1: Create a node using getnode() function (see example 8.2) then insert the item
say 50 using the following statements:

temp = getnode(); temp->info = item; temp->link = NULL;

temp temp temp

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:

first cur temp

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:

first cur temp


1
20 30 10 60 \0 50 \0

Note: The \0 (NULL character) is replaced by node pointed to by temp.

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 */

temp = getnode(); /* Obtain a new node and copy the item */


temp->info = item; Step 1
temp->link = NULL;

/* If list is empty return new node as the first node*/


if ( first == NULL ) return temp; Step 2

/* If list exists, obtain address of the last node */ Step 3


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

cur->link = temp; /* Insert the node at the end */ Step 4

return first; /* return address of the first node */ Step 5


}

8.2.8 Delete a node from the rear end

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.

/*If only one node is present, delete it */


if ( first ->link == NULL )
{
printf (“The item to be deleted is %d\n”, first->info);
free(first); /* Delete and return to OS */
return NULL; /* return empty list */
}
Case 3: List contains more than one node: Consider a list with five nodes shown in
figure 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

Now, the linked list looks as shown below:

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

while( cur->link != NULL )


{
prev = cur;
cur = cur->link;
}

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:

first prev cur


50 20 30 10 60 \0

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:

first prev cur


50 20 30 10 60 \0 3

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.

return first; 5 /* 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

NODE delete_rear(NODE first)


{
NODE cur, prev;

if (first == NULL) /* Check for empty list */


Case 1
{
printf(“List is empty cannot delete\n”);
return first;
}

if ( first ->link == NULL ) /*Only one node is present and delete it */


{
printf (“The item to deleted is %d\n”,first->info); Case 2

free(first); /* return to availability list */

return NULL; /* List is empty so return NULL */


}
8.26  Linked Lists

/* 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 */
}

8.3 Stacks using linked lists


We know that stack is a special type of data structure where elements are inserted at
one end and elements are deleted from the same end. That is, if an element is
inserted at front end, an element has to be deleted from front end. If an element is
inserted at rear end, an element has to be deleted from the rear end. Thus, a stack can
be implemented using the following functions:
 insert_front()
 insert_rear()
 delete_front() OR
 delete_rear()
 display()
 display()
The C program to implement stacks using singly linked list with the help of
insert_front(), delete_front() and display() functions is below:

Example 8.8: Program to implement stacks using singly linked list

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

8.4 Queue using linked lists

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:

Example 8.9: Program to implement queues using singly linked list

#include <stdio.h>
#include <stdlib.h>
#include <alloc.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.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

So, to implement double ended queue, we have to use insert_front(), insert_rear(),


delete_front() and delete_rear() functions.

The C program to implement double ended queue is shown below:

Example 8.10: Program to implement queues using singly linked list

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

8.6 Additional list operations

In this section, we discuss other list operations.

8.6.1 Find the length of the list

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:

Example 8.11: Function to find the length of the linked list

int Length(NODE first)


{
NODE cur;
int count = 0;

if ( first == NULL ) return 0; /* Check for empty list. If so, return 0 */


cur = first;
while (cur != NULL) /* As long as no end of list */
{
count++; /* Update count by 1 */
cur = cur->link; /* point cur to the next node */
}
return count; /* Return the length of list */
}
8.6.2 Search for an item in a list
Now, let us see “How to search for an item in a linked list?” Searching for a key item
is very simple and straight forward technique. We know how to display info of each
node. The partial code can be written as:
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 */
}
 Data Structures using C - 8.33
Replace the printf() by the following statement:

if (key == cur->info) break;

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 */

The complete C function to search for a key item is shown below:

Example 8.12: Function to search for key item in the list

void search(int key, NODE first)


{
NODE cur;
if ( first == NULL ) /* check for empty list */
{
printf("List is empty\n");
return;
}
cur = first;
while (cur != NULL) /* As long as no end of list */
{
if (key == cur->info) break; /* If found go out of the loop */
cur = cur->link; /* point cur to the next node */
}
8.34  Linked Lists

if (cur == NULL) /* If end of list, key not found */


{
printf(“Search is unsuccessful\n”);
return;
}
printf(“Serach is successful\n”); /* Yes, key found */
}
“Assume that we have a list of integers. Create a function that searches for an integer
number item. If item is present in the list, the function should return a pointer to the
node that contains item. Otherwise, it should return NULL”.

The above function should be modified as shown below:


 If item found, then return the pointer to the node. This can be done by replacing
the keyword break by:
return cur;

 If item not found, instead of displaying the message “Item not found” return
NULL.

The complete C function can be written as shown below:

Example 8.13: Function to search for key item in the list

NODE search(int key, NODE first)


{
NODE cur;

if ( first == NULL ) return NULL; /* Search for empty list */

/* Compare one after the other */


cur = first;
while (cur != NULL) /* As long as no end of list */
{
if (key == cur->info) return cur; /* If found go out of the loop */
cur = cur->link; /* point cur to the next node */
}

return NULL; /* key not found */


}
 Data Structures using C - 8.35
8.6.3 Delete a node whose information field is specified

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

key matches with first node

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:

first = first -> link; 2


Now, the pictorial representation of the list is shown below:

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

and return the address of the first using the statement:

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:

first prev cur


key = 10 50 20 30 10 60 \0

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:

first prev cur


key = 10 50 20 30 10 60 \0
5

The code corresponding to above activity can be written 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:

7 first prev cur


key = 10 50 20 30 10 60 \0
6

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

The complete C function to delete a node whose information field is specified is


shown below:
Example 8.14: Function to delete a node whose info field is specified

NODE delete_info(int key, NODE first)


{
NODE prev, cur;
if ( first == NULL ) /* Check for empty list */
{
printf("List is empty\n");
return NULL;
}
if ( key == first->info ) /* If key is present in first node, delete that node */
{
1 cur = first; /* Save the address of the first node */
2 first = first->link; /* Point first to second node in the list */
3 free(cur); /* Delete the first node */
4 return first; /* Return second node as the first node */
}
 Data Structures using C - 8.39
/* Search for the node to be deleted */
prev = NULL;
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 */
}

if (cur == NULL) /* If end of list, key not found */


{
printf(“Search is unsuccessful\n”);
return first;
}
/* Search successful. So, delete the node */
5 prev->link = cur->link; /* Establish link between the
predecessor and successor */

6 free(cur); /* Delete the node with info key */


7 return first; /* Return address of first node */
}

8.6.4 Concatenate two lists

Now, let us see “What is concatenation of two lists?”

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:

if (first == NULL) return second;

if (sec == NULL) return first;


8.40  Linked Lists

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

first cur second


50 20 30 10 \0 50 20 \0

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:

first cur second


50 20 30 10 50 20 \0

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:

Example 8.15: Function to concatenate two lists

NODE concat (NODE first, NODE sec)


{
NODE cur; /* holds the address of the last node of first list*/
if (first == NULL) return second;
if (sec == NULL) return first;
/* Obtain address of the last node of first list*/
cur = first;
while ( cur->link != NULL)
cur = cur->link;

cur->link = sec; /* Attach first node of second list to end of first list */
return first; /* Return the first node of the concatenated list */
}

8.6.5 Reverse (Invert) a list without creating new nodes


Now, let us see “How to reverse a given singly linked list?” Consider the list shown
below:

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

Now, if we display the above list, the output is: 50 40 30 20 10


8.42  Linked Lists

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

Now, let us assume two things:


 The pointer variable cur always contains address of the first node of the partially
reversed list (see above figure)
 The pointer variable first always contains address of the first node of the list to be
reversed (see above figure)

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:

cur first temp

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 steps 1 through 3 can be repeatedly performed as long as list to be reversed is


existing. That is, as long as the pointer variable first is not NULL keep executing
statements from step 1 to step 3. Now, the code can be written as:

cur = NULL; /* Initial reversed list */

while (first != NULL)


{
temp = first->link;
first->link = cur;
cur = first;
first = temp;
}

The C function to reverse a linked list is shown below:

Example 8.16: Function to reverse a list

NODE reverse (NODE first)


{
NODE cur, temp;
cur = NULL; /* Initial reversed list */
8.44  Linked Lists
while (first != NULL)
{
temp = first->link; // Obtain the address of second node
// of list to be reversed
first->link = cur; // attach first node of the list to be reversed
// at the beginning of the partially reversed list
cur = first; // Point cur to point to newly partially reversed list
first = temp; // Point first to point to the list to be reversed
}
return cur; /* Contains address of the reversed list */
}

The complete C function to insert an item into an ordered linked list is below:

8.6.6 Creating an ordered linked list


Now, let us see “What is an ordered linked list?”

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

Now, let us see “How to create an ordered linked list?”


Design: Assume that the ordered linked list is already existing with four nodes as
shown below:

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.

This can be pictorially represented as shown below:


temp 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:

if ( item <= first->info) /* Insert at the front end of the list */


{
temp->link = first;
return temp;
}

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:

first prev cur


item = 35 10 20 30 40 \0

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:

prev->link = temp; /* connect node prev with node temp */


temp->link = cur; /* connect new node temp with next node cur */

After executing the above statements, the linked list can be written as shown below:

first prev cur


item = 35 10 20 30 40 \0

temp

Step 6: Always we return the address of the first node as shown below:

return first; /* return address of the first node */

Now, the complete function to create an ordered linked list can be written as shown
below:

Example 8.17: C function to create an ordered linked list


8.48  Linked Lists

NODE insert(int item, NODE first)


{
NODE temp, prev, cur;
temp = getnode(); /* obtain a node to be inserted */ STEP 1
temp->info = item;
temp->link = NULL;
/* Inserting the node for the first time */ STEP 2
if ( first == NULL ) return temp;
/* Inserting the node in the beginning of the list */ STEP 3
if ( item <= first->info )
{
temp->link = first;
return temp;
}
/* find prev and cur locations so that node temp has to be inserted */
prev = NULL; STEP 4
cur = first;

while ( cur != NULL && item > cur->info )


{
prev = cur;
cur = cur->link;
}
/* Insert the node between prev and cur */ STEP 5
prev->link = temp;
temp->link = cur;

return first; /* return the first node */ STEP 6


}

8.6.7 Program to perform list operations


The complete program to implement various operations listed in previous sections is
shown below:

Example 8.18: Program to perform various operations


 Data Structures using C - 8.49
#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.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);
}
}
}

8.7 Header Node


Now, let us see “What is a header node?”

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

In the above list


 The info field of header node does not contain any information.
 The first node starts from link field of header node i.e., the node containing the
info 20 is the first node
 If we display the contents of above list, the output will be: 20, 30, 10, 40, 50

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

8.7.1 Insert a node at the front end


Now, let us see “How to insert an item at the front 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 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

The complete C function is shown below:

Example 8.19: Function to insert at the front end of the list


NODE insert_front(int item, NODE head)
{
NODE temp;
temp = getnode(); /* Create a node, insert the item */
1
temp->info = item;
2 first = head->link; /* Obtain the address of the first node */

3 head->link = temp; /* Insert at the front end */

4 temp->link = first;
return head; /* Return the header node */
}
8.54  Linked Lists

8.7.2 Insert a node at the rear end

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:

while (cur->link != NULL)


{
3 cur = cur->link;
}

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:

Head cur temp


4
20 30 10 40 50 \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

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

Example 8.20: Function to insert at the front end of the list

NODE insert_rear(int item, NODE head)


{
NODE temp, cur;

temp = getnode(); /* node to be inserted */


1 temp->info = item;
temp->link = NULL;

2 cur = head->link; /* obtain address of the first node */

while ( cur->link != NULL ) /* Obtain address of the last node */


{
3 cur = cur->link;
}

4 cur->link = temp; /* insert node at the end */

return head;
}

8.7.3 Delete a node from the rear end


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:

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:

Head prev cur


2

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:

while (cur->link != NULL)


{
3 prev = cur;
cur = cur->link;
}

After executing the above part of the code, the linked list can be written as shown
below:

Head prev 3 cur

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:

Head prev cur

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:

printf(“Item deleted = %d\n”, cur->info); /* Item deleted = 50 */


5
free (cur);

After executing the above statements, the linked list looks as shown below:

Head prev cur


5

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

NODE delete_rear(NODE head)


{
NODE prev, cur;

if (head->link == NULL)
{
printf(“List is empty\n”);
1
return head;
}

prev = head; // Previous to first node


2
cur = head->link; // Obtain the first node

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

printf(“Item deleted = %d\n”, cur->info); /* Item deleted = 50 */


5 free (cur); // Remove the last node

return head;
}

8.7.4 Delete a node from the front end

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:

2 first = head->link; // Obtain the first node

Now, the linked list looks as shown below:

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:

3 second = first->link; // Obtain the second node

After executing the above instruction, the linked list looks as shown below:

Head first second


3

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

4 head->link = second; // Make 2nd node as the first node


After executing the above instruction, the linked list looks as shown below:

Head first second

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:

Head first second


5
20 30 10 40 50 \0

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:

Example 8.22: Function to delete an element from the front end


8.62  Linked Lists

NODE delete_front(NODE head)


{
NODE first, second;

if (head->link == NULL)
{
1 printf(“List is empty\n”);
return head;
}

2 first = head->link; // Obtain the first node

3 second = first->link; // Obtain the second node

4 head->link = second; // Make 2nd node as the first node

printf(“Item deleted = %d\n”, first->info); // Item deleted = 20


5 free(first);

return head;
}

8.7.5 Implementation of double ended queue

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:

Example 8.23: Function to delete an element from the front end

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

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

typedef struct node* NODE;


 Data Structures using C - 8.63

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

8.8 Representing student data using linked list

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

A structure to hold the student details can be written as shown below:

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

NODE insert_front(STUDENT item, NODE first)


{
NODE temp;

temp = getnode(); /*obtain a node from OS */


temp->usn = item.usn; /* Insert various items into new node */
strcpy(temp->name, item.name);
strcpy(temp->branch, item.branch);
temp->sem = item.sem;
strcpy(temp->phone, item.phone);
temp->link = NULL;

if (first == NULL) return temp; /* Insert a node for the first time */

temp->link = first; /* Insert at the beginning of existing list */

return temp; /* return address of new first node */


}

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

NODE insert_rear(STUDENT item, NODE first)


{
NODE temp, cur;

temp = getnode(); /*obtain a node from OS */


temp->usn = item.usn; /* Insert various items into new node */
strcpy(temp->name, item.name);
strcpy(temp->branch, item.branch);
temp->sem = item.sem;
strcpy(temp->phone, item.phone);
temp->link = NULL;

if (first == NULL) return temp; /* Insert a node for the first time */
8.66  Linked Lists

/* Get the address of the first node */


cur = first;

/* Find the address of the last node */


while (cur->link != NULL)
{
cur = cur->link;
}

/* Insert the node at the end */


cur->link = temp;

/* return address of the first node */


return first;
}

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 */

return temp; /* return address of the first node */


}
 Data Structures using C - 8.67
The function to delete an element from the rear end given in example 8.7 can be
modified as shown below:

Example 8.27: Function to delete an item from the rear end of the list

NODE delete_rear(NODE first)


{
NODE cur, prev;

if (first == NULL) /* Check for empty list */


{
printf(“student list is empty cannot delete\n”);
return first;
}

if ( first->link == NULL ) /*Only one node is present and delete it */


{
printf("Delete student record: USN = %d\n", first->usn);

free(first); /* return to availability list */

return NULL; /* List is empty so return NULL */


}

/* Obtain address of the last node and just previous to that */


prev = NULL;
cur = first;
while( cur->link != NULL )
{
prev = cur;
cur = cur->link;
}

printf("Delete student record: USN = %d\n", first->usn);


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 */


}
8.68  Linked Lists

The function to display the student details are shown below:

Example 8.28: Function to display student details

void display(NODE first)


{
NODE cur; int count = 0;

if (first == NULL) /* List is empty */


{
printf(“student list is empty\n”);
return;
}

cur = first; /* Display employee details */


while (cur != NULL)
{
printf(“%d %s %s %d %s \n”, cur->usn, cur->name, cur->branch,
cur->sem, cur->phone);
cur = cur->link; count++;
}
printf(“Number of students = %d\n”, count);
}

The program to implement dequeuer operations can be written as shown below:

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

typedef struct node* NODE;

/* 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”);

printf("Enter the choice\n");


scanf("%d", &choice);
8.70  Linked Lists

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:

Example 8.28: Function to search for key item in the list

int search(int key, NODE first)


{
NODE cur;
if ( first == NULL ) return 0; /* Search unsuccessful */
cur = first;
while (cur != NULL) /* As long as no end of list */
{
if (key == cur->info) return 1; /* Search successful */
cur = cur->link; /* point cur to the next node */
}
return 0; /* Search not successful */
}

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:

first Existing 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

NODE remove_duplicate (NODE first)


{
NODE a, b;
int flag;

if (first == NULL) return NULL; /* empty list */


b = NULL; /* existing new list b*/

a = first; /* existing list a */


while (a != NULL) /* Traverse the entire list a */
{
flag = search(a->info, b); /* search for item in new list b */
/* if not found insert into new list b*/
if (flag == 0) b = insert_rear(a->info, b);

a = a->link; /* access next item in the list a */


}

return b; /* new list without duplicates */


}

8.9.2 Union of two lists


Now, let us see how to find union of two lists. It can be explained by looking into the
following two lists:

first

40 20 30 50 \0

second

60 20 30 50 40 70 \0
8.74  Linked Lists

The union of above two lists can be written as shown below:


third

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:

a = first; // access first list using variable a

/* Add all elements of first list to the end of resultant list */


third = NULL; // Initial resultant list
while (a != NULL) // Traverse till the end
{
third = insert_rear (a->info, third); // Insert item at the rear end of list
a = a->link; // Move to the next node in the list
}
 Data Structures using C - 8.75
Step 2: Insert elements of second list into resultant list: This can be done by accessing
each item from the first list and search in the resultant list. If item of first list is not
present in the resultant list then add the item of the first list to the end of the resulting
list. The above activity is pictorially represented as shown below:
first
First list

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:

a = second; /* existing list */


while (a != NULL) /* Traverse the entire second list */
{
flag = search(a->info, third); /* search for item in new list b */
/* if not found insert into new list b*/
if (flag == 0) third = insert_rear(a->info, third);

a = a->link; /* access next item in the list a */


}
Step 3: Return the resultant list: This can be done using the statement:
return third;
Now, the final code can be written as shown below:
8.76  Linked Lists

Example 8.30: Function to find union of two lists

NODE union_of_list (NODE first, NODE second)


{
NODE a, third;
int flag;
a = first; // access first list using variable a
/* Add all elements of first list to the end of resultant list */
third = NULL; // Initial resultant list
while (a != NULL) // Traverse till the end
{
third = insert_rear (a->info, third); // Insert item at the rear end of list
a = a->link; // Move to the next node in the list
}

/* 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 */
}

8.9.3 Intersection of two lists

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:

a = first; /* existing list a */


b = second; /* existing list b */
third = NULL; /* resultant list is empty */
while (a != NULL) /* Traverse the entire list a */
{
flag = search(a->info, b); /* search for item in new list b */
/* if found insert into resultant list*/
if (flag == 1) third = insert_rear(a->info, third);

a = a->link; /* access next item in the list a */


}

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 complete code can be written as shown below:

Example 8.31: Function to find intersection of two lists


8.78  Linked Lists

NODE intersection_of_list (NODE first, NODE second)


{
NODE a, b, third;
int flag;
a = first; /* a points to first list */
b = second; /* b points to second list */
third = NULL; /* resultant list is empty */

while (a != NULL) /* Traverse entire second list */


{
flag = search(a->info, b); /* search for item in new list b */
/* if not found insert into new list b*/
if (flag == 1) third = insert_rear(a->info, third);
a = a->link; /* access next item in the list a */
}
return third; /* return the resultant result */
}

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

/* Include: Example 8.29: Function to remove duplicates in the list*/


/* Include: Example 8.30: Function to find union of two lists */
/* Include: Example 8.31: Function to find intersection of two lists */

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

printf("Enter the choice\n");


scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the number of nodes in first list\n");
scanf("%d", &n);

first = NULL;

for (i = 1; i <= n; i++)


{
printf(“Enter the item\n”);
scanf("%d", &item);

first = insert_rear (item, first);


}

break;
case 2:
printf("Enter the number of nodes in second list\n");
scanf("%d", &n);
second = NULL;
8.80  Linked Lists

for (i = 1; i <= n; i++)


{
printf(“Enter the item\n”);
scanf("%d", &item);
second = insert_rear (item, second);
}
break;

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

8.9.4 Implementation of multiple queues

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

typedef struct node * NODE;

 To implement number of queues specified using symbolic constant MAX_QUES,


we use the following declarations:

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:

for (i = 0; i < MAX_QUES; i++)


{
a[i] = NULL;
}

The pictorial representation of initial multiple queues are shown below:

a[0] \0 0th queue is empty

a[1] \0 1st queue is empty

a[2] \0 2nd queue is empty

a[3] \0 3rd queue is empty

a[4] \0 4th queue is empty.

To insert an item into ith queue: Invoke the function insert_rear() (example 8.6)
using item and a[i] as shown below:

a[i] = insert_front(item, a[i]);

To delete an item from ith queue: Invoke the function delete_front() (example 8.5)
using the following statement:

a[i] = delete_front( a[i] );

To display contents of ith queue: 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:

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

typedef struct node* NODE;

/* 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 (i = 0; i < MAX_QUES; i++) // Initialize multiple queues to NULL


{
a[i] = NULL;
}

for (;;)
{
printf(“Enter queue number: 0, 1, 2, 3, 4 : “);
scanf(“%d”, &i);

printf("1:Insert rear 2:Delete front \n");


printf("3:Display 4:Exit\n");

printf("Enter the choice\n");


scanf("%d",&choice);
8.84  Linked Lists

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

8.9.5 Implementation of multiple stacks

Now, let us “Implement multiple stacks using array of singly linked lists”

Design: Multiple stacks can be implemented using array of linked lists as


shown below:

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

typedef struct node * NODE;


 Data Structures using C - 8.85

 To implement number of stacks specified using symbolic constant


MAX_STACKS, we use the following declarations:

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:

for (i = 0; i < MAX_STACKS; i++)


{
a[i] = NULL;
}

The pictorial representation of initial multiple stacks are shown below:

a[0] \0 0th stack is empty

a[1] \0 1st stack is empty

a[2] \0 2nd stack is empty

a[3] \0 3rd stack is empty

a[4] \0 4th stack is empty.

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 (i = 0; i < MAX_STACKS; i++) // Initialize multiple stacks to NULL


{
a[i] = NULL;
}

for (;;)
{
printf(“Enter stack number: 0, 1, 2, 3, 4 : “);
scanf(“%d”, &i);

printf("1:Push 2:Pop \n");


printf("3:Display 4:Exit\n");

printf("Enter the choice\n");


scanf("%d",&choice);
 Data Structures using C - 8.87
switch ( choice )
{
case 1:
printf("Enter the item to be inserted\n");
scanf("%d",&item);
a[i] = insert_front(item, a[i]);
break;
case 2:
a[i] = delete_front(a[i]);
break;

case 3:
display(a[i]);
break;

default:
exit(0);
}
}
}

8.10 Memory allocation and Garbage collection

Now, let us see “What is memory allocation?”

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?”

Definition: Garbage collection is form of memory management technique which


attempts to reclaim the unused memory space (called garbage) and return it to
operating system so that the memory space thus collected can be assigned to other
programs for storing the data. The garbage collections avoids the need for the
programmer to deallocate the memory space.

Garbage collection can be using a method called reference counting. In this


technique, each allocated space is given a counter. This counter always contains the
number of pointers associated with the allocated space. It is automatically
incremented whenever a new variable references this allocated space. It is
decremented whenever a pointer to the allocated space is de-referenced. When the
counter becomes zero, the allocated memory space is collected and returned to the
operating system.
 Data Structures using C - 8.89

EXERCISES

1. Write C functions to perform the following operations on singly linked list


a) Insert front b)Insert rear c) display
d) Delete front e) Delete rear
2. Write a C program to implement stack operations using singly linked lists.
3. Write a C program to implement queue operations using singly linked lists.
4. Write a C program to implement dequeuer operations using singly linked lists.
5. Write C functions to perform the following operations on singly linked list with a
header node
b) Insert front b)Insert rear c) display
d) Delete front e) Delete rear
6. Write a C program to implement stack operations using singly linked lists with a
header node
7. Write a C program to implement queue operations using singly linked lists with a
header node
8. Write a C program to implement dequeuer operations using singly linked lists
with a header node.
9. Write a C function which will perform an insertion to the immediate left of the kth
node in the singly linked list.
10. Write a C function to count the number of nodes in a singly linked list.
11. Write a C function to change the info field of the kth node to the value given by X.
12. Write a C function to concatenate two lists into a single list.
13. Write a C function to reverse a given singly linked list without creating new
nodes.
14. Write a C function search(p,x) that accepts a pointer p to a list of integers and an
integer x and returns a pointer to a node containing x, if it exists, and the NULL
pointer otherwise.
15. Write a C function srchinsrt(p,x) that adds an item x to the list pointed to by p,
provided x is not in the list. Insertion can be done at the front end or rear end.
16. Write a C function to delete a node from the front end and insert it at the end of
the list.
17. Write a C function to check whether a given string is a palindrome using a doubly
linked list.
18. Mention few advantages of a header node.
19. What are the advantages and disadvantages of dynamic data structures?
20. Compare and contrast static data structures with dynamic data structures.
21. Explain the advantages and disadvantages of representing a groups of items as an
array versus a linear linked list.
8.90  Linked Lists

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?

You might also like