DS 03 Linked List
DS 03 Linked List
UNIT 3 LISTS
Structure Page Nos.
3.0 Introduction 33
3.1 Objectives 33
3.2 Abstract Data Type-List 33
3.3 Array Implementation of Lists 34
3.4 Linked Lists-Implementation 38
3.5 Doubly Linked Lists-Implementation 44
3.6 Circularly Linked Lists-Implementation 46
3.7 Applications 54
3.8 Summary 56
3.9 Solutions/Answers 56
3.10 Further Readings 56
3.0 INTRODUCTION
In the previous unit, we have discussed arrays. Arrays are data structures of fixed size.
Insertion and deletion involves reshuffling of array elements. Thus, array
manipulation is time-consuming and inefficient. In this unit, we will see abstract data
type-lists, array implementation of lists and linked list implementation, Doubly and
Circular linked lists and their applications. In linked lists, items can be added or
removed easily to the end or beginning or even in the middle.
3.1 OBJECTIVES
After going through this unit, you will be able to:
ADT List
A list of elements of type T is a finite sequence of elements of type T together with
the operations of create, update, delete, testing for empty, testing for full, finding the
size, traversing the elements.
In defining Abstract Data Type, we are not concerned with space or time efficiency as
well as about implementation details. The elements of a list may be integers,
characters, real numbers and combination of multiple data types.
Consider a real world problem, where we have a company and we want to store the
details of employees. To store this, we need a data type which can store the type
details containing names of employee, date of joining, etc. The list of employees may
33
Introduction to increase depending on the recruitment and may decrease on retirements or termination
Algorithms and
Data Structures
of employees. To make it very simple and for understanding purposes, we are taking
the name of employee field and ignoring the date of joining etc. The operations we
have to perform on this list of employees are creation, insertion, deletion, visiting, etc.
We define employee_list as
typedef struct
{
char name[20];
……………….
………………….
} emp_list;
The list can be implemented in two ways: the contiguous (Array) implementation and
the linked (pointer) implementation. In contiguous implementation, the entries in the
list are stored next to each other within an array. The linked list implementation uses
pointers and dynamic memory allocation. We will be discussing array and linked list
implementation in our next section.
typedef struct
{
int count;
int entry[100];
}list;
For simplicity, we have taken list entry as integer. Of course, we can also take list
entry as structure of employee record or student record, etc.
34
Lists
Count 1 2 3 4 5 6 7 8
11 22 33 44 55 66 77
Insertion
From the above example, if we want to add element ‘35’ after element ‘33’. We
have to shift 77 to 8th position, 66 to 7th position, so on, 44 to 5th position.
Before Insertion
Count 1 2 3 4 5 6 7
11 22 33 44 55 66 77
Step 1
Count 1 2 3 4 5 6 7 8
11 22 33 44 55 66 77 77
Step 2
Count 1 2 3 4 5 6 7 8
11 22 33 44 55 66 66 77
Step 3
Count 1 2 3 4 5 6 7 8
11 22 33 44 55 55 66 77
Step 4
Count 1 2 3 4 5 6 7 8
11 22 33 44 44 55 66 77
Step 5
Count 1 2 3 4 5 6 7 8
11 22 33 35 44 55 66 77
start->data[position] = element;
start->count++ ;
}
if(start->data[i] == 0)
test=0;
else
i++;
}
start->count=i;
}
/* main function */
void main( )
{
int position, element;
list l;
create(&l);
printf("\n Entered list as follows:\n");
fflush(stdin);
traverse(&l);
36
fflush(stdin); Lists
printf("\n input the position where you want to add a new data item:");
scanf("%d", &position);
fflush(stdin);
printf("\n input the value for the position:");
scanf("%d", &element);
insert(&l, position, element);
traverse(&l);
}
Program 3.1: Insertion of an element into a linear array.
Deletion
To delete an element in the list at the end, we can delete it without any problem. But,
suppose if we want to delete the element at the beginning or middle of the list, then,
we have to rewrite all the elements after the position where the element that has to be
deleted exists. We have to shift (r+1)th element to rth position , where ‘r’ is position
of deleted element in the list, the (r + 2)th element to (r + 1)th position, and this will
continue until the (n)th element to ( n–1 )th position, where n is the number of
elements in the list. And then the count is decremented.
From the above example, if we want to delete an element ‘44’ from list. We have to
shift 55 to 4th position, 66 to 5th position, 77 to 6th position.
Before deletion
Count 1 2 3 4 5 6 7
11 22 33 44 55 66 77
Step 1
Count 1 2 3 4 5 6 7
11 22 33 55 55 66 77
Step 2
Count 1 2 3 4 5 6 7
11 22 33 55 66 66 77
Step 3
Count 1 2 3 4 5 6
11 22 33 55 66 77
Program 3.2 will demonstrate deletion of an element from the linear array
/* main function */
void main()
{
………………..
……………….
A linked list is a data structure used to maintain a dynamic series of data. Think of a
linked list as a line of bogies of train where each bogie is connected on to the next
bogie. If you know where the first bogie is, you can follow its link to the next one. By
following links, you can find any bogie of the train. When you get to a bogie that isn’t
holding (linked) on to another bogie, you know you are at the end.
Linked lists work in the same way, except programmers usually refer to nodes instead
of bogies. A single node is defined in the same way as any other user defined type or
object, except that it also contains a pointer to a variable of the same type as itself.
We will be seeing how the linked list is stored in the memory of the computer. In the
following Figure 3.1, we can see that start is a pointer which is pointing to the node
which contains data as madan and the node madan is pointing to the node mohan and
the last node babu is not pointing to any node. 1000,1050,1200 are memory addresses.
38
Once you have a definition for a list node, you can create a list simply by declaring a Lists
pointer to the first element, called the “head”. A pointer is generally used instead of a
regular variable. List can be defined as
list *head;
It is as simple as that! You now have a linked list data structure. It isn’t altogether
useful at the moment. You can see if the list is empty. We will be seeing how to
declare and define list-using pointers in the following program 3.3.
#include <stdio.h>
int main()
{
list *head = NULL; /* initialize list head to NULL */
if (head == NULL)
{
printf("The list is empty!\n");
}
}
Program 3.3: Creation of a linked list
In the next example (Program 3.4), we shall look to the process of addition of new
nodes to the list with the function create_list().
#include<stdio.h>
#include<stdlib.h>
#define NULL 0
struct linked_list
{
int data;
struct linked_list *next;
};
typedef struct linked_list list;
void main()
{
list *head;
void create(list *);
int count(list *);
void traverse(list *);
head=(list *)malloc(sizeof(list));
create(head);
printf(" \n traversing the list \n");
traverse(head);
printf("\n number of elements in the list %d \n", count(head));
}
{
if(start->next == NULL)
return 0;
else
return (1+count(start->next));
}
Program 3.4: Insertion of elements into a Linked list
Step 1 Begin
Step 2 if the list is empty or a new element comes before the start (head)
element, then insert the new element as start element.
Step 3 else, if the new element comes after the last element, then insert the
new element as the end element.
Step 4 else, insert the new element in the list by using the find function, find
function returns the address of the found element to the insert_list
function.
Step 5 End.
Figure 3.2 depicts the scenario of a linked list of two elements and a new element
which has to be inserted between them. Figure 3.3 depicts the scenario of a linked list
after insertion of a new element into the linked list of Figure 3.2.
Before insertion
f next
f
NULL
new element
NULL
40
Lists
Figure 3.2: A linked list of two elements and an element that is to be inserted
After insertion
NULL
f next
new element
Program 3.5 depicts the code for the insertion of an element into a linked list by
searching for the position of insertion with the help of a find function.
INSERT FUNCTION
void main()
{
list *head;
void create(list *);
int count(list *);
void traverse(list *);
head=(list *)malloc(sizeof(list));
create(head);
printf(" \n traversing the created list \n");
traverse(head);
printf("\n number of elements in the list %d \n", count(head));
head=insert_list(head);
printf(" \n traversing the list after insert \n");
traverse(head);
}
Step 1 Begin
Step 2 if the list is empty, then element cannot be deleted
Step 3 else, if element to be deleted is first node, then make the start (head) to point
to the second element.
Step 4 else, delete the element from the list by calling find function and returning the
found address of the element.
Step 5 End
Figure 3.4 depicts the process of deletion of an element from a linked list.
After Deletion
f next
42
Lists
key node
Figure 3.4: Deletion of an element from the linked list (Dotted line depicts the link prior to
deletion)
Program 3.6 depicts the deletion of an element from the linked list. It includes a
function which specifically searches for the element to be deleted.
DELETE_LIST FUNCTION
/* prototype of delete_function */
list *delete_list(list *);
list *find(list *, int);
/*definition of delete_list */
list *delete_list(list *start)
{
int key; list * f, * temp;
printf(“\n enter the value of element to be deleted \n”);
scanf(“%d”, &key);
if(start->data == key)
{
temp=start->next;
free(start);
start=temp;
}
else
{
f = find(start,key);
if(f==NULL)
printf(“\n key not fund”);
else
{
temp = f->next->next;
free(f->next);
f->next=temp;
}
}
return(start);
}
void main()
{
list *head;
void create(list *);
int count(list *);
void traverse(list *);
head=(list *)malloc(sizeof(list));
create(head);
43
Introduction to printf(“ \n traversing the created list \n”);
Algorithms and
Data Structures
traverse(head);
printf(“\n number of elements in the list %d \n”, count(head));
head=insert(head);
printf(“ \n traversing the list after insert \n”);
traverse(head);
head=delete_list(head);
printf(“ \n traversing the list after delete_list \n”);
traverse(head);
}
Program 3.6: Deletion of an element from the linked list by searching for element that is to be deleted
Doubly linked list (Figure 3.5) is defined as a collection of elements, each element
consisting of three fields:
• pointer to left element,
• data field, and
• pointer to right element.
Left link of the leftmost element is set to NULL which means that there is no left
element to that. And, right link of the rightmost element is set to NULL which means
that there is no right element to that.
ALGORITHM (Creation)
Step 1 begin
Step 2 define a structure ELEMENT with fields
Data
Left pointer
Right pointer
Step 3 declare a pointer by name head and by using (malloc()) memory
allocation function allocate space for one element and store the
address in head pointer
Head = (ELEMENT *) malloc(sizeof(ELEMENT))
44
Step 6 end Lists
# include <stdio.h>
# include <malloc.h>
struct dl_list
{
int data;
struct dl_list *right;
struct dl_list *left;
};
typedef struct dl_list dlist;
OUTPUT
• Insertion,
• Deletion, and
• Traversing
head
46
Lists
struct linked_list
{
int data;
struct linked_list *next;
};
typedef struct linked_list clist;
void main()
{
void create_clist(clist *);
int count(clist *);
void traverse(clist *);
head=(clist *)malloc(sizeof(clist));
s=head;
create_clist(head);
printf(" \n traversing the created clist and the starting address is %u \n",
head);
traverse(head);
printf("\n number of elements in the clist %d \n", count(head));
}
47
Introduction to if(start->next!=s)
Algorithms and
Data Structures
{
printf("data is %d \t next element address is %u\n", start->data, start-
>next);
traverse(start->next);
}
if(start->next == s)
printf("data is %d \t next element address is %u\n",start->data, start-
>next);
}
Step 1 Begin
Step 2 if the list is empty or new element comes before the start (head)
element, then insert the new element as start element.
Step 3 else, if the new element comes after the last element, then insert the
new element at the end element and adjust the pointer of last element
to the start element.
Step 4 else, insert the new element in the list by using the find function. find
function returns the address of the found element to the insert_list
function.
Step 5 End.
If new item is to be inserted after an existing element, then, call the find function
recursively to trace the ‘key’ element. The new element is inserted before the ‘key’
element by using above algorithm.
Figure 3.7 depicts the Circular linked list with a new element that is to be inserted.
Figure 3.8 depicts a Circular linked list with the new element inserted between first
and second nodes of Figure 3.7.
48
f next
Lists
f
f next
new element
NULL
Figure 3.8: A Circular Linked List after insertion of the new element between first and second nodes
(Dotted lines depict the links prior to insertion)
Program 3.9 depicts the code for insertion of a node into a Circular linked list.
#include<stdio.h>
#include<stdlib.h>
#define NULL 0
struct linked_list
{
int data;
struct linked_list *next;
};
typedef struct linked_list clist;
clist *head, *s;
/* prototype of find and insert functions */
clist * find(clist *, int);
clist * insert_clist(clist *);
/*definition of insert_clist function */
clist * insert_clist(clist *start) {
clist *n, *n1;
int key, x;
printf("enter value of new element");
scanf("%d", &x);
printf("eneter value of key element");
scanf("%d",&key);
if(start->data ==key)
{
49
Introduction to n=(clist *)malloc(sizeof(clist));
Algorithms and
Data Structures
n->data=x;
n->next = start;
start=n;
}
else
{
n1 = find(start, key);
if(n1 == NULL)
printf("\n key is not found\n");
else
{
n=(clist*)malloc(sizeof(clist));
n->data=x;
n->next=n1->next;
n1->next=n;
}
}
return(start);
}
/*definition of find function */
clist * find(clist *start, int key)
{
if(start->next->data == key)
return(start);
if(start->next->next == NULL)
return(NULL);
else
find(start->next, key);
}
void main()
{
void create_clist(clist *);
int count(clist *);
void traverse(clist *);
head=(clist *)malloc(sizeof(clist));
s=head;
create_clist(head);
printf(" \n traversing the created clist and the starting address is %u \n",
head);
traverse(head);
printf("\n number of elements in the clist %d \n", count(head));
head=insert_clist(head);
printf("\n traversing the clist after insert_clist and starting address is %u
\n",head);
traverse(head);
}
void create_clist(clist *start)
{
printf("inputthe element -1111 for coming oout of the loop\n");
scanf("%d", &start->data);
if(start->data == -1111)
start->next=s;
else
{
start->next=(clist*)malloc(sizeof(clist));
create_clist(start->next);
50
} Lists
}
Figure 3.9 depicts a Circular linked list from which an element was deleted.
Step 1 Begin
Step 2 if the list is empty, then element cannot be deleted.
Step 3 else, if element to be deleted is first node, then make the start (head) to point
to the second element.
Step 4 else, delete the element from the list by calling find function and returning
the found address of the element.
Step 5 End.
f next
Figure 3.9 A Circular Linked List from which an element was deleted
(Dotted line shows the linked that existed prior to deletion)
Program 3.10 depicts the code for the deletion of an element from the Circular linked
list.
#include<stdio.h>
#include<stdlib.h>
#define NULL 0
struct linked_list
{
int data;
struct linked_list *next;
};
51
Introduction to typedef struct linked_list clist;
Algorithms and
Data Structures
clist *head, *s;
/*definition of delete_clist */
clist *delete_clist(clist *start)
{
int key; clist * f, * temp;
printf("\n enter the value of element to be deleted \n");
scanf("%d", &key);
if(start->data == key)
{
temp=start->next;
free(start);
start=temp;
}
else
{
f = find(start,key);
if(f==NULL)
printf("\n key not fund");
else
{
temp = f->next->next;
free(f->next);
f->next=temp;
}
}
return(start);
}
/*definition of find function */
clist * find(clist *start, int key)
{
if(start->next->data == key)
return(start);
if(start->next->next == NULL)
return(NULL);
else
find(start->next, key);
}
void main()
{
void create_clist(clist *);
int count(clist *);
void traverse(clist *);
head=(clist *)malloc(sizeof(clist));
s=head;
create_clist(head);
printf(" \n traversing the created clist and the starting address is %u \n",
head);
traverse(head);
printf("\n number of elements in the clist %d \n", count(head));
head=delete_clist(head);
52
printf(" \n traversing the clist after delete_clistand starting address is %u Lists
\n",head);
traverse(head);
}
void create_clist(clist *start)
{
printf("inputthe element -1111 for coming oout of the loop\n");
scanf("%d", &start->data);
if(start->data == -1111)
start->next=s;
else
{
start->next=(clist*)malloc(sizeof(clist));
create_clist(start->next);
}
}
3.7 APPLICATIONS
Lists are used to maintain POLYNOMIALS in the memory. For example, we have a
function f(x)= 7x5 + 9x4 – 6x³ + 3x². Figure 3.10 depicts the representation of a
Polynomial using a singly linked list. 1000,1050,1200,1300 are memory addresses.
53
Introduction to Polynomial contains two components, coefficient and an exponent, and ‘x’ is a formal
Algorithms and
Data Structures
parameter. The polynomial is a sum of terms, each of which consists of coefficient
and an exponent. In computer, we implement the polynomial as list of structures
consisting of coefficients and an exponents.
Program 3.11 accepts a Polynomial as input. It uses linked list to represent the
Polynomial. It also prints the input polynomial along with the number of nodes in it.
3.8 SUMMARY
The advantage of Lists over Arrays is flexibility. Over flow is not a problem until the
computer memory is exhausted. When the individual records are quite large, it may be
difficult to determine the amount of contiguous storage that might be in need for the
required arrays. With dynamic allocation, there is no need to attempt to allocate in
advance. Changes in list, insertion and deletion can be made in the middle of the list,
more quickly than in the contiguous lists.
The drawback of lists is that the links themselves take space which is in addition to
the space that may be needed for data. One more drawback of lists is that they are not
suited for random access. With lists, we need to traverse a long path to reach a
desired node.
55
Introduction to
Algorithms and
Data Structures
3.9 SOLUTIONS/ANSWERS
1) void print_location(struct node *head)
{
temp=head;
while(temp->next !=NULL)
{
printf("%u", temp);
temp=temp->next;
}
printf("%u", temp);
}
4) void count_items(struct node *head)
{
int count=0;
temp=head;
while(temp->next !=NULL)
{
count++;
}
count++;
pintf("total items = %d", count);
}
5) void Is_Overflow(int max_size, int last_element_position)
{
if(last_element_position == max_size)
printf("List Overflow");
else
printf("not Overflow");
}
56