0% found this document useful (0 votes)
24 views180 pages

CS23231 DS Unit I Reg - 2023

The document covers Unit I of a course on Data Structures, focusing on linear data structures, specifically linked lists. It explains self-referential structures, their importance in dynamic memory allocation, and provides examples of singly and multiple linked lists in both C and Python. The document also includes various operations that can be performed on linked lists, such as insertion, deletion, and viewing the list.

Uploaded by

harish.s.2024.it
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views180 pages

CS23231 DS Unit I Reg - 2023

The document covers Unit I of a course on Data Structures, focusing on linear data structures, specifically linked lists. It explains self-referential structures, their importance in dynamic memory allocation, and provides examples of singly and multiple linked lists in both C and Python. The document also includes various operations that can be performed on linked lists, such as insertion, deletion, and viewing the list.

Uploaded by

harish.s.2024.it
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 180

CS23231 - Data Structures

Unit - I

Lecture Notes

(Regulations - 2023)
UNIT-I LINEAR DATA STRUCTURES – LIST 9
Self-Referential Structures, Dynamic Memory Allocation, Linked list implementation - Singly Linked List,
Doubly Linked List, Circular Linked List, Applications of List.

Self-Referential Structures, Dynamic Memory Allocation

Self-referential structure

The self-referential structure is a structure that points to the same type of structure. It contains one or
more pointers that ultimately point to the same structure.

o Structures are a user-defined data structure type in C and C++.


o The main benefit of creating structure is that it can hold the different predefined data types.
o It is initialized with the struct keyword and the structure's name followed by this struct keyword.
o We can easily take the different data types like integer value, float, char, and others within the
same structure.
o It reduces the complexity of the program.
o Using a single structure can hold the values and data set in a single place.
o In the C++ programming language, placing struct keywords is optional or not mandatory, but it is
mandatory in the C programming language.
o Self-referential structure plays a very important role in creating other data structures like Linked
list.
o In this type of structure, the object of the same structure points to the same data structure and
refers to the data types of the same structure.
o It can have one or more pointers pointing to the same type of structure as their member.
o The self-referential structure is widely used in dynamic data structures such as trees, linked
lists, etc.
Why do we require a Self-referential structure?

Self-referential structure plays a vital role in the linked list, trees, graphs, and many more data
structures.

By using the structure, we can easily implement these data structures efficiently. For defining a particular
node, the structure plays a very important role.

In a linked list, the structure is used to store the data information and the address of the next node in
the given linked list. Mainly the data part is of integer type, and the link address part is of pointer type,
which holds the address of the next node, so that it can for the Link ultimately.

Here in the linked list, we will define a common structure, which contains the data and address pointer
to carry the address of the next node, so to form the multiple nodes, we from each node using the node
structure.

Unlike a static data structure such as an array where the size of the array limits the number of elements
that can easily to inserted into the array, a self-referential structure can dynamically be expanded or
contracted.

Operations like the insertion or deletion of nodes in a self-referential structure involve straightforward
alteration of pointers.

Linked list

o A linked list is a useful data storage method, and it is very easy to implement it in C programming
Language.
o Several kinds of linked lists, including single linked lists, double linked lists, and binary trees.
o Each type is suited for certain types of data storage.
o The one thing that these lists have in common is that the links between data items are defined by
the information contained in the items themselves, in the form of pointers.
o The linked list is distinctly different from arrays, in which the links between data items result from
the layout and storage of the array.
Here, we will discuss the self-referential structure in more detail using the linked list concepts.

Let's understand the concept of self-referential structure in more detail using the example mentioned
below:

Example 1: Creating a random self-referential structure in the C programming language.

1. // Dummy Self-referential structure in C language


2. struct node // Creating a node of structure type contains data
3. // part of integer type and a pointer of structure type to
4. // hold the address of the next node
5. {
6. int d1 ; // data 1 of integer type
7. int d2 ; // data 2 of integer type
8. struct node * link ; // Self referential structure link is pointing the same
9. // structure of the type node
10. } ;
11. Int main()
12. {
13. Struct node obj; // Creating an object of the node type, this object is // consists o
f three parts one is data 1 and
14. // second is of data 2, and third is of link type pointer
15. // carries the address of the next node.
16. Return 0 ;
17. }
Example 2: Creating a random self-referential structure in a python programming language.

1. # Dummy Self-referential structure in python language


2. class node: # Creating a node that contains data
3. # part of and a pointer of node type to
4. # hold the address of the next node
5. def __init__(self):
6. self.data1=0
7. self.data2=' '
8. self.link=None # Self-referential structure link is pointing the same
9. # structure of the type node
10.
11.
12. if __name__ == '__main__':
13. ob=node()
14. # Creating a object of node type, this object is
15. # consists of three parts one is data 1 and
16. # second is of data 2 and third is of link type pointer
17. # carries the address of the next node

Types of self-referential structure


1. Single Link self-referential structure
2. Multiple Link self-referential structures

Single Link self-referential structure

In a singly linked list, there is only a single pointer that carries the address of the next node, and that
pointer variable is of the structure node type itself.

It is mainly used when we want to store the different data items by fetching out them from various
addresses and connecting all of them by storing the address of one data item into the linked part of the
other node. In this way, we can easily connect all the data items by using these connecting links.

Let's look at the working of single link self-referential structure with the help of an example:

1. // Single link self-referential structure implementation in C language


2. #include<stdio.h>
3. #include<stdlib.h>
4. struct node
5. {
6. int info ;
7. struct node *link ; // Self-referential structure link is pointing the same
8. // structure of the type node
9. };
10.
11. struct node *START = NULL ; // start pointer to control the linked list //
12. struct node* createnode() ;
13. void insertatlast() ; // insert node at last //
14. void deleteatfirst() ; // delete node at first //
15. void viewlist() ;
16. void insertatfirst() ;
17. int getlength() ;
18. int menu() ;
19. void insertafteranynode() ;
20. void deleteatlast() ;
21. void deleteatposition() ;
22.
23. struct node* createnode() // create node dynamically //
24. {
25. struct node *n ;
26. n = malloc( sizeof(struct node) ) ;
27. return ( n ) ;
28. }
29. void insertatlast()
30. {
31. struct node *temp ,*t ;
32. temp = createnode() ;
33. printf( "Enter the data in node \n " ) ;
34. scanf( " %d" , &temp->info ) ;
35. temp->link = NULL ;
36. if ( START == NULL )
37. START = temp ;
38. else
39. {
40. t = START ;
41. while ( t->link != NULL )
42. {
43. t = t->link ;
44. }
45. t->link = temp ;
46. }
47. }
48. void deleteatfirst() // delete node at first //
49. {
50. if ( START == NULL )
51. printf ( "List is empty \n " ) ;
52. else
53. {
54. struct node *q ;
55. q = START ;
56. START = START->link ;
57. free( q ) ;
58. }
59. }
60. void viewlist()
61. { struct node* t ;
62. if ( START == NULL )
63. {
64. printf ( "No List \n " ) ;
65. }
66. else
67. {
68. t = START ;
69. while ( t != NULL )
70. {
71. printf ( " %d" , t->info ) ;
72. t = t->link ;
73. }
74. }
75. }
76. void insertatfirst()
77. { struct node*New ;
78. New = createnode() ;
79. printf ( "Enter the data in node \n " ) ;
80. scanf ( " %d" , &New->info ) ;
81.
82. if ( START == NULL )
83. START = New ;
84. else
85. {
86. New->link = START ;
87. START = New ;
88. }
89. }
90. int getlength()
91. {
92. int count = 0 ;
93. struct node* t ;
94. if ( START == NULL )
95. printf ( "List is empty \n " ) ;
96. else
97. {
98. t =START ;
99. while ( t != NULL )
100. {
101. count = count + 1 ;
102. t = t->link ;
103. }
104. }
105. return count ;
106. }
107. void insertafteranynode()
108. {
109. int position ;
110. struct node* newnode ,*t ;
111. if ( START == NULL )
112. printf ( "List is empty \n " ) ;
113. else
114. {
115. printf ( "Enter position after which you want to add: \n " ) ;
116. scanf ( " %d" , &position ) ;
117. if ( position > getlength() )
118. {
119. printf ( "Wrong position \n " ) ;
120. insertafteranynode() ; // recursion //
121.
122. }
123. else
124. {
125. int i = 1 ;
126. newnode = createnode() ;
127. printf ( "Enter Data \n " ) ;
128. scanf ( " %d" , &newnode->info ) ;
129. newnode->link = NULL ;
130. if ( START == NULL )
131. START = newnode ;
132. else
133. {
134. t = START ;
135. while ( i < position )
136. {
137. t = t->link ;
138. i++ ;
139. }
140. newnode->link = t->link ;
141. t->link = newnode ;
142. }
143. }
144. }
145. }
146. void deleteatlast()
147. {
148. struct node* t , *q ;
149. if ( START == NULL )
150. {
151. printf ( "List is empty \n " ) ;
152. }
153. else
154. {
155. t = START ;
156. q = START ;
157. while ( t->link != NULL )
158. {
159. q=t;
160. t = t->link ;
161. }
162. if ( t == START )
163. {
164. START == NULL ;
165. }
166. else
167. {
168. q->link = NULL ;
169. free( t ) ;
170. }
171. }
172. }
173. void deleteatposition()
174. {
175. struct node *t , *q ;
176. int position , i = 1 ;
177. t = START ;
178. if ( START == NULL)
179. {
180. printf ( "List is empty \n " ) ;
181. }
182. else
183. {
184. printf ( "Enter position after which you want to delete: \n " ) ;
185. scanf ( " %d" , &position ) ;
186. if ( position > getlength() )
187. {
188. printf ( "Wrong position \n " ) ;
189. deleteatposition() ; // recursion //
190.
191. }
192. else
193. {
194. while ( i < position )
195. {
196. q=t;
197. t = t->link ;
198. i++ ;
199. }
200. if ( t == START )
201. {
202. START == NULL ;
203. }
204. else
205. {
206. q->link = t->link ;
207. free( t ) ;
208. }
209. }
210. }
211. }
212. int menu()
213. {
214. int ch ;
215. printf ( " \t \t \t 1.ADD NODE LAST IN LINK \n " ) ;
216. printf ( " \t \t \t 2.ADD NODE AT FIRST IN LINK \n " ) ;
217. printf ( " \t \t \t 3.VIEW LIST IN LINK \n " ) ;
218. printf ( " \t \t \t 4.DELETE NODE AT FIRST IN LINK \n " ) ;
219. printf( " \t \t \t 5. TO SEE THE LENGTH OF LIST \n " ) ;
220. printf ( " \t \t \t 6. INSERT NODE IN BETWEEN \n " ) ;
221. printf ( " \t \t \t 7.DELETE NODE AT LAST IN LINK \n " ) ;
222. printf ( " \t \t \t 8.DELETE NODE AT SPECIFIC POSITION IN LINK \n " ) ;
223. printf ( " \t \t \t 9.EXIT \n " ) ;
224. printf ( "ENTER THE CHOICE \n " ) ;
225. scanf ( " %d" , &ch ) ;
226. return( ch ) ;
227. }
228. void main()
229. { int k ;
230. while ( 1 )
231. {
232. switch ( menu() )
233. {
234. case 1 :
235. insertatlast() ;
236. break ;
237. case 2 :
238. insertatfirst() ;
239. break ;
240. case 3 :
241. viewlist() ;
242. break ;
243. case 4 :
244. deleteatfirst() ;
245. break ;
246. case 5 :
247. k = getlength() ;
248. printf ( "THE LENGTH OF THE LIST IS %d \n " , k ) ;
249. break ;
250. case 6 :
251. insertafteranynode() ;
252. break ;
253. case 7 :
254. deleteatlast() ;
255. break ;
256. case 8 :
257. deleteatposition() ;
258. break ;
259. case 9 :
260. exit( 0 ) ;
261. break ;
262. default :
263. printf ( " Not available \n " ) ;
264. }
265. }
266. }
The output of the above program is:
1. # Single link self-referential structure implementation in Python language
2. class node:
3. def __init__(self):
4. self.d1=0
5. self.d2=0
6. self.link=None
7.
8. if __name__ == '__main__':
9. obj1=node() # Node1
10.
11. # Initialization
12. obj1.link = None
13. obj1.d1 = 17
14. obj1.d2 = 14
15.
16. obj2=node() # Node2
17.
18. # Initialization
19. obj2.link = None
20. obj2.d1 = 36
21. obj2.d2 = 24
22.
23. # Linking obj1 and obj2
24. obj1.link = obj2
25.
26. # Accessing data members of obj2 using obj1
27. print(obj1.link.d1)
28. print(obj1.link.d2)
The output of the above program is:

36

24

Multiple Link self-referential structures

As the name suggests, we can easily predict that these types of the structure consist of multiple Link,
here we will make use of two pointer links of structure type which is pointing to the same structure, to
understand it better, we can connect this concept with a doubly-linked list.

In a doubly-linked list, two single pointers carry the address of the next node and the previous node, and
that pointer variable is of the structure node type itself.

It is mainly used when we want to store the different data items by fetching out them from various
addresses and connecting all of them by storing the address of one data item into the linked part of the
other node; in this way, we can easily connect all the data items by using these connecting links.

Let us look at the working of, multiple link self-referential structure with the help of an example:

1. // Multiple link self-referential structure implementation in C language


2. #include<stdio.h>
3. #include<stdlib.h>
4. struct node
5. {
6. int info ;
7. struct node *prev ; // Self-referential structure link is pointing the same
8. // structure of the type node but to the previous node
9.
10. struct node *next; // Self-referential structure link is pointing the same
11. // structure of the type node but to the next node
12.
13. } ;
14.
15. struct node * START = NULL ; // Start pointer of the list and initially it must be null, // represents th
at no node is present
16. void insertnodeatfirst() ;
17. void deleteatfirst() ;
18. void viewlist() ;
19. int menu() ;
20. void insertnodeatfirst() // Inserting the node at first
21. {
22. struct node * newnode ;
23. newnode = malloc( sizeof( struct node ) ) ;
24. printf ( "Enter Data: \n " ) ;
25. scanf ( " %d" , &newnode->info ) ;
26. newnode->prev = NULL ;
27. newnode->next = NULL ;
28. if ( START == NULL )
29. START = newnode ;
30. else
31. {
32. START->prev = newnode ;
33. newnode->next = START ;
34. START = newnode ;
35. }
36. }
37. void deleteatfirst() // deleting the first node
38. {
39. struct node * temp ;
40. if ( START == NULL )
41. printf ( "List is empty \n " ) ;
42. else
43. {
44. temp = START ;
45. START = START->next ;
46. START->prev = NULL ;
47. free( temp ) ;
48. }
49. }
50. void viewlist() // displaying all the nodes in the list
51. {
52. struct node * t ;
53. if ( START == NULL )
54. printf ( "List is empty \n " ) ;
55. else
56. {
57. t = START ;
58. while ( t != NULL )
59. {
60. printf ( " %d \n " , t->info ) ;
61. t = t->next ;
62. }
63. }
64. }
65. int menu()
66. { int n ;
67. printf ( " \t \t \t 1. VIEW LIST \n " ) ;
68. printf ( " \t \t \t 2. INSERT AT FIRST IN LIST \n " ) ;
69. printf ( " \t \t \t 3. DELETE AT FIRST IN LIST \n " ) ;
70. printf ( " \t \t \t 4. EXIT \n " ) ;
71. printf ( "ENTER YOUR CHOICE \n " ) ;
72. scanf ( " %d" , &n ) ;
73. return ( n ) ;
74. }
75. int main()
76. {
77. while ( 1 )
78. {
79. switch ( menu() )
80. {
81. case 1 :
82. viewlist() ;
83. break ;
84. case 2 :
85. insertnodeatfirst() ;
86. break ;
87. case 3 :
88. deleteatfirst() ;
89. break ;
90. case 4 :
91. exit ( 1 ) ;
92. break ;
93. default :
94. printf ( " NOT AVAILABLE \n " ) ;
95. }
96. }
97. }
The output of the above program is:
1. # Multiple link self-referential structure implementation in Python language
2. class node:
3. def __init__(self):
4. self.data = 0
5. self.prev = None
6. self.next = None
7.
8. if __name__ == '__main__':
9. obj1=node() # Node1
10.
11. # Initialization
12. obj1.prev = None
13. obj1.next = None
14. obj1.data = 15
15.
16. obj2=node() # Node2
17.
18.
19. # Initialization
20. obj2.prev = None
21. obj2.next = None
22. obj2.data = 20
23.
24. obj3 = node() # Node3
25.
26. # Initialization
27. obj3.prev = None
28. obj3.next = None
29. obj3.data = 25
30.
31. # Forward links
32. obj1.next = obj2
33. obj2.next = obj3
34.
35. # Backward links
36. obj2.prev = obj1
37. obj3.prev = obj2
38.
39. # Accessing data of obj1, obj2 and obj3 by obj1
40. print(obj1.data , end='\t')
41. print(obj1.next.data , end='\t')
42. print(obj1.next.next.data)
43.
44. # Accessing data of obj1, obj2 and obj3 by obj2
45. print(obj2.prev.data , end='\t')
46. print(obj2.data , end='\t')
47. print(obj2.next.data)
48.
49. # Accessing data of obj1, obj2 and obj3 by obj3
50. print(obj3.prev.prev.data , end='\t')
51. print(obj3.prev.data , end='\t')
52. print(obj3.data)
The output of the above program is:

15 20 25
15 20 25
15 20 25
Dynamic memory allocation in C

The concept of dynamic memory allocation in c language enables the C programmer to allocate memory
at runtime. Dynamic memory allocation in c language is possible by 4 functions of stdlib.h header file.

1. malloc()
2. calloc()
3. realloc()
4. free()

Difference between static memory allocation and dynamic memory allocation.

statStatic memory allocation dynamic memory allocation


location
c memory allocation

memory is allocated at compile time. memory is allocated at run time.

memory can't be increased while executing memory can be increased while executing
program. program.

used in array. used in linked list.

malloc() allocates single block of requested memory.

calloc() allocates multiple block of requested memory.

reallocates the memory occupied by malloc()


realloc()
or calloc() functions.

free() frees the dynamically allocated memory.


Methods used for dynamic memory allocation

malloc() function in C

The malloc() function allocates single block of requested memory.

It doesn't initialize memory at execution time, so it has garbage value initially.

It returns NULL if memory is not sufficient.

The syntax of malloc() function is given below:

1. ptr=(cast-type*)malloc(byte-size)
Test it Now
Let's see the example of malloc() function.

1. #include<stdio.h>
2. #include<stdlib.h>
3. int main(){
4. int n,i,*ptr,sum=0;
5. printf("Enter number of elements: ");
6. scanf("%d",&n);
7. ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
8. if(ptr==NULL)
9. {
10. printf("Sorry! unable to allocate memory");
11. exit(0);
12. }
13. printf("Enter elements of array: ");
14. for(i=0;i<n;++i)
15. {
16. scanf("%d",ptr+i);
17. sum+=*(ptr+i);
18. }
19. printf("Sum=%d",sum);
20. free(ptr);
21. return 0;
22. }
Output

Enter elements of array: 3


Enter elements of array: 10
10
10
Sum=30

calloc() function in C

The calloc() function allocates multiple block of requested memory.


It initially initialize all bytes to zero.

It returns NULL if memory is not sufficient.

The syntax of calloc() function is given below:

1. ptr=(cast-type*)calloc(number, byte-size)
Test it Now
Let's see the example of calloc() function.

1. #include<stdio.h>
2. #include<stdlib.h>
3. int main(){
4. int n,i,*ptr,sum=0;
5. printf("Enter number of elements: ");
6. scanf("%d",&n);
7. ptr=(int*)calloc(n,sizeof(int)); //memory allocated using calloc
8. if(ptr==NULL)
9. {
10. printf("Sorry! unable to allocate memory");
11. exit(0);
12. }
13. printf("Enter elements of array: ");
14. for(i=0;i<n;++i)
15. {
16. scanf("%d",ptr+i);
17. sum+=*(ptr+i);
18. }
19. printf("Sum=%d",sum);
20. free(ptr);
21. return 0;
22. }
Output

Enter elements of array: 3


Enter elements of array: 10
10
10
Sum=30

realloc() function in C

If memory is not sufficient for malloc() or calloc(), you can reallocate the memory by realloc() function. In
short, it changes the memory size.

Let's see the syntax of realloc() function.

1. ptr=realloc(ptr, new-size)
Test it Now
free() function in C

The memory occupied by malloc() or calloc() functions must be released by calling free() function.
Otherwise, it will consume memory until program exit.

Let's see the syntax of free() function.

1. free(ptr)
CHAPTER - 1 - INTRODUCTION TO DATA STRUCTURES

1.1 INTRODUCTION

Data structure is the way of organizing and storing data in a computer system so that
it can be used efficiently.

1.2 CHARACTERISTICS OF DATA STRUCTURES

The following points highlight the need of data structures in computer science:

1. It depicts the logical representation of data in computer memory.


2. It represents the logical relationship between the various data elements.
3. It helps in efficient manipulation of stored data elements.
4. It allows the programs to process the data in an efficient manner.

1.3 APPLICATIONS OF DATA STRUCTURES

Some of the applications of data structures are:

1. Compiler design
2. Operating system
3. Database management system
4. Statistical analysis package
5. Numerical analysis
6. Graphics
7. Artificial intelligence
8. Simulation

1.4 CLASSIFICATION OF DATA STRUCTURES

Data structures are primarily divided into two classes:

 Primitive
 Non-primitive

1.4.1 Primitive Data Structures

Primitive data structures include all the fundamental data structures that can be directly
manipulated by machine level instructions.

Some of the common primitive data structures include:

 Integer
 Character
 Real
 Boolean, etc.

1.4.2 Non-primitive Data Structures


Non-primitive data structures refer to all those data structures that are derived from
one or more primitive data structures. The objective of creating non-primitive data
structures is to form sets of homogeneous or heterogeneous data elements.

Non-primitive data structures are further categorized into two types:

 Linear
 Non-linear

1.4.3 Linear Data Structures

In linear data structures, all the data elements are arranged in a linear or sequential
fashion. Examples of linear data structures include:

 Arrays
 Stacks
 Queues
 Linked lists, etc.

1.4.4 Non-linear Data Structures

In non-linear data structures, there is no definite order or sequence in which data


elements are arranged. For instance, a non-linear data structure could arrange data
elements in a hierarchical fashion. Examples of non-linear data structures are:

 Trees
 Graphs

Data Structures

Primitive Data Non-primitive Data


Structures Structures

Linear Data Non-linear Data


Integer Real Character Boolean Structures Structures

Arrays Trees

Linked List Graphs

Stacks

Queues

Fig. 1.1 Classification of Data Structures


REVIEW QUESTIONS

1. What is data structure? How is it classified?


2. What are the various characteristics of a data structure?
3. What are primitive data structures?
4. What are non-primitive data structures?
5. What is a linear data structure?
6. What is anon-linear data structure?
7. List out the characteristics of data structure?
8. List out the areas in which data structures are applied.
9. What are the major data structures used in the following
areas: RDBMS, Network data model and Hierarchical data
model.
10. Write any two data structures used in Operating System?
CHAPTER - 2 - LIST ADT

1.1 ABSTRACT DATA TYPE (ADT)

An abstract data type (ADT) is a set of objects together with a set of operations.
Abstract data types are mathematical abstractions. Objects such as lists, sets, and graphs,
along with their operations, can be viewed as abstract data types.

1.2 LIST ADT

List is an ordered set of elements. For any list except the empty list, we say that A i+1
follows (or succeeds) Ai (i<N) and that Ai-1 precedes Ai (i>1). The first element of the list is
A1, and the last element is AN.

Some popular operations are printList, makeEmpty, find, insert, remove, findKth,
next, previous.

Fig. 2.1. A linked list

1.3 OPERATIONS OF THE LIST ADT

 printList – contents of the list is displayed


 makeEmpty – makes the list empty
 find – returns the position of the first occurrence of an item
 insert – insert some element from some position in the list
 remove – remove some element from some position in the list
 findKth – returns the element in some position (specified as an argument)
 next – return the position of the successor
 previous – return the position of the predecessor

1.4 DIFFERENT WAYS TO IMPLEMENT LIST

Lists are implemented using:

 Array
 Linked list
1.5 ARRAYS

An array implementation allows print_list and find to be carried out in linear time,
which is as good as can be expected, and the find_kth operation takes constant time.
However, insertion and deletion are expensive. For example, inserting at position 0 (which
amounts to making a new first element) requires first pushing the entire array down one
spot to make room, whereas deleting the first element requires shifting all the elements in
the list up one, so the worst case of these operations is O(n). On average, half the list needs
to be moved for either operation, so linear time is still required. Merely building a list by n
successive inserts would require quadratic time.
Because the running time for insertions and deletions is so slow and the list size
must be known in advance, simple arrays are generally not used to implement lists.

1.6 LINKED LIST

The linked list consists of a series of structures, which are not necessarily adjacent in
memory. Each structure contains the element and a pointer to a structure containing its
successor. We call this the next pointer. The last cell's next pointer points to NULL.

Data Element Next Pointer


Node

1.7 ADVANTAGES OF LINKED LISTS

Some of the key advantages of linked lists are:

1. Linked lists facilitate dynamic memory management by allowing elements to


be added or deleted at any time during program execution.
2. The use of linked lists ensures efficient utilization of memory space as only that
much amount of memory space is reserved as is required for storing the list
elements.
3. It is easy to insert or delete elements in a linked list, unlike arrays, which
require shuffling of other elements with each insert and delete operation.

1.8 DISADVANTAGES OF LINKED LISTS

Apart from the advantages, linked lists also possess certain limitations, which are:

1. A linked list element requires more memory space in comparison to an array


element because it has to also store the address of the next element in the list.
2. Accessing an element is a little more difficult in linked lists than arrays because
unlike arrays, there is no index identifier associated with each list element. Thus,
to access a linked list element, it is mandatory to traverse all the preceding
elements.

1.9 TYPES OF LINKED LIST

Depending on the manner in which its nodes are interconnected with each other,
linked lists are categorized into the following types:

 Singly linked list


 Doubly linked list
 Circular linked list
REVIEW QUESTIONS

1. What is an Abstract Data Type (ADT)? (or) Define Abstract Data Type (ADT). (or) Define
ADT and give an example. (or) What do you mean by abstract data type? (or) What is an
abstract data type? Give any two examples. (or) Give an example for abstract data type.
(or) Define abstract data type. List out few.
2. What is advantage of an ADT?
3. Define a 'list'; Mention any two operations that are performed on a list. (or) Define
List Abstract Data Type with example.
4. List out the operations of the list ADT. (or) Which operations are supported by the list ADT?
5. What are the different ways to implement list?
6. What are the advantages of linked list over arrays?
7. What are the disadvantages of linked list?
8. List the various types of linked lists.
CHAPTER - 3 - ARRAY BASED IMPLEMENTATION OF LIST

3.1 INTRODUCTION

Array is a collection of specific number of data stored in consecutive memory locations.

Fig. 3.1. Array example

3.2 OPERATIONS ON ARRAY

 Insert
 Delete
 Traversal
 Sorting
 Searching

3.3 INSERTION

Insertion is the task of adding an element into an existing array. If an element is to be


inserted at the end of the array, then it can be simply achieved by storing the new element
one position to the right of the last element. Alternatively, if an element is required to be
inserted at the middle, then this will require all the subsequent elements to be moved one
place to the right.

Example

Fig. 3.2. Array insertion


Algorithm to Insert an Element in an Array

Insert(a[], p, e)

Step 1 : Start.
Step 2 : Set i =
n.
Step 3 : Repeat Steps 4 to 5 while i >=
p. Step 4 : Set a[i+1] = a[i].
Step 5 : Set i = i – 1.
Step 6 : Set a[p] = e.
Step 7 : Set n = n +
1. Step 8 : Stop.

Routine to Insert an Element in an Array

void Insert(int a[], int p, int e)


{
int i;
for(i = n; i >= p; i--)
a[i + 1] = a[i]; a[p] = e;
n = n + 1;
}

3.4 DELETION

Deletion is the task of removing an element from the array. The deletion of element
from the end is quite simple and can be achieved by mere updation of index identifier.
However, to remove an element from the middle, one must move all the elements present
to the right of the point of deletion, one position to the left.

Example

Fig. 3.3. Array deletion


Algorithm to Delete an Element from an Array

Delete(a[], p)
Step 1 : Start.
Step 2 : Set i =
p.
Step 3 : Repeat Steps 4 to 5 while i <
n. Step 4 : Set a[i] = a[i+1].
Step 5 : Set i = i +
1. Step 6 : Set n = n
- 1. Step 7 : Stop.

Routine to Delete an Element from an Array

void Delete(int a[], int p)


{
int i;
for(i = p; i < n; i++) a[i] = a[i + 1];
n = n - 1;
}

3.5 TRAVERSAL

While working with arrays, it is often required to access the array elements; that is,
reading values from the array. This is achieved with the help of array traversal. It involves
visiting the array elements and storing or retrieving values from it.

Some of the typical situations where array traversal may be required are:

 Printing array elements


 Searching an element in the array
 Sorting an array

Algorithm to Traverse an Array

Traverse(a[])
Step 1 : Start.
Step 2 : Set i =
0.
Step 3 : Repeat Steps 4 to 5 while i <
n. Step 4 : Access a[i].
Step 5 : Set i = i + 1.
Step 6 : Stop.

Routine to Traverse an Array

void Traverse(int a[])


{
int i;
for(i = 0; i < n; i++)
printf("%d\t", a[i]);
}
3.6 SEARCHING

Searching is the process of traversing an array to find out if a specific element is


present in the array or not. If the search is successful, the index location of the element is
returned.

Example

Fig. 3.4. Array Searching

Algorithm to Search an element in an Array

Search(a[], e)

Step 1 : Start.
Step 2 : Set i =
0.
Step 3 : Repeat Steps 4 to 6 while i < n.
Step 4 : if e = a[i] goto Step 5 else goto Step
6. Step 5 : Set flag = 1 and goto Step 7.
Step 6 : Set i = i + 1.
Step 7 : if flag = 1 goto Step 8 else goto Step
9. Step 8 : Print i and goto step 10.
Step 9 : Print i.
Step 10: Print “Unsuccesful.”.
Step 11: Stop.

Routine to Search an element in an Array

void Search(int a[], int e)


{
int i, flag = 0;
for(i = 0; i < n; i++)
{
if(e == a[i])
{
flag = 1;
break;
}
}
if(flag == 1)
printf("Successful. Element %d is at location %d",e,i);
else
printf("Unsuccessful.");
}
3.7 SORTING

The sorting operation arranges the elements of an array in a specific order or


sequence. Sorting involves comparing the array elements with each other and shuffling them
until all the elements are sorted.

Example

Fig. 3.5. Array Sorting

Algorithm to Sort the elements in an Array

Sort(a[])

Step 1 : Start.
Step 2 : Set i =
0.
Step 3 : Repeat Steps 4 to 11 while i < n-1.
Step 4 : Set j = i+1.
Step 5 : Repeat Steps 6 to 10 while j < n.
Step 6 : if a[i] > a[j] goto Step 7 else goto Step
10. Step 7 : Set t = a[i].
Step 8 : Set a[i] =
a[j]. Step 9 : Set a[j]
= t.
Step 10: Set j = j +
1. Step 11: Set i = i
+ 1. Step 12: Stop.
Routine to Sort the elements in an Array

void Sort(int a[])


{
int i, j, t;
for(i = 0; i < n-1; i++)
{
for(j = i + 1; j < n; j++)
{
if(a[i] > a[j])
{
t = a[i]; a[i] =
a[j]; a[j] = t;
}
}
}
}

3.8 PROGRAM

#include <stdio.h>

int n = 0;

void Insert(int a[], int p, int e);


void Delete(int a[], int p); void
Search(int a[], int e); void
Traverse(int a[]);
void Sort(int a[]);

int main()
{
int a[5], ch, e, p;
printf("1.Insert \n2.Delete \n3.Search"); printf("\
n4.Traverse \n5.Sort \n6.Exit\n"); do
{
printf("\nEnter your choice : ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the position : ");
scanf("%d", &p);
printf("Enter the element : ");
scanf("%d", &e);
Insert(a, p, e);
case 2:
printf("Enter the position : ");
scanf("%d", &p);
Delete(a, p); break;
case 3:
printf("Enter the element : ");
scanf("%d", &e);
Search(a, e); break;
case 4:
printf("The elements are : ");
Traverse(a);
break;
case 5:
Sort(a);
break;
}
} while(ch <= 5);
return 0;
}

void Insert(int a[], int p, int e)


{
int i;
for(i = n; i >= p; i--)
a[i + 1] = a[i]; a[p] = e;
n = n + 1;
}

void Delete(int a[], int p)


{
int i;
for(i = p; i < n; i++) a[i] = a[i +
1];
n = n - 1;
}

void Search(int a[], int e)


{
int i, flag = 0;
for(i = 0; i < n; i++)
{
if(e == a[i])
{
flag = 1;
break;
}
}
if(flag == 1)
printf("Successful. Element %d is at location %d", e, i);
else
printf("Unsuccessful.");
}

void Traverse(int a[])


{
int i;
for(i = 0; i < n; i++)
printf("%d\t", a[i]);
}

void Sort(int a[])


{
int i, j, t;
for(i = 0; i < n-1; i++)
{
for(j = i + 1; j < n; j++)
{
if(a[i] > a[j])
{
t = a[i]; a[i] =
a[j]; a[j] = t;
}
}
}
}

OUTPUT

1.Insert
2.Delete
3.Search
4.Traverse
5.Sort 6.Exit

Enter your choice : 1 Enter


the position : 0 Enter the
element : 10

Enter your choice : 4 The


elements are : 10 Enter
your choice : 1 Enter the
position : 0 Enter the
element : 20
Enter your choice : 4
The elements are : 20 10

Enter your choice : 1 Enter


the position : 1 Enter the
element : 25

Enter your choice : 4


The elements are : 20 25 10
Enter your choice : 2 Enter
the position : 1

Enter your choice : 4


The elements are : 20 10
Enter your choice : 3 Enter
the element : 10
Successful. Element 10 is at location 1

Enter your choice : 3 Enter


the element : 25
Unsuccessful.
Enter your choice : 5

Enter your choice : 4


The elements are : 10 20
Enter your choice : 6
REVIEW QUESTIONS

1. What is an array?
2. What are the two basic operations on arrays?
3. What are the limitations of list implemented by array?
CHAPTER - 4 - LINKED LIST IMPLEMENTATION - SINGLY LINKED LISTS

1.1 INTRODUCTION

A singly linked list is a linked list in which each node contains only one link field
pointing to the next node in the list.

Fig. 4.1 Singly Linked List

Fig. 4.2 Singly Linked List with Header

1.2 TYPE DECLARATIONS FOR SINGLY LINKED LIST

struct node
{
int Element;
struct node *Next;
};
typedef struct node Node;

1.3 EMPTY LIST WITH HEADER

Example

Fig. 4.3 Empty List with Header

Algorithm

IsEmpty(List)

Step 1 : Start.
Step 2 : If ListNext = NULL goto Step 3 else goto Step
4. Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.
Routine

int IsEmpty(Node *List)


{
if(List->Next == NULL)
return 1;
else
return 0;
}

1.4 CURRENT POSITION IS LAST

Example

Position
Fig. 4.4 Current Position is the Last in a Linked List

Algorithm

IsLast(Position)

Step 1 : Start.
Step 2 : If PositionNext = NULL goto Step 3 else goto Step
4. Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.

Routine to Check whether the Current Position is Last

int IsLast(Node *Position)


{
if(Position->Next == NULL)
return 1;
else
return 0;
}

1.5 FIND

1.5.1 Find

Example
Find(List, 30)
Position
Algorithm

Find(List, x)

Step 1 : Start.
Step 2 : Set Position = ListNext.
Step 3 : Repeat the Step 4 until Position != NULL and PositionElement != x.
Step 4 : Set Position = PositionNext.
Step 5 : Return Position.
Step 6 : Stop.

Routine

Node *Find(Node *List, int x)


{
Node *Position; Position =
List->Next;
while(Position != NULL && Position->Element != x) Position = Position-
>Next;
return Position;
}

1.5.2 FindPrevious

To avoid the problems associated with deletions, we need to write a routine


FindPrevious, which will return the position of the predecessor of the cell we wish to delete.
If we use a header, then if we wish to delete the first element in the list, FindPrevious will
return the position of the header.

Example

FindPrevious(List, 30)

Position X

Algorithm

FindPrevious(List, x)

Step 1 : Start.
Step 2 : Set Position = List.
Step 3 : Repeat the Step 4 until PositionNext != NULL and PositionNextElement
!= x.
Step 4 : Set Position = PositionNext.
Step 5 : Return Position.
Step 6 : Stop.
Routine

Node *FindPrevious(Node *List, int x)


{
Node *Position;
Position = List;
while(Position->Next != NULL && Position->Next->Element != x) Position =
Position->Next;
return Position;
}

1.5.3 FindNext

Example

FindNext(List, 20)

X, Position PositionNext

Algorithm

FindNext(List, x)

Step 1 : Start.
Step 2 : Set Position = Find(List, x).
Step 3 : Return PositionNext.
Step 4 : Stop.

Routine

Node *FindNext(Node *List, int x)


{
Node *Position;
Position = Find(List, x);
return Position->Next;
}

1.6 TRAVERSE THE LIST

Example
B.BHUVANESWARAN | AP (SG) | CSE | Rajalakshmi Engineering College
Algorithm

Traverse(List)

Step 1 : Start.
Step 2 : If !IsEmpty = TRUE goto Step 3 else goto Step
8. Step 3 : Set Position = List.
Step 4 : Repeat the Steps 5-6 until PositionNext != NULL.
Step 5 : Set Position = PositionNext.
Step 6 : Display PositionElement.
Step 7 : Goto Step 9.
Step 8 : Display “List is
empty”. Step 9 : Stop.

Routine

void Traverse(Node *List)


{
if(!IsEmpty(List))
{
Node *Position; Position
= List;
while(Position->Next != NULL)
{
Position = Position->Next;
printf("%d\t", Position->Element);
}
printf("\n");
}
else
printf("List is empty...!");
}

1.7 INSERT

The insert command requires obtaining a new cell from the system by using an malloc
call and then executing two pointer maneuvers.

We will pass an element to be inserted along with the list L and a position P. Our
particular insertion routine will insert an element after the position implied by P. This
decision is arbitrary and meant to show that there are no set rules for what insertion does.
It is quite possible to insert the new element into position P (which means before the
element currently in position p), but doing this requires knowledge of the element before
position P. This could be obtained by a call to Find.

Insertion

 Insert an element at the beginning


 Insert an element at the end
 Insert an element in the middle
1.7.1 Insert an Element at the Beginning

Example

The general idea is shown in Figure. The dashed line represents the old pointer.

InsertBeg(List, 5)

NewNode

Algorithm

InsertBeg(List, e)

Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : Set NewNodeElement = e.
Step 4 : If List = NULL, then goto Step 5 else goto Step
6. Step 5 : Set NewNodeNext = NULL and goto Step 7.
Step 6 : Set NewNodeNext = ListNext.
Step 7 : Set ListNext = NewNode.
Step 8: Stop.

Routine

void InsertBeg(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
NewNode->Element = e; if(IsEmpty(List))
NewNode->Next = NULL;
else
NewNode->Next = List->Next;
List->Next = NewNode;
}

1.7.2 Insert an Element at the End

Example
InsertLast(List, 45)

Position NewNode

Algorithm

InsertLast(List, e)
Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : Set NewNodeElement = e.
Step 4 : Set NewNodeNext = NULL.
Step 5 : If List = NULL, then goto Step 6 else goto Step
7. Step 6 : Set ListNext = NewNode and goto Step 11.
Step 7 : Set Position = List.
Step 8 : Repeat the Step 9 until PositionNext != NULL.
Step 9 : Set Position = PositionNext.
Step 10: Set PositionNext = NewNode.
Step 11: Stop.

Routine

void InsertLast(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
Node *Position;
NewNode->Element = e;
NewNode->Next = NULL;
if(IsEmpty(List))
List->Next = NewNode;
else
{
Position = List;
while(Position->Next != NULL) Position =
Position->Next;
Position->Next = NewNode;
}
}

1.7.3 Insert an Element in the Middle

Example
InsertMid(List, 20, 25)

NewNode

Position

Algorithm

InsertMid(List, p, e)

Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : Set Position = Find(List, p).
Step 4 : Set NewNodeElement = e.
Step 5 : Set NewNodeNext = PositionNext.
Step 6 : Set PositionNext = NewNode.
Step 7 : Stop.

Routine

void InsertMid(Node *List, int p, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
Position = Find(List, p);
NewNode->Element = e;
NewNode->Next = Position->Next;
Position->Next = NewNode;
}

1.8 DELETE

The delete command can be executed in one pointer change. Our routine will delete
some element X in list L. We need to decide what to do if x occurs more than once or not at
all. Our routine deletes the first occurrence of x and does nothing if x is not in the list. To
do this, we find p, which is the cell prior to the one containing x, via a call to FindPrevious.

1.8.1 Delete an Element from the Beginning

Example
DeleteBeg(List)

TempNode

Algorithm

DeleteBeg(List, e)
Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
7. Step 3 : Set TempNode = ListNext.
Step 4 : Set ListNext = TempNodeNext.
Step 5 : Display the TempNodeElement.
Step 6 : Delete TempNode and goto Step 8.
Step 7 : Display “List is Empty”.
Step 8: Stop.

Routine

void DeleteBeg(Node *List)


{
if(!IsEmpty(List))
{
Node *TempNode;
TempNode = List->Next;
List->Next = TempNode->Next;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

1.8.2 Delete an Element from the End

Example

DeleteEnd(List)
Position TempNode
Algorithm

DeleteEnd(List)

Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
10. Step 3 : Set Position = List.
Step 4 : Repeat the Step 5 until PositionNext != NULL.
Step 5 : Set Position = PositionNext.
Step 6 : Set TempNode = PositionNext.
Step 7 : Set PositionNext = NULL.
Step 8 : Display TempNodeElement.
Step 9 : Delete TempNode and goto Step
11. Step 10: Display “List is Empty”.
Step 11: Stop.

Routine

void DeleteEnd(Node *List)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = List;
while(Position->Next->Next != NULL)
Position = Position->Next;
TempNode = Position->Next;
Position->Next = NULL;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}
1.8.3 Delete an Element from the Middle

Example

DeleteMid(List, 30)
TempNode

Position

Algorithm

DeleteMid(List, e)
Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
9. Step 3 : Set Position = FindPrevious(List, e).
Step 4 : If !Islast(Position) = True, then goto Step 5 else goto Step 10.
Step 5 : Set TempNode = PositionNext.
Step 6 : Set PositionNext = TempNodeNext.
Step 7 : Display the TempNodeElement.
Step 8 : Delete TempNode and goto Step
10. Step 9 : Display “List is Empty”.
Step 10: Stop.

Routine

void DeleteMid(Node *List, int e)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = FindPrevious(List, e);
if(!IsLast(Position))
{
}
else

}
T Node = Position->Next; Position->Next =
e TempNode->Next;
m printf("The deleted item is %d\n", TempNode->Element);
p free(TempNode);
printf("List is empty...!\n");
}

4.9. PROGRAM

/* Implementation of singly linked list - SLL.C */

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

struct node
{
int Element;
struct node *Next;
};
typedef struct node Node;

int IsEmpty(Node *List);


int IsLast(Node *Position);
Node *Find(Node *List, int x);
Node *FindPrevious(Node *List, int x); Node
*FindNext(Node *List, int x); void
InsertBeg(Node *List, int e); void
InsertLast(Node *List, int e);
void InsertMid(Node *List, int p, int e);
void DeleteBeg(Node *List);
void DeleteEnd(Node *List);
void DeleteMid(Node *List, int e);
void Traverse(Node *List);

int main()
{
Node *List = malloc(sizeof(Node)); List-
>Next = NULL;
Node *Position;
int ch, e, p;
printf("1.Insert Beg \n2.Insert Middle \n3.Insert End"); printf("\n4.Delete Beg \
n5.Delete Middle \n6.Delete End"); printf("\n7.Find \n8.Traverse \n9.Exit\n");
do
{
printf("Enter your choice : ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the element : ");
scanf("%d", &e); InsertBeg(List, e);
break;
case 2:
printf("Enter the position element : ");
scanf("%d", &p);
printf("Enter the element : ");
scanf("%d", &e); InsertMid(List, p, e);
break;
case 3:
printf("Enter the element : ");
scanf("%d", &e); InsertLast(List, e);
break;
case 4:
DeleteBeg(List);
break;
case 5:
printf("Enter the element : ");
scanf("%d", &e); DeleteMid(List, e);
break;
case 6:
DeleteEnd(List);
break;
case 7:
printf("Enter the element : ");
scanf("%d", &e); Position =
Find(List, e); if(Position !=
NULL)
printf("Element found...!\n");
else
printf("Element not found...!\n");
break;
case 8:
Traverse(List);
break;
}
} while(ch <= 8);

return 0;
}

int IsEmpty(Node *List)


{
if(List->Next == NULL)
return 1;
else
return 0;
}
int IsLast(Node *Position)
{
if(Position->Next == NULL)
return 1;
else
return 0;
}
Node *Find(Node *List, int x)
{
Node *Position; Position =
List->Next;
while(Position != NULL && Position->Element != x) Position =
Position->Next;
return Position;
}
Node *FindPrevious(Node *List, int x)
{
Node *Position;
Position = List;
while(Position->Next != NULL && Position->Next->Element != x) Position =
Position->Next;
return Position;
}
Node *FindNext(Node *List, int x)
{
Node *Position;
Position = Find(List, x);
return Position->Next;
}

void InsertBeg(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
NewNode->Element = e;

if(IsEmpty(List))
NewNode->Next = NULL;
else
NewNode->Next = List->Next;
List->Next = NewNode;
}

void InsertLast(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
NewNode->Element = e;
NewNode->Next = NULL;

if(IsEmpty(List))
List->Next = NewNode;
else
{
Position = List;
while(Position->Next != NULL) Position =
Position->Next;
Position->Next = NewNode;
}
}

void InsertMid(Node *List, int p, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
Position = Find(List, p);
NewNode->Element = e;
NewNode->Next = Position->Next;
Position->Next = NewNode;
}
void DeleteBeg(Node *List)
{
if(!IsEmpty(List))
{
Node *TempNode;
TempNode = List->Next;
List->Next = TempNode->Next;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

void DeleteEnd(Node *List)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = List;
while(Position->Next->Next != NULL)
Position = Position->Next;
TempNode = Position->Next;
Position->Next = NULL;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

void DeleteMid(Node *List, int e)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = FindPrevious(List, e);
if(!IsLast(Position))
{
TempNode = Position->Next; Position-
>Next = TempNode->Next;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
}
else
printf("List is empty...!\n");
}
void Traverse(Node *List)
{
if(!IsEmpty(List))
{
Node *Position;
Position = List;
while(Position->Next != NULL)
{
Position = Position->Next;
printf("%d\t", Position->Element);
}
printf("\n");
}
else
printf("List is empty...!\n");
}
OUTPUT

1. Insert Beg
2. Insert Middle
3. Insert End
4. Delete Beg
5. Delete Middle
6. Delete End
7.Find
8.Traverse
9.Exit
Enter your choice : 1
Enter the element : 40
Enter your choice : 1
Enter the element : 30
Enter your choice : 1
Enter the element : 20
Enter your choice : 1
Enter the element : 10
Enter your choice : 8
10 20 30 40
Enter your choice : 7
Enter the element : 30
Element found...!
Enter your choice : 1
Enter the element : 5
Enter your choice : 8
5 10 20 30 40
Enter your choice : 3
Enter the element : 45
Enter your choice : 8
5 10 20 30 40 45
Enter your choice : 2
Enter the position elem ent : 20
Enter the element : 25
Enter your choice : 8
5 10 20 25 30 40 45
Enter your choice : 4
The deleted item is 5
Enter your choice : 8
10 20 25 30 40 45
Enter your choice : 6
The deleted item is 45
Enter your choice : 8
10 20 25 30 40
Enter your choice : 5
Enter the element : 30
The deleted item is 30
Enter your choice : 8
10 20 25 40
Enter your choice : 9

REVIEW QUESTIONS

1. What is a singly linked list?


2. Should arrays or linked list be used for the following types of applications? Justify
your answer.
(a) Many search operations in sorted list.
(b) Many search operations in unsorted list.
CHAPTER - 5 - CIRCULAR LINKED LISTS

5.1 INTRODUCTION

A popular convention is to have the last cell keep a pointer back to the first. This can
be done with or without a header (if the header is present, the last cell points to it), and
can also be done with doubly linked lists (the first cell's previous pointer points to the last
cell). This clearly affects some of the tests, but the structure is popular in some applications.

In circular linked list the pointer of the last node points to the first node. Circular
linked list can be implemented as singly linked list and doubly linked list with or without
headers.

5.2 IMPLEMENTATION

A singly linked circular list is a linked list in which the last node of the list points to the
first node.

Fig. 5.1 Singly Linked Circular List

Fig. 5.2. Singly Linked Circular List with Header

5.3 TYPE DECLARATIONS FOR LINKED LIST

struct node
{
int Element;
struct node *Next;
};
typedef struct node Node;
5.4. EMPTY SINGLY LINKED CIRCULAR LIST WITH HEADER

Example

Fig. 5.3 Empty Singly Linked Circular List with Header

Algorithm

IsEmpty(List)

Step 1 : Start.
Step 2 : If ListNext = LIST goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.

Routine

int IsEmpty(Node *List)


{
if(List->Next == List)
return 1;
else
return 0;
}

5.5 CURRENT POSITION IS LAST

Example

Position
Fig. 5.4 Current Position is the Last in a Singly Linked Circular List

Algorithm

IsLast(Position, List)
Step 1 : Start.
Step 2 : If PositionNext = List goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.

Routine to Check whether the Current Position is Last

int IsLast(Node *Position, Node *List)


{
if(Position->Next == List)
return 1;
else
return 0;
}

5.6 FIND

5.6.1 Find

Example
Find(List, 30)
Position

Algorithm

Find(List, x)

Step 1 : Start.
Step 2 : Set Position = ListNext.
Step 3 : Repeat the Step 4 until Position != List and PositionElement !=
x. Step 4 : Set Position = PositionNext.
Step 5 : Return Position.
Step 6 : Stop.

Routine

Node *Find(Node *List, int x)


{
Node *Position; Position =
List->Next;
while(Position != List && Position->Element != x) Position = Position-
>Next;
return Position;
}
5.6.2 FindPrevious

To avoid the problems associated with deletions, we need to write a routine


FindPrevious, which will return the position of the predecessor of the cell we wish to delete.
If we use a header, then if we wish to delete the first element in the list, FindPrevious will
return the position of the header.

Example

FindPrevious(List, 30)
Position X

Algorithm

FindPrevious(List, x)

Step 1 : Start.
Step 2 : Set Position = List.
Step 3 : Repeat the Step 4 until PositionNext != List and
PositionNextElement!=x.
Step 4 : Set Position = PositionNext.
Step 5 : Return Position.
Step 6 : Stop.

Routine

Node *FindPrevious(Node *List, int x)


{
Node *Position; Position = List;
while(Position->Next != List && Position->Next->Element != x) Position = Position->Next;
return Position;
}
5.6.3 FindNext

Example

FindNext(List, 20)
X, Position PositionNext

Algorithm

FindNext(List, x)

Step 1 : Start.
Step 2 : Set Position = Find(List, x).
Step 3 : Return PositionNext.
Step 4 : Stop.

Routine

Node *FindNext(Node *List, int x)


{
Node *Position;
Position = Find(List, x);
return Position->Next;
}

5.7 TRAVERSE THE LIST

Example

Algorithm

Traverse(List)

Step 1 : Start.
Step 2 : If !IsEmpty = TRUE goto Step 3 else goto Step
8. Step 3 : Set Position = List.
Step 4 : Repeat the Steps 5-6 until PositionNext != List.
Step 5 : Set Position = PositionNext.
Step 6 : Display PositionElement.
Step 7 : Goto Step 9.
Step 8 : Display “List is
empty”. Step 9 : Stop.

Routine

void Traverse(Node *List)


{
if(!IsEmpty(List))
{
Node *Position; Position
= List;
while(Position->Next != List)
{
Position = Position->Next;
printf("%d\t", Position->Element);
}
printf("\n");
}
else
printf("List is empty...!\n");
}

5.8 INSERT

The insert command requires obtaining a new cell from the system by using an malloc
call and then executing two pointer maneuvers.

We will pass an element to be inserted along with the list L and a position P. Our
particular insertion routine will insert an element after the position implied by P. This
decision is arbitrary and meant to show that there are no set rules for what insertion does.
It is quite possible to insert the new element into position P (which means before the
element currently in position p), but doing this requires knowledge of the element before
position P. This could be obtained by a call to Find.

Insertion

 Insert an element at the beginning


 Insert an element at the end
 Insert an element in the middle

5.8.1 Insert an Element at the Beginning

Example

The general idea is shown in Figure. The dashed line represents the old pointer.
InsertBeg(List, 5)

NewNode

Algorithm

InsertBeg(List, e)

Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 4 : Set NewNodeElement = e.
Step 5 : Set NewNodeNext = ListNext.
Step 6 : Set ListNext = NewNode.
Step 7: Stop.

Routine

void InsertBeg(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
NewNode->Element = e;
NewNode->Next = List->Next;
List->Next = NewNode;
}
5.8.2 Insert an Element at the End

Example

InsertLast(List, 45)
Position NewNode

Algorithm

InsertLast(List, e)
Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : Set NewNodeElement = e.
Step 4 : If List = NULL, then goto Step 5 else goto Step
7. Step 5 : Set NewNodeNext = List.
Step 6 : Set ListNext = NewNode and goto Step 12.
Step 7 : Set Position = List.
Step 8 : Repeat the Step 9 until PositionNext != List.
Step 9 : Set Position = PositionNext.
Step 10: Set PositionNext = NewNode.
Step 11: Set NewNodeNext = List.
Step 12: Stop.

Routine

void InsertLast(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
NewNode->Element = e;
if(IsEmpty(List))
{
NewNode->Next = List;
List->Next = NewNode;
}
else
{
Position = List;
while(Position->Next != List) Position =
Position->Next;
Position->Next = NewNode;
NewNode->Next = List;
}
}

5.8.3 Insert an Element in the Middle

Example

InsertMid(List, 20, 25)


Position NewNode

Algorithm

InsertMid(List, p, e)

Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : Set Position = Find(List, p).
Step 4 : Set NewNodeElement = e.
Step 5 : Set NewNodeNext = PositionNext.
Step 6 : Set PositionNext = NewNode.
Step 7 : Stop.
Routine

void InsertMid(Node *List, int p, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
Position = Find(List, p);
NewNode->Element = e;
NewNode->Next = Position->Next;
Position->Next = NewNode;
}

5.9 DELETE

The delete command can be executed in one pointer change. Our routine will delete
some element X in list L. We need to decide what to do if x occurs more than once or not at
all. Our routine deletes the first occurrence of x and does nothing if x is not in the list. To
do this, we find p, which is the cell prior to the one containing x, via a call to FindPrevious.

5.9.1 Delete an Element from the Beginning

Example

DeleteBeg(List)
TempNode

Algorithm

DeleteBeg(List, e)
Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
7. Step 3 : Set TempNode = ListNext.
Step 4 : Set ListNext = TempNodeNext.
Step 5 : Display the TempNodeElement.
Step 6 : Delete TempNode and goto Step 8.
Step 7 : Display “List is Empty”.
Step 8: Stop.
Routine

void DeleteBeg(Node *List)


{
if(!IsEmpty(List))
{
Node *TempNode;
TempNode = List->Next;
List->Next = TempNode->Next;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

5.9.2 Delete an Element from the End

Example

DeleteEnd(List)

Position TempNode

Algorithm

DeleteEnd(List)

Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
10. Step 3 : Set Position = List.
Step 4 : Repeat the Step 5 until PositionNext != List.
Step 5 : Set Position = PositionNext.
Step 6 : Set TempNode = PositionNext.
Step 7 : Set PositionNext = List.
Step 8 : Display TempNodeElement.
Step 9 : Delete TempNode and goto Step
11. Step 10: Display “List is Empty”.
Step 11: Stop.

Routine

void DeleteEnd(Node *List)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = List;
while(Position->Next->Next != List) Position
= Position->Next;
TempNode = Position->Next;
Position->Next = List;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

5.9.3 Delete an Element from the Middle

Example

DeleteMid(List, 30)
Position TempNode
Algorithm

DeleteMid(List, e)
Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
9. Step 3 : Set Position = FindPrevious(List, e).
Step 4 : If !Islast(Position, List) = True, then goto Step 5 else goto Step
10. Step 5 : Set TempNode = PositionNext.
Step 6 : Set PositionNext = TempNodeNext.
Step 7 : Display the TempNodeElement.
Step 8 : Delete TempNode and goto Step
10. Step 9 : Display “List is Empty”.
Step 10: Stop.

Routine

void DeleteMid(Node *List, int e)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = FindPrevious(List, e);
if(!IsLast(Position, List))
{
TempNode = Position->Next; Position-
>Next = TempNode->Next;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
}
else
printf("List is empty...!\n");
}

5.10 PROGRAM

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

struct node
{
int Element;
struct node *Next;
};
typedef struct node Node;

int IsEmpty(Node *List);


int IsLast(Node *Position, Node *List); Node
*Find(Node *List, int x);
Node *FindPrevious(Node *List, int x);
Node *FindNext(Node *List, int x); void
InsertBeg(Node *List, int e); void
InsertLast(Node *List, int e);
void InsertMid(Node *List, int p, int e);
void DeleteBeg(Node *List);
void DeleteEnd(Node *List);
void DeleteMid(Node *List, int e);
void Traverse(Node *List);

int main()
{
Node *List = malloc(sizeof(Node)); List-
>Next = List;
Node *Position;
int ch, e, p;
printf("1.Insert Beg \n2.Insert Middle \n3.Insert End"); printf("\n4.Delete Beg \
n5.Delete Middle \n6.Delete End"); printf("\n7.Find \n8.Traverse \n9.Exit\n");
do
{
printf("Enter your choice : ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the element : ");
scanf("%d", &e); InsertBeg(List, e);
break;
case 2:
printf("Enter the position element : ");
scanf("%d", &p);
printf("Enter the element : ");
scanf("%d", &e); InsertMid(List, p, e);
break;
case 3:
printf("Enter the element : ");
scanf("%d", &e); InsertLast(List, e);
break;
case 4:
DeleteBeg(List);
break;
case 5:
printf("Enter the element : ");
scanf("%d", &e); DeleteMid(List, e);
break;
case 6:
DeleteEnd(List);
break;
case 7:
printf("Enter the element : ");
scanf("%d", &e); Position =
Find(List, e); if(Position != List)
printf("Element found...!\n");
else
printf("Element not found...!\n");
break;
case 8:
Traverse(List);
break;
}
} while(ch <= 8);

return 0;
}

int IsEmpty(Node *List)


{
if(List->Next == List)
return 1;
else
return 0;
}

int IsLast(Node *Position, Node *List)


{
if(Position->Next == List)
return 1;
else
return 0;
}

Node *Find(Node *List, int x)


{
Node *Position; Position =
List->Next;
while(Position != List && Position->Element != x) Position = Position-
>Next;
return Position;
}

Node *FindPrevious(Node *List, int x)


{
Node *Position;
Position = List;
while(Position->Next != List && Position->Next->Element != x) Position =
Position->Next;
return Position;
}

Node *FindNext(Node *List, int x)


{
Node *Position;
Position = Find(List, x);
return Position->Next;
}

void InsertBeg(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
NewNode->Element = e;
NewNode->Next = List->Next;
List->Next = NewNode;
}

void InsertLast(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
NewNode->Element = e;
if(IsEmpty(List))
{
NewNode->Next = List;
List->Next = NewNode;
}
else
{
Position = List;
while(Position->Next != List) Position =
Position->Next;
Position->Next = NewNode;
NewNode->Next = List;
}
}

void InsertMid(Node *List, int p, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
Position = Find(List, p);
NewNode->Element = e;
NewNode->Next = Position->Next;
Position->Next = NewNode;
}
void DeleteBeg(Node *List)
{
if(!IsEmpty(List))
{
Node *TempNode;
TempNode = List->Next;
List->Next = TempNode->Next;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

void DeleteEnd(Node *List)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = List;
while(Position->Next->Next != List) Position
= Position->Next;
TempNode = Position->Next;
Position->Next = List;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

void DeleteMid(Node *List, int e)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = FindPrevious(List, e);
if(!IsLast(Position, List))
{
TempNode = Position->Next; Position-
>Next = TempNode->Next;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
}
else
printf("List is empty...!\n");
}
void Traverse(Node *List)
{
if(!IsEmpty(List))
{
Node *Position;
Position = List;
while(Position->Next != List)
{
Position = Position->Next;
printf("%d\t", Position->Element);
}
printf("\n");
}
else
printf("List is empty...!\n");
}

OUTPUT

1. Insert Beg
2. Insert Middle
3. Insert End
4. Delete Beg
5. Delete Middle
6. Delete End
7.Find
8.Traverse
9.Exit
Enter your choice : 1
Enter the element : 40
Enter your choice : 1
Enter the element : 30
Enter your choice : 1
Enter the element : 20
Enter your choice : 1
Enter the element : 10
Enter your choice : 8
10 20 30 40
Enter your choice : 7
Enter the element : 30
Element found...!
Enter your choice : 1
Enter the element : 5
Enter your choice : 8
5 10 20 30 40
Enter your choice : 3
Enter the element : 45
Enter your choice : 8
5 10 20 30 40 45
Enter your choice : 2
Enter the position elem ent : 20
Enter the element : 25
Enter your choice : 8
5 10 20 25 30 40 45
Enter your choice : 4
The deleted item is 5
Enter your choice : 8
10 20 25 30 40 45
Enter your choice : 6
The deleted item is 45
Enter your choice : 8
10 20 25 30 40
Enter your choice : 5
Enter the element : 30
The deleted item is 30
Enter your choice : 8
10 20 25 40
Enter your choice : 9
REVIEW QUESTIONS

1. What is circular linked list?


2. What is a singly linked circular list?
CHAPTER - 6 - DOUBLY LINKED LIST IMPLEMENTATION

6.1 INTRODUCTION

Sometimes it is convenient to traverse lists backwards. The standard implementation


does not help here, but the solution is simple. Merely add an extra field to the data
structure, containing a pointer to the previous cell. The cost of this is an extra link, which
adds to the space requirement and also doubles the cost of insertions and deletions because
there are more pointers to fix. On the other hand, it simplifies deletion, because you no
longer have to refer to a key by using a pointer to the previous cell; this information is now
at hand. Figure shows a doubly linked list.

Fig. 6.1 A Doubly Linked List

A doubly linked list is a linked list in which each node has three fields namely data
field, next link (Next) and previous link (Prev). Next points to the successor node in the list
whereas Prev points to the predecessor node.

Previous Data Next Pointer


Pointer Element
Node

Fig. 6.2 Doubly Linked List

Fig. 6.3 Doubly Linked List with Header


6.2 TYPE DECLARATIONS FOR DOUBLY LINKED LIST

struct node
{
struct node *Prev; int
Element; struct node
*Next;

};
typedef struct node Node;

6.3 EMPTY LIST WITH HEADER

Example

Fig. 6.4 Empty Doubly Linked List with Header

Algorithm

IsEmpty(List)

Step 1 : Start.
Step 2 : If ListNext = NULL goto Step 3 else goto Step 4.
Step 3 : Return 1 and
Stop. Step 4 : Return 0
and Stop. Step 5 : Stop.

Routine

int IsEmpty(Node *List)


{
if(List->Next == NULL)
return 1;
else
return 0;
}

6.4 CURRENT POSITION IS LAST

Example
Position
Fig. 6.5. Current Position is the Last in a Doubly Linked List
Algorithm

IsLast(Position)

Step 1 : Start.
Step 2 : If PositionNext = NULL goto Step 3 else goto Step
4. Step 3 : Return 1 and Stop.
Step 4 : Return 0 and
Stop. Step 5 : Stop.

Routine to Check Whether the Current Position is Last

int IsLast(Node *Position)


{
if(Position->Next == NULL)
return 1;
else
return 0;
}

6.5 FIND

Example

Find(List, 30)

Position
Algorithm

Find(List, x)

Step 1 : Start.
Step 2 : Set Position = ListNext.
Step 3 : Repeat the Step 4 until Position != NULL and PositionElement != x.
Step 4 : Set Position = PositionNext.
Step 5 : Return Position.
Step 6 : Stop.

Routine

Node *Find(Node *List, int x)


{
Node *Position; Position =
List->Next;
while(Position != NULL && Position->Element != x) Position = Position-
>Next;
return Position;
}
6.6 TRAVERSE THE LIST

Example

Algorithm

Traverse(List)

Step 1 : Start.
Step 2 : If !IsEmpty = TRUE goto Step 3 else goto Step
8. Step 3 : Set Position = List.
Step 4 : Repeat the Steps 5-6 until PositionNext != NULL.
Step 5 : Set Position = PositionNext.
Step 6 : Display PositionElement.
Step 7 : Goto Step 9.
Step 8 : Display “List is
empty”. Step 9 : Stop.

Routine

void Traverse(Node *List)


{
if(!IsEmpty(List))
{
Node *Position; Position
= List;
while(Position->Next != NULL)
{
Position = Position->Next;
printf("%d\t", Position->Element);
}
printf("\n");
}
else
{
printf("List is empty...!\n");
}
}

6.7 INSERT

Insertion

 Insert an element at the beginning


 Insert an element at the end
 Insert an element in the middle
6.7.1 Insert an Element at the Beginning

Example

The general idea is shown in Figure. The dashed line represents the old pointer.

InsertBeg(List, 5)
NewNode

Algorithm

InsertBeg(List, e)

Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : If List = NULL, then goto Step 4 else goto Step
8. Step 4 : Set NewNodeElement = e.
Step 5 : Set NewNodeNext = NULL.
Step 6 : Set NewNodePrev = List.
Step 7 : Set ListNext = NewNode and goto Step 13.
Step 8 : Set NewNodeElement = e.
Step 9 : Set NewNodeNext = ListNext.
Step 10: Set NewNodeNextPrev = NewNode.
Step 11: Set NewNodePrev = List.
Step 12: Set ListNext = NewNode.
Step 13: Stop.

Routine

void InsertBeg(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
NewNode->Element = e; if(IsEmpty(List))
NewNode->Next = NULL;
else
{
NewNode->Next = List->Next;
NewNode->Next->Prev = NewNode;
}
NewNode->Prev = List;
List->Next = NewNode;
}

6.7.2 Insert an Element at the End

Example

InsertLast(List, 45)

Position NewNode
Algorithm

InsertLast(List, e)

Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : If List = NULL, then goto Step 4 else goto Step
8. Step 4 : Set NewNodeElement = e.
Step 5 : Set NewNodeNext = NULL.
Step 6 : Set NewNodePrev = List.
Step 7 : Set ListNext = NewNode and goto Step 15.
Step 8 : Set Position = List.
Step 9 : Repeat the Step 10 until PositionNext !=
NULL. Step 10: Set Position = PositionNext.
Step 11: Set NewNodeElement = e.
Step 12: Set PositionNext = NewNode.
Step 13: Set NewNodePrev = Position.
Step 14: Set NewNodeNext = NULL.
Step 15: Stop.

Routine

void InsertLast(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
Node *Position;
NewNode->Element = e;
NewNode->Next = NULL;
if(IsEmpty(List))
{
NewNode->Prev = List;
List->Next = NewNode;
}
else
{
Position = List;
while(Position->Next != NULL) Position =
Position->Next;
Position->Next = NewNode;
NewNode->Prev = Position;
}
}

6.7.3 Insert an Element in the Middle

Example

InsertMid(List, 20, 25)

NewNode

Position

Algorithm

InsertMid(List, p, e)

Step 1 : Start.
Step 2 : Set NewNode = addressof(Node).
Step 3 : Set Position = Find(List, p).
Step 4 : Set NewNodeElement = e.
Step 5 : Set NewNodeNext = PositionNext.
Step 6 : Set PositionNextPrev = NewNode.
Step 7 : Set PositionNext = NewNode.
Step 8 : Set NewNodePrev = Position.
Step 9 : Stop.
Routine

void InsertMid(Node *List, int p, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
Position = Find(List, p);
NewNode->Element = e;
NewNode->Next = Position->Next;
Position->Next->Prev = NewNode;
Position->Next = NewNode; NewNode-
>Prev = Position;
}

6.8 DELETE

6.8.1 Delete an Element from the Beginning

Example

DeleteBeg(List)
TempNode

Algorithm

DelBeg(List, e)

Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
9. Step 3 : Set TempNode = ListNext.
Step 4 : Set ListNext = TempNodeNext.
Step 5 : If ListNext != NULL, then goto Step 6 else goto Step
7. Step 6 : Set TempNodeNextPrev = List.
Step 7 : Display the TempNodeElement.
Step 8 : Delete TempNode and goto Step10.
Step 9 : Display “List is Empty”.
Step 10: Stop.
Routine

void DeleteBeg(Node *List)


{
if(!IsEmpty(List))
{
Node *TempNode;
TempNode = List->Next;
List->Next = TempNode->Next;
if(List->Next != NULL)
TempNode->Next->Prev = List;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

6.8.2 Delete an Element from the End

Example

DeleteEnd(List)

Position TempNode

Algorithm

DeleteEnd(List)

Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
10. Step 3 : Set Position = List.
Step 4 : Repeat the Step 5 until PositionNext != NULL.
Step 5 : Set Position = PositionNext.
Step 6 : Set TempNode = Position.
Step 7 : Set PositionPrevNext = NULL.
Step 8 : Display the TempNodeElement.
Step 9 : Delete TempNode and goto Step
11. Step 10: Display “List is Empty”.
Step 11: Stop.
Routine

void DeleteEnd(Node *List)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = List;
while(Position->Next != NULL) Position
= Position->Next;
TempNode = Position; Position-
>Prev->Next = NULL;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}

6.8.3 Delete an Element from the Middle

Example

DeleteMid(List, 30)
TempNode

Position
Algorithm

DeleteMid(List, e)

Step 1 : Start.
Step 2 : If !IsEmpty = True, then goto Step 3 else goto Step
10. Step 3 : Set Position = Find (List, e).
Step 4 : If !Islast(Position) = True, then goto Step 5 else goto Step 11.
Step 5 : Set TempNode = Position.
Step 6 : Set PositionPrevNext = PositionNext.
Step 7 : Set PositionNextPrev = PositionPrev.
Step 8 : Display the TempNodeElement.
Step 9 : Delete TempNode and goto Step
11. Step 10: Display “List is Empty”.
Step 11: Stop.

Routine

void DeleteMid(Node *List, int e)


{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = Find(List, e);
if(!IsLast(Position))
{
TempNode = Position;
Position->Prev->Next = Position->Next; Position-
>Next->Prev = Position->Prev;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
}
else
printf("List is empty...!\n");
}

6.9 PROGRAM

/* Implementation of doubly linked list - DLL.C */

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

struct node
{
struct node *Prev; int
Element; struct node
*Next;

};
typedef struct node Node;

int IsEmpty(Node *List);


int IsLast(Node *Position); Node
*Find(Node *List, int x);
void InsertBeg(Node *List, int e);
void InsertLast(Node *List, int e);
void InsertMid(Node *List, int p, int e);
void DeleteBeg(Node *List);
void DeleteEnd(Node *List);
void DeleteMid(Node *List, int e);
void Traverse(Node *List);

int main()
{
Node *List = malloc(sizeof(Node)); List-
>Prev = NULL;
List->Next = NULL;
Node *Position; int
ch, e, p;
printf("1.Insert Beg \n2.Insert Middle \n3.Insert End"); printf("\n4.Delete Beg \
n5.Delete Middle \n6.Delete End"); printf("\n7.Find \n8.Traverse \n9.Exit\n");
do
{
printf("Enter your choice : ");
scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the element : ");
scanf("%d", &e); InsertBeg(List, e);
break;
case 2:
printf("Enter the position element : ");
scanf("%d", &p);
printf("Enter the element : ");
scanf("%d", &e); InsertMid(List, p, e);
break;
case 3:
printf("Enter the element : ");
scanf("%d", &e); InsertLast(List, e);
break;
case 4:
DeleteBeg(List);
break;
case 5:
printf("Enter the element : ");
scanf("%d", &e); DeleteMid(List, e);
break;
case 6:
DeleteEnd(List);
break;
case 7:
printf("Enter the element : ");
scanf("%d", &e); Position =
Find(List, e); if(Position !=
NULL)
printf("Element found...!\n");
else
printf("Element not found...!\n");
break;
case 8:
Traverse(List);
break;
}
} while(ch <= 8);

return 0;
}

int IsEmpty(Node *List)


{
if(List->Next == NULL)
return 1;
else
return 0;
}

int IsLast(Node *Position)


{
if(Position->Next == NULL)
return 1;
else
return 0;
}
Node *Find(Node *List, int x)
{
Node *Position; Position =
List->Next;
while(Position != NULL && Position->Element != x) Position =
Position->Next;
return Position;
}

void InsertBeg(Node *List, int e)

{
Node *NewNode = malloc(sizeof(Node));
NewNode->Element = e; if(IsEmpty(List))
NewNode->Next = NULL;

else
{
NewNode->Next = List->Next;
NewNode->Next->Prev = NewNode;
}
NewNode->Prev = List;
List->Next = NewNode;
}

void InsertLast(Node *List, int e)


{
Node *NewNode = malloc(sizeof(Node));
Node *Position;
NewNode->Element = e;
NewNode->Next = NULL;
if(IsEmpty(List))
{
}

}
else
{

}
NewNode->prev = List;
List->Next = NewNode;

Position = List;
while(Position->Next != NULL) Position =
Position->Next;
Position->Next = NewNode;
NewNode->Prev = Position;

void InsertMid(Node *List, int p, int e)


{
Node *NewNode = malloc(sizeof(Node)); Node
*Position;
Position = Find(List, p);
NewNode->Element = e;
NewNode->Next = Position->Next;
Position->Next->Prev = NewNode;
Position->Next = NewNode; NewNode-
>Prev = Position;
}

void DeleteBeg(Node *List)


{
if(!IsEmpty(List))
{
Node *TempNode;
TempNode = List->Next;
List->Next = TempNode->Next;
if(List->Next != NULL)
TempNode->Next->Prev = List;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}
void DeleteEnd(Node *List)
{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = List;
while(Position->Next != NULL) Position
= Position->Next;
TempNode = Position; Position-
>Prev->Next = NULL;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
else
printf("List is empty...!\n");
}
void DeleteMid(Node *List, int e)
{
if(!IsEmpty(List))
{
Node *Position;
Node *TempNode;
Position = Find(List, e);
if(!IsLast(Position))
{
TempNode = Position;
Position->Prev->Next = Position->Next; Position-
>Next->Prev = Position->Prev;
printf("The deleted item is %d\n", TempNode->Element);
free(TempNode);
}
}
else
printf("List is empty...!\n");
}
void Traverse(Node *List)
{
if(!IsEmpty(List))
{
Node *Position;
Position = List;
while(Position->Next != NULL)
{
Position = Position->Next;
printf("%d\t", Position->Element);
}
printf("\n");
}
else
printf("List is empty...!\n");
}

OUTPUT

1. Insert Beg
2. Insert Middle
3. Insert End
4. Delete Beg
5. Delete Middle
6. Delete End
7.Find
8.Traverse
9.Exit
Enter your choice : 1
Enter the element : 40
Enter your choice : 1
Enter the element : 30
Enter your choice : 1
Enter the element : 20
Enter your choice : 1
Enter the element : 10
Enter your choice : 8
10 20 30 40
Enter your choice : 7
Enter the element : 30
Element found...!
Enter your choice : 1
Enter the element : 5
Enter your choice : 8
5 10 20 30 40
Enter your choice : 3
Enter the element : 45
Enter your choice : 8
5 10 20 30 40 45
Enter your choice : 2
Enter the position element : 20
Enter the element : 25
Enter your choice : 8
5 10 20 25 30 40 45
Enter your choice : 4
The deleted item is 5
Enter your choice : 8
10 20 25 30 40 45
Enter your choice : 6
The deleted item is 45
Enter your choice : 8
10 20 25 30 40
Enter your choice : 5
Enter the element : 30
The deleted item is 30
Enter your choice : 8
10 20 25 40
Enter your choice : 9
REVIEW QUESTIONS

1. What is a doubly linked list?


2. What are the advantages of doubly linked list over singly linked list? (or) What is
the advantage of using doubly linked list over single linked list?
3. Differentiate doubly and circular linked list.
CHAPTER - 7 - POLYNOMIAL ADT

7.1 INTRODUCTION

We can define an abstract data type for single-variable polynomials (with


nonnegative exponents) by using a list. We could then write routines to perform addition,
subtraction, multiplication, differentiation, and other operations on these polynomials.

7.2 LINKED LIST REPRESENTATIONS OF TWO POLYNOMIALS

7.3 DECLARATION FOR LINKED LIST IMPLEMENTATION OF POLYNOMIAL ADT

struct poly
{
int coeff;
int pow;
struct poly *Next;
};
typedef struct poly Poly;
REVIEW QUESTIONS

1. Why is linked list used for polynomial arithmetic?


CHAPTER - 8 - POLYNOMIAL ADDITION

8.1 EXAMPLE

8.2 ROUTINE

void Addition(Poly *Poly1, Poly *Poly2, Poly *Result)


{
Poly *Position;
Poly *NewNode;
Poly1 = Poly1->Next;
Poly2 = Poly2->Next;
Result->Next = NULL;
Position = Result;
while(Poly1 != NULL && Poly2 != NULL)
{
NewNode = malloc(sizeof(Poly));
if(Poly1->pow == Poly2->pow)
{
NewNode->coeff = Poly1->coeff + Poly2->coeff;
NewNode->pow = Poly1->pow;
Poly1 = Poly1->Next; Poly2 =
Poly2->Next;
}
else if(Poly1->pow > Poly2->pow)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
else if(Poly1->pow < Poly2->pow)
{
NewNode->coeff = Poly2->coeff;
NewNode->pow = Poly2->pow; Poly2
= Poly2->Next;
}
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}

while(Poly1 != NULL || Poly2 != NULL)


{
NewNode = malloc(sizeof(Poly));
if(Poly1 != NULL)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
if(Poly2 != NULL)
{
NewNode->coeff = Poly2->coeff;
NewNode->pow = Poly2->pow; Poly2
= Poly2->Next;
}
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}
}

8.3 PROGRAM

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

struct poly
{
int coeff;
int pow;
struct poly *Next;
};
typedef struct poly Poly; void
Create(Poly *List); void
Display(Poly *List);
void Addition(Poly *Poly1, Poly *Poly2, Poly *Result);

int main()
{
Poly *Poly1 = malloc(sizeof(Poly)); Poly
*Poly2 = malloc(sizeof(Poly)); Poly *Result =
malloc(sizeof(Poly)); Poly1->Next = NULL;
Poly2->Next = NULL;
printf("Enter the values for first polynomial :\n"); Create(Poly1);
printf("The polynomial equation is : "); Display(Poly1);
printf("\nEnter the values for second polynomial :\n"); Create(Poly2);
printf("The polynomial equation is : "); Display(Poly2);
Addition(Poly1, Poly2, Result);
printf("\nThe polynomial equation addition result is : "); Display(Result);
return 0;
}

void Create(Poly *List)


{
int choice;
Poly *Position, *NewNode; Position =
List;
do
{
NewNode = malloc(sizeof(Poly));
printf("Enter the coefficient : "); scanf("%d",
&NewNode->coeff); printf("Enter the power
: "); scanf("%d", &NewNode->pow);
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
printf("Enter 1 to continue : ");
scanf("%d", &choice);
} while(choice == 1);
}

void Display(Poly *List)


{
Poly *Position; Position =
List->Next; while(Position !=
NULL)
{
printf("%dx^%d", Position->coeff, Position->pow); Position = Position-
>Next;
if(Position != NULL && Position->coeff > 0)
{
printf("+");
}
}
}

void Addition(Poly *Poly1, Poly *Poly2, Poly *Result)


{
Poly *Position; Poly
*NewNode;
Poly1 = Poly1->Next;
Poly2 = Poly2->Next;
Result->Next = NULL;
Position = Result;
while(Poly1 != NULL && Poly2 != NULL)
{
NewNode = malloc(sizeof(Poly));
if(Poly1->pow == Poly2->pow)
{
NewNode->coeff = Poly1->coeff + Poly2->coeff;
NewNode->pow = Poly1->pow;
Poly1 = Poly1->Next; Poly2 =
Poly2->Next;
}
else if(Poly1->pow > Poly2->pow)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
else if(Poly1->pow < Poly2->pow)
{
NewNode->coeff = Poly2->coeff;
NewNode->pow = Poly2->pow; Poly2
= Poly2->Next;
}
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}

while(Poly1 != NULL || Poly2 != NULL)


{
NewNode = malloc(sizeof(Poly));
if(Poly1 != NULL)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
if(Poly2 != NULL)
{
NewNode->coeff = Poly2->coeff;
NewNode->pow = Poly2->pow; Poly2
= Poly2->Next;
}
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}
}
OUTPUT

Enter the values for first polynomial :


Enter the coefficient : 2 Enter
the power : 2 Enter 1 to
continue : 1 Enter the
coefficient : 6 Enter the power
: 1 Enter 1 to continue : 1
Enter the coefficient : 5 Enter
the power : 0 Enter 1 to
continue : 0
The polynomial equation is : 2x^2+6x^1+5x^0 Enter
the values for second polynomial :
Enter the coefficient : 3 Enter
the power : 2 Enter 1 to
continue : 1
Enter the coefficient : -2 Enter the
power : 1
Enter 1 to continue : 1 Enter the
coefficient : -1 Enter the power :
0
Enter 1 to continue : 0
The polynomial equation is : 3x^2-2x^1-1x^0
The polynomial equation addition result is : 5x^2+4x^1+4x^0
REVIEW QUESTIONS

1. Write the routine for polynomial addition.


CHAPTER - 9 - POLYNOMIAL SUBTRACTION

9.1 EXAMPLE

9.2 ROUTINE

void Subtraction(Poly *Poly1, Poly *Poly2, Poly *Result)


{
Poly *Position;
Poly *NewNode;
Poly1 = Poly1->Next;
Poly2 = Poly2->Next;
Result->Next = NULL;
Position = Result;
while(Poly1 != NULL && Poly2 != NULL)
{
NewNode = malloc(sizeof(Poly));
if(Poly1->pow == Poly2->pow)
{
NewNode->coeff = Poly1->coeff - Poly2->coeff;
NewNode->pow = Poly1->pow;
Poly1 = Poly1->Next; Poly2 =
Poly2->Next;
}
else if(Poly1->pow > Poly2->pow)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
else if(Poly1->pow < Poly2->pow)
{
NewNode->coeff = -(Poly2->coeff);
NewNode->pow = Poly2->pow;
Poly2 = Poly2->Next;
}
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}

while(Poly1 != NULL || Poly2 != NULL)


{
NewNode = malloc(sizeof(Poly));
if(Poly1 != NULL)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
if(Poly2 != NULL)
{
NewNode->coeff = -(Poly2->coeff);
NewNode->pow = Poly2->pow;
Poly2 = Poly2->Next;
}
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}
}

9.3 PROGRAM

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

struct poly
{
int coeff;
int pow;
struct poly *Next;
};
typedef struct poly Poly; void
Create(Poly *List); void
Display(Poly *List);
void Subtraction(Poly *Poly1, Poly *Poly2, Poly *Result);

int main()
{
Poly *Poly1 = malloc(sizeof(Poly)); Poly
*Poly2 = malloc(sizeof(Poly)); Poly *Result =
malloc(sizeof(Poly)); Poly1->Next = NULL;
Poly2->Next = NULL;
printf("Enter the values for first polynomial :\n"); Create(Poly1);
printf("The polynomial equation is : "); Display(Poly1);
printf("\nEnter the values for second polynomial :\n"); Create(Poly2);
printf("The polynomial equation is : "); Display(Poly2);
Subtraction(Poly1, Poly2, Result);
printf("\nThe polynomial equation subtraction result is : "); Display(Result);
return 0;
}

void Create(Poly *List)


{
int choice;
Poly *Position, *NewNode; Position =
List;
do
{
NewNode = malloc(sizeof(Poly));
printf("Enter the coefficient : "); scanf("%d",
&NewNode->coeff); printf("Enter the power
: "); scanf("%d", &NewNode->pow);
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
printf("Enter 1 to continue : ");
scanf("%d", &choice);
} while(choice == 1);
}

void Display(Poly *List)


{
Poly *Position; Position =
List->Next; while(Position !=
NULL)
{
printf("%dx^%d", Position->coeff, Position->pow); Position = Position-
>Next;
if(Position != NULL && Position->coeff > 0)
{
printf("+");
}
}
}

void Subtraction(Poly *Poly1, Poly *Poly2, Poly *Result)


{
Poly *Position; Poly
*NewNode;
Poly1 = Poly1->Next;
Poly2 = Poly2->Next;
Result->Next = NULL;
Position = Result;
while(Poly1 != NULL && Poly2 != NULL)
{
NewNode = malloc(sizeof(Poly));
if(Poly1->pow == Poly2->pow)
{
NewNode->coeff = Poly1->coeff - Poly2->coeff;
NewNode->pow = Poly1->pow;
Poly1 = Poly1->Next; Poly2 =
Poly2->Next;
}
else if(Poly1->pow > Poly2->pow)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
else if(Poly1->pow < Poly2->pow)
{
NewNode->coeff = -(Poly2->coeff);
NewNode->pow = Poly2->pow;
Poly2 = Poly2->Next;
}

NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}

while(Poly1 != NULL || Poly2 != NULL)


{
NewNode = malloc(sizeof(Poly));
if(Poly1 != NULL)
{
NewNode->coeff = Poly1->coeff;
NewNode->pow = Poly1->pow; Poly1
= Poly1->Next;
}
if(Poly2 != NULL)
{
NewNode->coeff = -(Poly2->coeff);
NewNode->pow = Poly2->pow;
Poly2 = Poly2->Next;
}
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}
}

OUTPUT

Enter the values for first polynomial :


Enter the coefficient : 3 Enter
the power : 2 Enter 1 to
continue : 1 Enter the
coefficient : 4 Enter the power
: 1 Enter 1 to continue : 1
Enter the coefficient : -2 Enter the
power : 0
Enter 1 to continue : 0
The polynomial equation is : 3x^2+4x^1-2x^0 Enter the
values for second polynomial :
Enter the coefficient : -7 Enter the
power : 2
Enter 1 to continue : 1 Enter the
coefficient : -10 Enter the power :
1
Enter 1 to continue : 1 Enter the
coefficient : 17 Enter the power :
0
Enter 1 to continue : 0
The polynomial equation is : -7x^2-10x^1+17x^0
The polynomial equation subtraction result is : 10x^2+14x^1-19x^0
REVIEW QUESTIONS

1. Write the routine for polynomial subtraction.


CHAPTER - 10 - POLYNOMIAL DIFFERENTIATION

10.1 EXAMPLE

10.2 ROUTINE

void Differentiation(Poly *Poly1, Poly *Result)


{
Poly *Position; Poly
*NewNode;
Poly1 = Poly1->Next;
Result->Next = NULL;
Position = Result;
while(Poly1 != NULL)
{
NewNode = malloc(sizeof(Poly));
NewNode->coeff = Poly1->coeff * Poly1->pow;
NewNode->pow = Poly1->pow - 1;
Poly1 = Poly1->Next;
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}
}

10.3 PROGRAM

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

struct poly
{
int coeff;
int pow;
struct poly *Next;
};
typedef struct poly Poly;

void Create(Poly *List);


void Display(Poly *List);
void Differentiation(Poly *Poly1, Poly *Result);
int main()
{
Poly *Poly1 = malloc(sizeof(Poly)); Poly *Result
= malloc(sizeof(Poly));
Poly1->Next = NULL;
printf("Enter the values for polynomial :\n"); Create(Poly1);
printf("The polynomial equation is : "); Display(Poly1);
Differentiation(Poly1, Result);
printf("\nThe polynomial differentiation equation is : "); Display(Result);
return 0;
}

void Create(Poly *List)


{
int choice;
Poly *Position, *NewNode; Position =
List;
do
{
NewNode = malloc(sizeof(Poly));
printf("Enter the coefficient : "); scanf("%d",
&NewNode->coeff); printf("Enter the power
: "); scanf("%d", &NewNode->pow);
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
printf("Enter 1 to continue : ");
scanf("%d", &choice);
} while(choice == 1);
}

void Display(Poly *List)


{
Poly *Position; Position =
List->Next;
while(Position != NULL && Position->pow >= 0)
{
printf("%dx^%d", Position->coeff, Position->pow); Position = Position-
>Next;
if(Position != NULL && Position->coeff > 0)
{
printf("+");
}
}
}
void Differentiation(Poly *Poly1, Poly *Result)
{
Poly *Position; Poly
*NewNode;
Poly1 = Poly1->Next;
Result->Next = NULL;
Position = Result;
while(Poly1 != NULL)
{
NewNode = malloc(sizeof(Poly));
NewNode->coeff = Poly1->coeff * Poly1->pow;
NewNode->pow = Poly1->pow - 1;
Poly1 = Poly1->Next;
NewNode->Next = NULL;
Position->Next = NewNode;
Position = NewNode;
}
}

Output

Enter the values for polynomial :


Enter the coefficient : 3 Enter
the power : 5 Enter 1 to
continue : 1
Enter the coefficient : -2 Enter the
power : 3
Enter 1 to continue : 1 Enter
the coefficient : 1 Enter the
power : 1 Enter 1 to continue :
1 Enter the coefficient : 5 Enter
the power : 0 Enter 1 to
continue : 0
The polynomial equation is : 3x^5-2x^3+1x^1+5x^0
The polynomial differentiation equation is : 15x^4-6x^2+1x^0
REVIEW QUESTIONS

1. Write the routine for polynomial differentiation.

CHAPTER - 11 - MULTILISTS

11.1 INTRODUCTION

A university with 40,000 students and 2,500 courses needs to be able to generate two
types of reports. The first report lists the class registration for each class, and the second
report lists, by student, the classes that each student is registered for.

The obvious implementation might be to use a two-dimensional array. Such an array


would have 100 million entries. The average student registers for about three courses, so
only 120,000 of these entries, or roughly 0.1 percent, would actually have meaningful data.

What is needed is a list for each class, which contains the students in the class. We
also need a list for each student, which contains the classes the student is registered for.
Figure shows our implementation.
Fig. 11.1 Multilist implementation for registration problem

As the figure shows, we have combined two lists into one. All lists use a header and
are circular.

To list all of the students in class C3, we start at C3 and traverse its list (by going
right). The first cell belongs to student S1. Although there is no explicit information to this
effect, this can be determined by following the student's linked list until the header is
reached. Once this is done, we return to C3's list (we stored the position we were at in the
course list before we traversed the student's list) and find another cell, which can be
determined to belong to S3. We can continue and find that S4 and S5 are also in this class. In
a similar manner, we can determine, for any student, all of the classes in which the student
is registered.

REVIEW QUESTIONS

1. What is multilist?
Applications of lists

In linear data structures, a list is one of the most fundamental types of data structures. A linear data
structure is one where elements are arranged sequentially, and each element is connected to its
previous and next element (if applicable). Lists, in this context, refer to both arrays (or dynamic arrays)
and linked lists.

Here are several key applications of lists in linear data structures:

1. Storing Collections of Data

 Lists are used to store collections of data in an ordered manner, where each element has a
unique position (or index). This helps in efficiently managing, accessing, and modifying data.
 Example: A list of employee IDs or names in a company.

2. Implementing Stacks (LIFO Structure)

 A stack is a linear data structure that follows the Last In, First Out (LIFO) principle. Lists can be
used to implement a stack, where elements are added and removed from the same end (top).
 Example: Undo operations in text editors or browser history can be implemented using a stack.
 Operations:
o Push (add an element): Can be done using the append() method in a list.
o Pop (remove an element): Can be done using the pop() method in a list.

3. Implementing Queues (FIFO Structure)

 A queue is another linear data structure that follows the First In, First Out (FIFO) principle. Lists
can be used to implement a queue, where elements are added at the rear and removed from the
front.
 Example: Print jobs in a queue, task scheduling in operating systems.
 Operations:
o Enqueue (add an element): Can be done using the append() method.
o Dequeue (remove an element): Can be done using the pop(0) method (though this
operation is not as efficient in a list as in other data structures like deque).

4. Implementing Linked Lists

 A linked list is another type of linear data structure where each element (node) stores a
reference (pointer) to the next element in the sequence. This can be implemented using lists (or
nodes in languages that support pointers).
 Example: Memory management, dynamic memory allocation.
 Operations:
o Insertion and Deletion: Insertion and deletion can be done efficiently by adjusting
pointers (or modifying list elements) to add or remove nodes.
o Traversal: Iterating through the nodes in the linked list.
5. Dynamic Resizing of Data Collections

 Lists are often used in situations where the size of the data collection may change over time (e.g.,
items being added or removed). In this case, dynamic arrays (like Python’s list) can resize
automatically.
 Example: Storing elements of varying size or length, like a list of people attending a party where
guests can leave or arrive at different times.

6. Data Sorting and Searching

 Lists are essential for sorting algorithms (like Bubble Sort, Merge Sort, and Quick Sort) and
searching algorithms (like Linear Search and Binary Search when the list is sorted).
 Example: Searching for a name in a contact list, sorting a list of ages.

7. Graph Representation (Adjacency Lists)

 Lists are used in the representation of graphs using adjacency lists. In an adjacency list
representation, each node in the graph has a list of its neighbors.
 Example: Social networks (where nodes are people and edges are relationships).

8. Matrix Representation

 Lists can be used to represent 2D matrices, where each list represents a row of the matrix. This
allows for efficient access and modification of elements.
 Example: Storing a grid for a game or representing a chessboard.

9. Buffer/Memory Management

 Lists can serve as buffers in low-level memory management or in real-time systems, where data
needs to be managed efficiently and accessed in a linear fashion.
 Example: Circular buffers in embedded systems where data needs to be continuously stored and
read.

10. Recursive Algorithms and Backtracking

 Lists can store intermediate results in recursive algorithms or backtracking problems. Lists allow
easy modification and access to the intermediate data.
 Example: Storing partial solutions or paths in maze-solving algorithms or the N-Queens problem.

11. Data Transformation and Filtering

 Lists are useful for processing or transforming data in algorithms that involve filtering, mapping,
or reducing data.
 Example: Applying a function to each element in a list (e.g., converting a list of temperatures
from Celsius to Fahrenheit).
12. Sparse Data Representation

 In cases where most of the data is empty or has default values (sparse data), lists are used for
efficient storage and manipulation.
 Example: Sparse matrices in scientific computing or machine learning models, where most
elements are zeros.

13. Memory-Efficient Operations

 Lists are often used for scenarios where efficient memory management is important, such as
managing large datasets that change dynamically (growth or shrinkage).
 Example: A list of currently active users in a chat room or a list of tasks to be processed.

You might also like