0% found this document useful (0 votes)
29 views

Data Structure

A data structure is a specific way of organizing and storing data in a computer so that it can be accessed and modified efficiently. Common data structures include arrays, linked lists, stacks, queues, trees and graphs. The choice of data structure affects the performance and efficiency of algorithms and applications.

Uploaded by

dev.user.1792
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views

Data Structure

A data structure is a specific way of organizing and storing data in a computer so that it can be accessed and modified efficiently. Common data structures include arrays, linked lists, stacks, queues, trees and graphs. The choice of data structure affects the performance and efficiency of algorithms and applications.

Uploaded by

dev.user.1792
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 138

DATA STRUCTURE:

In the context of computers, the data structure is a specific way of storing and
organizing data in the computer's memory so that these data can be easily retrieved
and efficiently used when needed later. The data can be managed in many ways, such
as a logical or mathematical model for a particular data organization called a data
structure.

The variety of a specific data model depends on two factors:

● First, it must be loaded enough into the structure to reflect the actual relationship
of the data with a real-world object.
● Second, the formation should be so simple that one can efficiently process the
data whenever necessary.

Data structures can be subdivided into two major types:

● Linear Data Structure


● Non-linear Data Structure

Linear Data Structure

A data structure is said to be linear if its elements combine to form any specific order.
There are two techniques for representing such linear structure within memory.

● The first way is to provide a linear relationship between all the elements
represented using a linear memory location. These linear structures are called
arrays.
● The second technique provides a linear relationship between all the elements
represented using the concept of pointers or links. These linear structures are
called linked lists.

The typical examples of the linear data structure are:

● Arrays
● Queues
● Stacks
● Linked lists

Non-linear Data Structure

This structure mainly represents data with a hierarchical relationship between different
elements.

Examples of Non-Linear Data Structures are listed below:


● Graphs
● Family of trees and
● Table of contents

Tree: In this case, the data often has a hierarchical relationship between the different
elements. The data structure representing this relationship is called a rooted tree graph
or tree.

Graph: In this case, the data sometimes has relationships between pair elements, which
do not necessarily follow a hierarchical structure. Such a data structure is called a
graph.

Data Structure
The data structure is a particular way of organizing and storing data in
a computer so that it can be accessed and modified efficiently. It is a
collection of data values, the relationships among them, and the
functions or operations that can be applied to the data.

Arrays, Linked List, Stack, Queue, etc., are some examples of Data
Structures that are universally used in almost every realm of
Computer Science i.e. Operating systems, Compiler Design, Artificial
intelligence, Graphics, and a lot more. To handle the data in an
efficient way, Data Structures are used as the main part of many
computer science algorithms. To enhance the performance of the
software or a program as the main function of the software to store
and retrieve the user’s data as fast as possible, the Data Structures
are important.

Important terms used in Data Structure:


● Data: Elementary value or the collection of values. Example: Name
and id of the employee are the data about the employee.
● Group Items: Data items with subordinate data items. Example: The
name of the employee can have the first name and the last name.
● Record: The collection of various data items. Example: Name,
address, and experience of the employee can be grouped together to
form the record for the employee.
● File: Collection of various records of one type of entity.
● Attribute and Entity: An entity can be defined as the class of certain
objects, containing various attributes, where each attribute represents
the particular property of that entity.
● Field: A single elementary unit of information representing the
attribute of an entity.

Why we need Data Structures:


Complexed applications and an increase in the amount of data can
result in below:

● Processor speed: High-speed processing is a must to handle a large


amount of data. Still, the processor may fail to deal with such a large
amount of data, because the data is increasing day by day to the
billions of files per entity.
● Data Search: An inventory can have hundreds of items in a store,
which simply means that an application needs to traverse hundreds of
items every time to search for a particular item. This results in slowing
down the search process.
● Multiple requests: Even a very large server can fail if thousands of
users are searching the data simultaneously on a web server. The data
structures are used to solve any such problems. Thus, all the items are
not required to be searched and the required data can be searched
instantly if the data is organized to form a data structure in such a
way.

Data Structures Advantages:


● Efficiency: The choice of data structures decides the efficiency of a
program. Example: Using an array may not be a very good choice if
we have some data and we need to perform the search for a particular
record. Organizing the data in an array means that we will have to
search sequentially element by element. To make the search process
efficient, we can use other data structures like an ordered array,
binary search tree, or hash tables.
● Reusability: After the implementation of a particular data structure,
we can use it at any other place. Thus, the data structures are
reusable. Compiling the implementation of data structures into
libraries that can be used by different clients, serves this purpose.
● Abstraction: The ADT provides a level of abstraction. The data
structure is specified by ADT. The client program does not get into the
implementation details and uses the data structure through the
interface only.
Data Structures Types:

Linear Data Structures:


If all the elements of a data structure are arranged in linear order, it is
called a linear data structure. The elements in linear data structures
are stored in a non-hierarchical way. Here, each element has
successors and predecessors except the first and last element.
Types of Linear Data Structures:
● Arrays: A collection of similar types of data items is called an array. It
can be one-dimensional, two-dimensional, or multidimensional. Each
data item in an array is called an element of the array. We can use any
valid data type like char, int, float, or double as the data type of the
element. The same variable name is shared by the elements of the
array. However, each element carries a different index number known
as a subscript.
● Linked List: To maintain a list in the memory a linear data structure
is used, also known as a linked list. We can also define it as a
collection of nodes stored at non-contiguous memory locations, where
each node of the list contains a pointer to its adjacent node.
● Stack: A linear list in which insertion and deletions are allowed only at
one end, i.e., top, is called a stack. It is an abstract data type (ADT),
which is named as a stack because it behaves like a real-world stack.
It can be implemented in most programming languages.
● Queue: A linear list in which elements can be inserted only at one end
called rear and deleted only at the other end called front is called a
queue. It is also an abstract data structure, which is opened at both
ends, and thus follows the First-In-First-Out (FIFO) methodology for
storing the data items.

Non-Linear Data Structures:


In a non-linear arrangement, the data elements are not arranged in
sequential structure, i.e., this data structure does not form a sequence
and each item or element is connected with two or more other items.

Types of Non-Linear Data Structures:


● Trees: A multilevel data structure with a hierarchical relationship
among its elements is called a tree. The elements of a tree are known
as nodes. In a hierarchy, the bottommost nodes are called the leaf
node, and the topmost node is called the root node. To point the
adjacent nodes, each node contains pointers. Based on the parent-
child relationship among the nodes, each node in the tree can have
more than one child except the leaf nodes whereas each node can
have at most one parent except the root node.
● Graphs: The pictorial representation of the set of elements
(represented by vertices) connected by the links known as edges is
called a graph. A graph can have a cycle while the tree can not have
one, and is thus different from a tree.
Commonly used data structure
operations:
● Traversing: A set of data elements are included in every data
structure. Visiting each element of the data structure in order to
perform some specific operation like searching or sorting, is called
traversing the data structure.
● Insertion: The process of adding the elements to the data structure
at any location is defined as insertion. We can insert n-1 data elements
into a data structure if the size of the data structure is n.
● Deletion: Deletion is the process of removing an element from the
data structure. An element can be deleted from the data structure at
any random location. Underflow occurs if we try to delete an element
from an empty data structure.
● Searching: Searching is the process of finding the location of an
element within the data structure. To perform searching, Linear Search
and Binary Search are the two algorithms.
● Sorting: Sorting is the process of arranging the data structure in a
specific order. To perform sorting, there are many algorithms that can
be used, including, insertion sort, selection sort, bubble sort, etc.
● ● Merging: Merging is the process where the two lists List A and List B
of size M and N respectively, of similar type of elements, are clubbed
or joined to produce the third list, List C of size (M+N).

What is a Stack?
A Stack is a linear data structure that follows the LIFO (Last-In-First-Out) principle. Stack
has one end, whereas the Queue has two ends (front and rear). It contains only one
pointer top pointer pointing to the topmost element of the stack. Whenever an element is
added in the stack, it is added on the top of the stack, and the element can be deleted only
from the stack. In other words, a stack can be defined as a container in which insertion and
deletion can be done from the one end known as the top of the stack.
o It is called as stack because it behaves like a real-world stack, piles of books, etc.
o A Stack is an abstract data type with a pre-defined capacity, which means that it can
store the elements of a limited size.
o It is a data structure that follows some order to insert and delete the elements, and
that order can be LIFO or FILO.

Working of Stack
Stack works on the LIFO pattern. As we can observe in the below figure there are five memory
blocks in the stack; therefore, the size of the stack is 5.

Suppose we want to store the elements in a stack and let's assume that stack is empty. We have
taken the stack of size 5 as shown below in which we are pushing the elements one by one until
the stack becomes full.
Since our stack is full as the size of the stack is 5. In the above cases, we can observe that it goes
from the top to the bottom when we were entering the new element in the stack. The stack gets
filled up from the bottom to the top.

PlayNext
Unmute
Current Time 0:00
/
Duration 18:10
Loaded: 2.94%
Â
Fullscreen

When we perform the delete operation on the stack, there is only one way for entry and exit as
the other end is closed. It follows the LIFO pattern, which means that the value entered first will
be removed last. In the above case, the value 5 is entered first, so it will be removed only after
the deletion of all the other elements.

Standard Stack Operations


The following are some common operations implemented on the stack:

o push(): When we insert an element in a stack then the operation is known as a push.
If the stack is full then the overflow condition occurs.
o pop(): When we delete an element from the stack, the operation is known as a pop.
If the stack is empty means that no element exists in the stack, this state is known as
an underflow state.
o isEmpty(): It determines whether the stack is empty or not.
o isFull(): It determines whether the stack is full or not.'
o peek(): It returns the element at the given position.
o count(): It returns the total number of elements available in a stack.
o change(): It changes the element at the given position.
o display(): It prints all the elements available in the stack.

PUSH operation
The steps involved in the PUSH operation is given below:

o Before inserting an element in a stack, we check whether the stack is full.


o If we try to insert the element in a stack, and the stack is full, then
the overflow condition occurs.
o When we initialize a stack, we set the value of top as -1 to check that the stack is
empty.
o When the new element is pushed in a stack, first, the value of the top gets
incremented, i.e., top=top+1, and the element will be placed at the new position of
the top.
o The elements will be inserted until we reach the max size of the stack.
POP operation
The steps involved in the POP operation is given below:

o Before deleting the element from the stack, we check whether the stack is empty.
o If we try to delete the element from the empty stack, then the underflow condition
occurs.
o If the stack is not empty, we first access the element which is pointed by the top
o Once the pop operation is performed, the top is decremented by 1, i.e., top=top-1.

Applications of Stack
The following are the applications of the stack:

o Balancing of symbols: Stack is used for balancing a symbol. For example, we have
the following program:

1. int main()
2. {
3. cout<<"Hello";
4. cout<<"javaTpoint";
5. }
As we know, each program has an opening and closing braces; when the opening braces
come, we push the braces in a stack, and when the closing braces appear, we pop the
opening braces from the stack. Therefore, the net value comes out to be zero. If any
symbol is left in the stack, it means that some syntax occurs in a program.

o String reversal: Stack is also used for reversing a string. For example, we want to
reverse a "javaTpoint" string, so we can achieve this with the help of a stack.
First, we push all the characters of the string in a stack until we reach the null
character.
After pushing all the characters, we start taking out the character one by one until we
reach the bottom of the stack.
o UNDO/REDO: It can also be used for performing UNDO/REDO operations. For
example, we have an editor in which we write 'a', then 'b', and then 'c'; therefore, the
text written in an editor is abc. So, there are three states, a, ab, and abc, which are
stored in a stack. There would be two stacks in which one stack shows UNDO state,
and the other shows REDO state.
If we want to perform UNDO operation, and want to achieve 'ab' state, then we
implement pop operation.
o Recursion: The recursion means that the function is calling itself again. To maintain
the previous states, the compiler creates a system stack in which all the previous
records of the function are maintained.
o DFS(Depth First Search): This search is implemented on a Graph, and Graph uses the
stack data structure.
o Backtracking: Suppose we have to create a path to solve a maze problem. If we are
moving in a particular path, and we realize that we come on the wrong way. In order
to come at the beginning of the path to create a new path, we have to use the stack
data structure.
o Expression conversion: Stack can also be used for expression conversion. This is one
of the most important applications of stack. The list of the expression conversion is
given below:
o Infix to prefix
o Infix to postfix
o Prefix to infix
o Prefix to postfix
Postfix to infix
o Memory management: The stack manages the memory. The memory is assigned in
the contiguous memory blocks. The memory is known as stack memory as all the
variables are assigned in a function call stack memory. The memory size assigned to
the program is known to the compiler. When the function is created, all its variables
are assigned in the stack memory. When the function completed its execution, all
the variables assigned in the stack are released.
Array implementation of Stack
In array implementation, the stack is formed by using the array. All the operations regarding
the stack are performed using arrays. Lets see how each operation can be implemented on
the stack using array data structure.

Adding an element onto the stack (push operation)


Adding an element into the top of the stack is referred to as push operation. Push operation
involves following two steps.
1. Increment the variable Top so that it can now refere to the next memory location.
2. Add element at the position of incremented top. This is referred to as adding new element
at the top of the stack.

Stack is overflown when we try to insert an element into a completely filled stack therefore,
our main function must always avoid stack overflow condition.
Algorithm:
PauseNext

Unmute

Current Time 0:24

Duration 18:10

Loaded: 7.34%

Fullscreen

1. begin
2. if top = n then stack full
3. top = top + 1
4. stack (top) : = item;
5. end
Time Complexity : o(1)

implementation of push algorithm in C language


1. void push (int val,int n) //n is size of the stack
2. {
3. if (top == n )
4. printf("\n Overflow");
5. else
6. {
7. top = top +1;
8. stack[top] = val;
9. }
10. }

Deletion of an element from a stack (Pop operation)


Deletion of an element from the top of the stack is called pop operation. The value of the
variable top will be incremented by 1 whenever an item is deleted from the stack. The top
most element of the stack is stored in an another variable and then the top is decremented
by 1. the operation returns the deleted value that was stored in another variable as the result.
The underflow condition occurs when we try to delete an element from an already empty
stack.
Algorithm :
1. begin
2. if top = 0 then stack empty;
3. item := stack(top);
4. top = top - 1;
5. end;
Time Complexity : o(1)

Implementation of POP algorithm using C language


1. int pop ()
2. {
3. if(top == -1)
4. {
5. printf("Underflow");
6. return 0;
7. }
8. else
9. {
10. return stack[top - - ];
11. }
12. }

C program

1. #include <stdio.h>
2. int stack[100],i,j,choice=0,n,top=-1;
3. void push();
4. void pop();
5. void show();
6. void main ()
7. {
8.
9. printf("Enter the number of elements in the stack ");
10. scanf("%d",&n);
11. printf("*********Stack operations using array*********");
12.
13. printf("\n----------------------------------------------\n");
14. while(choice != 4)
15. {
16. printf("Chose one from the below options...\n");
17. printf("\n1.Push\n2.Pop\n3.Show\n4.Exit");
18. printf("\n Enter your choice \n");
19. scanf("%d",&choice);
20. switch(choice)
21. {
22. case 1:
23. {
24. push();
25. break;
26. }
27. case 2:
28. {
29. pop();
30. break;
31. }
32. case 3:
33. {
34. show();
35. break;
36. }
37. case 4:
38. {
39. printf("Exiting....");
40. break;
41. }
42. default:
43. {
44. printf("Please Enter valid choice ");
45. }
46. };
47. }
48. }
49.
50. void push ()
51. {
52. int val;
53. if (top == n )
54. printf("\n Overflow");
55. else
56. {
57. printf("Enter the value?");
58. scanf("%d",&val);
59. top = top +1;
60. stack[top] = val;
61. }
62. }
63.
64. void pop ()
65. {
66. if(top == -1)
67. printf("Underflow");
68. else
69. top = top -1;
70. }
71. void show()
72. {
73. for (i=top;i>=0;i--)
74. {
75. printf("%d\n",stack[i]);
76. }
77. if(top == -1)
78. {
79. printf("Stack is empty");
80. }
81. }

Linked list implementation of stack


Instead of using array, we can also use linked list to implement stack. Linked list allocates
the memory dynamically. However, time complexity in both the scenario is same for all the
operations i.e. push, pop and peek.
In linked list implementation of stack, the nodes are maintained non-contiguously in the
memory. Each node contains a pointer to its immediate successor node in the stack. Stack
is said to be overflown if the space left in the memory heap is not enough to create a node.

The top most node in the stack always contains null in its address field. Lets discuss the way
in which, each operation is performed in linked list implementation of stack.

Adding a node to the stack (Push operation)


Adding a node to the stack is referred to as push operation. Pushing an element to a stack
in linked list implementation is different from that of an array implementation. In order to
push an element onto the stack, the following steps are involved.
PlayNext

Unmute

Current Time 0:05

Duration 18:10

Loaded: 4.04%

Fullscreen
1. Create a node first and allocate memory to it.
2. If the list is empty then the item is to be pushed as the start node of the list. This includes
assigning value to the data part of the node and assign null to the address part of the node.
3. If there are some nodes in the list already, then we have to add the new element in the
beginning of the list (to not violate the property of the stack). For this purpose, assign the
address of the starting element to the address field of the new node and make the new node,
the starting node of the list.

Time Complexity : o(1)


C implementation :
1. void push ()
2. {
3. int val;
4. struct node *ptr =(struct node*)malloc(sizeof(struct node));
5. if(ptr == NULL)
6. {
7. printf("not able to push the element");
8. }
9. else
10. {
11. printf("Enter the value");
12. scanf("%d",&val);
13. if(head==NULL)
14. {
15. ptr->val = val;
16. ptr -> next = NULL;
17. head=ptr;
18. }
19. else
20. {
21. ptr->val = val;
22. ptr->next = head;
23. head=ptr;
24.
25. }
26. printf("Item pushed");
27.
28. }
29. }

Deleting a node from the stack (POP operation)


Deleting a node from the top of stack is referred to as pop operation. Deleting a node
from the linked list implementation of stack is different from that in the array
implementation. In order to pop an element from the stack, we need to follow the
following steps :
30. Check for the underflow condition: The underflow condition occurs when we try to
pop from an already empty stack. The stack will be empty if the head pointer of the
list points to null.
31. Adjust the head pointer accordingly: In stack, the elements are popped only from
one end, therefore, the value stored in the head pointer must be deleted and the
node must be freed. The next node of the head node now becomes the head node.

Time Complexity : o(n)

C implementation
1. void pop()
2. {
3. int item;
4. struct node *ptr;
5. if (head == NULL)
6. {
7. printf("Underflow");
8. }
9. else
10. {
11. item = head->val;
12. ptr = head;
13. head = head->next;
14. free(ptr);
15. printf("Item popped");
16.
17. }
18. }

Display the nodes (Traversing)


Displaying all the nodes of a stack needs traversing all the nodes of the linked list
organized in the form of stack. For this purpose, we need to follow the following
steps.
19. Copy the head pointer into a temporary pointer.
20. Move the temporary pointer through all the nodes of the list and print the value field
attached to every node.

Time Complexity : o(n)

C Implementation
1. void display()
2. {
3. int i;
4. struct node *ptr;
5. ptr=head;
6. if(ptr == NULL)
7. {
8. printf("Stack is empty\n");
9. }
10. else
11. {
12. printf("Printing Stack elements \n");
13. while(ptr!=NULL)
14. {
15. printf("%d\n",ptr->val);
16. ptr = ptr->next;
17. }
18. }
19. }

Menu Driven program in C implementing all the stack


operations using linked list :
1. #include <stdio.h>
2. #include <stdlib.h>
3. void push();
4. void pop();
5. void display();
6. struct node
7. {
8. int val;
9. struct node *next;
10. };
11. struct node *head;
12.
13. void main ()
14. {
15. int choice=0;
16. printf("\n*********Stack operations using linked list*********\n");
17. printf("\n----------------------------------------------\n");
18. while(choice != 4)
19. {
20. printf("\n\nChose one from the below options...\n");
21. printf("\n1.Push\n2.Pop\n3.Show\n4.Exit");
22. printf("\n Enter your choice \n");
23. scanf("%d",&choice);
24. switch(choice)
25. {
26. case 1:
27. {
28. push();
29. break;
30. }
31. case 2:
32. {
33. pop();
34. break;
35. }
36. case 3:
37. {
38. display();
39. break;
40. }
41. case 4:
42. {
43. printf("Exiting....");
44. break;
45. }
46. default:
47. {
48. printf("Please Enter valid choice ");
49. }
50. };
51. }
52. }
53. void push ()
54. {
55. int val;
56. struct node *ptr = (struct node*)malloc(sizeof(struct node));
57. if(ptr == NULL)
58. {
59. printf("not able to push the element");
60. }
61. else
62. {
63. printf("Enter the value");
64. scanf("%d",&val);
65. if(head==NULL)
66. {
67. ptr->val = val;
68. ptr -> next = NULL;
69. head=ptr;
70. }
71. else
72. {
73. ptr->val = val;
74. ptr->next = head;
75. head=ptr;
76.
77. }
78. printf("Item pushed");
79.
80. }
81. }
82.
83. void pop()
84. {
85. int item;
86. struct node *ptr;
87. if (head == NULL)
88. {
89. printf("Underflow");
90. }
91. else
92. {
93. item = head->val;
94. ptr = head;
95. head = head->next;
96. free(ptr);
97. printf("Item popped");
98.
99. }
100. }
101. void display()
102. {
103. int i;
104. struct node *ptr;
105. ptr=head;
106. if(ptr == NULL)
107. {
108. printf("Stack is empty\n");
109. }
110. else
111. {
112. printf("Printing Stack elements \n");
113. while(ptr!=NULL)
114. {
115. printf("%d\n",ptr->val);
116. ptr = ptr->next;
117. }
118. }
119. }

Queue
1. A queue can be defined as an ordered list which enables insert operations to be performed
at one end called REAR and delete operations to be performed at another end
called FRONT.
2. Queue is referred to be as First In First Out list.
3. For example, people waiting in line for a rail ticket form a queue.
Applications of Queue
Due to the fact that queue performs actions on first in first out basis which is quite fair for
the ordering of actions. There are various applications of queues discussed as below.
1. Queues are widely used as waiting lists for a single shared resource like printer, disk, CPU.
2. Queues are used in asynchronous transfer of data (where data is not being transferred at the
same rate between two processes) for eg. pipes, file IO, sockets.
3. Queues are used as buffers in most of the applications like MP3 media player, CD player, etc.
4. Queue are used to maintain the play list in media players in order to add and remove the
songs from the play-list.
5. Queues are used in operating systems for handling interrupts.

Complexity
Data Time Complexity Space
Structure Compleity

Average Worst Worst

Acces Searc Insertion Deletion Acces Searc Insertion Deletion


s h s h

Queue θ(n) θ(n) θ(1) θ(1) O(n) O(n) O(1) O(1) O(n)
Types of Queue
In this article, we will discuss the types of queue. But before moving towards the types, we
should first discuss the brief introduction of the queue.

What is a Queue?
Queue is the data structure that is similar to the queue in the real world. A queue is a data
structure in which whatever comes first will go out first, and it follows the FIFO (First-In-
First-Out) policy. Queue can also be defined as the list or collection in which the insertion
is done from one end known as the rear end or the tail of the queue, whereas the deletion
is done from another end known as the front end or the head of the queue.
The real-world example of a queue is the ticket queue outside a cinema hall, where the
person who enters first in the queue gets the ticket first, and the last person enters in the
queue gets the ticket at last. Similar approach is followed in the queue in data structure.
The representation of the queue is shown in the below image -

Now, let's move towards the types of queue.

Types of Queue
There are four different types of queue that are listed as follows -
o Simple Queue or Linear Queue
o Circular Queue
o Priority Queue
o Double Ended Queue (or Deque)

Let's discuss each of the type of queue.

Simple Queue or Linear Queue


In Linear Queue, an insertion takes place from one end while the deletion occurs from
another end. The end at which the insertion takes place is known as the rear end, and the
end at which the deletion takes place is known as front end. It strictly follows the FIFO rule.

The major drawback of using a linear Queue is that insertion is done only from the rear end.
If the first three elements are deleted from the Queue, we cannot insert more elements even
though the space is available in a Linear Queue. In this case, the linear Queue shows the
overflow condition as the rear is pointing to the last element of the Queue.
To know more about the queue in data structure, you can click the link
- https://www.javatpoint.com/data-structure-queue

Circular Queue
In Circular Queue, all the nodes are represented as circular. It is similar to the linear Queue
except that the last element of the queue is connected to the first element. It is also known
as Ring Buffer, as all the ends are connected to another end. The representation of circular
queue is shown in the below image -

The drawback that occurs in a linear queue is overcome by using the circular queue. If the
empty space is available in a circular queue, the new element can be added in an empty
space by simply incrementing the value of rear. The main advantage of using the circular
queue is better memory utilization.
To know more about the circular queue, you can click the link
- https://www.javatpoint.com/circular-queue

Priority Queue
It is a special type of queue in which the elements are arranged based on the priority. It is a
special type of queue data structure in which every element has a priority associated with
it. Suppose some elements occur with the same priority, they will be arranged according to
the FIFO principle. The representation of priority queue is shown in the below image -
Insertion in priority queue takes place based on the arrival, while deletion in the priority
queue occurs based on the priority. Priority queue is mainly used to implement the CPU
scheduling algorithms.
There are two types of priority queue that are discussed as follows -
o Ascending priority queue - In ascending priority queue, elements can be inserted in arbitrary
order, but only smallest can be deleted first. Suppose an array with elements 7, 5, and 3 in
the same order, so, insertion can be done with the same sequence, but the order of deleting
the elements is 3, 5, 7.
o Descending priority queue - In descending priority queue, elements can be inserted in
arbitrary order, but only the largest element can be deleted first. Suppose an array with
elements 7, 3, and 5 in the same order, so, insertion can be done with the same sequence,
but the order of deleting the elements is 7, 5, 3.

To learn more about the priority queue, you can click the link
- https://www.javatpoint.com/ds-priority-queue

Deque (or, Double Ended Queue)


In Deque or Double Ended Queue, insertion and deletion can be done from both ends of
the queue either from the front or rear. It means that we can insert and delete elements
from both front and rear ends of the queue. Deque can be used as a palindrome checker
means that if we read the string from both ends, then the string would be the same.
Deque can be used both as stack and queue as it allows the insertion and deletion
operations on both ends. Deque can be considered as stack because stack follows the LIFO
(Last In First Out) principle in which insertion and deletion both can be performed only from
one end. And in deque, it is possible to perform both insertion and deletion from one end,
and Deque does not follow the FIFO principle.
The representation of the deque is shown in the below image -

To know more about the deque, you can click the link - https://www.javatpoint.com/ds-
deque
There are two types of deque that are discussed as follows -
o Input restricted deque - As the name implies, in input restricted queue, insertion operation
can be performed at only one end, while deletion can be performed from both ends.

o Output restricted deque - As the name implies, in output restricted queue, deletion
operation can be performed at only one end, while insertion can be performed from both
ends.

Now, let's see the operations performed on the queue.

Operations performed on queue


The fundamental operations that can be performed on queue are listed as follows -
o Enqueue: The Enqueue operation is used to insert the element at the rear end of the queue.
It returns void.
o Dequeue: It performs the deletion from the front-end of the queue. It also returns the
element which has been removed from the front-end. It returns an integer value.
o Peek: This is the third operation that returns the element, which is pointed by the front
pointer in the queue but does not delete it.
o Queue overflow (isfull): It shows the overflow condition when the queue is completely full.
o Queue underflow (isempty): It shows the underflow condition when the Queue is empty,
i.e., no elements are in the Queue.

Now, let's see the ways to implement the queue.


Ways to implement the queue
There are two ways of implementing the Queue:
o Implementation using array: The sequential allocation in a Queue can be implemented using
an array. For more details, click on the below link: https://www.javatpoint.com/array-
representation-of-queue
o Implementation using Linked list: The linked list allocation in a Queue can be implemented
using a linked list. For more details, click on the below
link: https://www.javatpoint.com/linked-list-implementation-of-queue

So, that's all about the article. Hope, the article will be helpful and informative to you.

Array representation of Queue


We can easily represent queue by using linear arrays. There are two variables i.e. front and
rear, that are implemented in the case of every queue. Front and rear variables point to the
position from where insertions and deletions are performed in a queue. Initially, the value
of front and queue is -1 which represents an empty queue. Array representation of a queue
containing 5 elements along with the respective values of front and rear, is shown in the
following figure.

The above figure shows the queue of characters forming the English word "HELLO". Since,
No deletion is performed in the queue till now, therefore the value of front remains -1 .
However, the value of rear increases by one every time an insertion is performed in the
queue. After inserting an element into the queue shown in the above figure, the queue will
look something like following. The value of rear will become 5 while the value of front
remains same.
After deleting an element, the value of front will increase from -1 to 0. however, the queue
will look something like following.

Algorithm to insert any element in a queue


Check if the queue is already full by comparing rear to max - 1. if so, then return an overflow
error.
If the item is to be inserted as the first element in the list, in that case set the value of front
and rear to 0 and insert the element at the rear end.
Otherwise keep increasing the value of rear and insert each element one by one having rear
as the index.
Algorithm
o Step 1: IF REAR = MAX - 1
Write OVERFLOW
Go to step
[END OF IF]
o Step 2: IF FRONT = -1 and REAR = -1
SET FRONT = REAR = 0
ELSE
SET REAR = REAR + 1
[END OF IF]
o Step 3: Set QUEUE[REAR] = NUM
o Step 4: EXIT

C Function
1. void insert (int queue[], int max, int front, int rear, int item)
2. {
3. if (rear + 1 == max)
4. {
5. printf("overflow");
6. }
7. else
8. {
9. if(front == -1 && rear == -1)
10. {
11. front = 0;
12. rear = 0;
13. }
14. else
15. {
16. rear = rear + 1;
17. }
18. queue[rear]=item;
19. }
20. }

Algorithm to delete an element from the queue


If, the value of front is -1 or value of front is greater than rear , write an underflow message
and exit.
Otherwise, keep increasing the value of front and return the item stored at the front end of
the queue at each time.
Algorithm
o Step 1: IF FRONT = -1 or FRONT > REAR
Write UNDERFLOW
ELSE
SET VAL = QUEUE[FRONT]
SET FRONT = FRONT + 1
[END OF IF]
o Step 2: EXIT

C Function
1. int delete (int queue[], int max, int front, int rear)
2. {
3. int y;
4. if (front == -1 || front > rear)
5.
6. {
7. printf("underflow");
8. }
9. else
10. {
11. y = queue[front];
12. if(front == rear)
13. {
14. front = rear = -1;
15. else
16. front = front + 1;
17.
18. }
19. return y;
20. }
21. }

Menu driven program to implement queue using array


1. #include<stdio.h>
2. #include<stdlib.h>
3. #define maxsize 5
4. void insert();
5. void delete();
6. void display();
7. int front = -1, rear = -1;
8. int queue[maxsize];
9. void main ()
10. {
11. int choice;
12. while(choice != 4)
13. {
14. printf("\n*************************Main Menu*****************************\n");
15. printf("\n=================================================================\n");
16. printf("\n1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
17. printf("\nEnter your choice ?");
18. scanf("%d",&choice);
19. switch(choice)
20. {
21. case 1:
22. insert();
23. break;
24. case 2:
25. delete();
26. break;
27. case 3:
28. display();
29. break;
30. case 4:
31. exit(0);
32. break;
33. default:
34. printf("\nEnter valid choice??\n");
35. }
36. }
37. }
38. void insert()
39. {
40. int item;
41. printf("\nEnter the element\n");
42. scanf("\n%d",&item);
43. if(rear == maxsize-1)
44. {
45. printf("\nOVERFLOW\n");
46. return;
47. }
48. if(front == -1 && rear == -1)
49. {
50. front = 0;
51. rear = 0;
52. }
53. else
54. {
55. rear = rear+1;
56. }
57. queue[rear] = item;
58. printf("\nValue inserted ");
59.
60. }
61. void delete()
62. {
63. int item;
64. if (front == -1 || front > rear)
65. {
66. printf("\nUNDERFLOW\n");
67. return;
68.
69. }
70. else
71. {
72. item = queue[front];
73. if(front == rear)
74. {
75. front = -1;
76. rear = -1 ;
77. }
78. else
79. {
80. front = front + 1;
81. }
82. printf("\nvalue deleted ");
83. }
84.
85.
86. }
87.
88. void display()
89. {
90. int i;
91. if(rear == -1)
92. {
93. printf("\nEmpty queue\n");
94. }
95. else
96. { printf("\nprinting values .....\n");
97. for(i=front;i<=rear;i++)
98. {
99. printf("\n%d\n",queue[i]);
100. }
101. }
102. }
Output:
*************Main Menu**************

==============================================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?1

Enter the element


123

Value inserted

*************Main Menu**************

==============================================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?1

Enter the element


90

Value inserted

*************Main Menu**************

===================================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?2

value deleted

*************Main Menu**************
==============================================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?3

printing values .....


90

*************Main Menu**************

==============================================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?4

Drawback of array implementation


Although, the technique of creating a queue is easy, but there are some drawbacks of using
this technique to implement a queue.
o Memory wastage : The space of the array, which is used to store queue elements, can never
be reused to store the elements of that queue because the elements can only be inserted at
front end and the value of front might be so high so that, all the space before that, can never
be filled.

The above figure shows how the memory space is wasted in the array representation of
queue. In the above figure, a queue of size 10 having 3 elements, is shown. The value of the
front variable is 5, therefore, we can not reinsert the values in the place of already deleted
element before the position of front. That much space of the array is wasted and can not be
used in the future (for this queue).
o Deciding the array size

On of the most common problem with array implementation is the size of the array which
requires to be declared in advance. Due to the fact that, the queue can be extended at
runtime depending upon the problem, the extension in the array size is a time taking process
and almost impossible to be performed at runtime since a lot of reallocations take place.
Due to this reason, we can declare the array large enough so that we can store queue
elements as enough as possible but the main problem with this declaration is that, most of
the array slots (nearly half) can never be reused. It will again lead to memory wastage.

Linked List implementation of Queue


Due to the drawbacks discussed in the previous section of this tutorial, the array
implementation can not be used for the large scale applications where the queues are
implemented. One of the alternative of array implementation is linked list implementation
of queue.
The storage requirement of linked representation of a queue with n elements is o(n) while
the time requirement for operations is o(1).
In a linked queue, each node of the queue consists of two parts i.e. data part and the link
part. Each element of the queue points to its immediate next element in the memory.
In the linked queue, there are two pointers maintained in the memory i.e. front pointer and
rear pointer. The front pointer contains the address of the starting element of the queue
while the rear pointer contains the address of the last element of the queue.
Insertion and deletions are performed at rear and front end respectively. If front and rear
both are NULL, it indicates that the queue is empty.
The linked representation of queue is shown in the following figure.

Operation on Linked Queue


There are two basic operations which can be implemented on the linked queues. The
operations are Insertion and Deletion.

Insert operation
The insert operation append the queue by adding an element to the end of the queue. The
new element will be the last element of the queue.
Firstly, allocate the memory for the new node ptr by using the following statement.
1. Ptr = (struct node *) malloc (sizeof(struct node));
There can be the two scenario of inserting this new node ptr into the linked queue.
In the first scenario, we insert element into an empty queue. In this case, the condition front
= NULL becomes true. Now, the new element will be added as the only element of the
queue and the next pointer of front and rear pointer both, will point to NULL.
1. ptr -> data = item;
2. if(front == NULL)
3. {
4. front = ptr;
5. rear = ptr;
6. front -> next = NULL;
7. rear -> next = NULL;
8. }
In the second case, the queue contains more than one element. The condition front = NULL
becomes false. In this scenario, we need to update the end pointer rear so that the next
pointer of rear will point to the new node ptr. Since, this is a linked queue, hence we also
need to make the rear pointer point to the newly added node ptr. We also need to make
the next pointer of rear point to NULL.
1. rear -> next = ptr;
2. rear = ptr;
3. rear->next = NULL;
In this way, the element is inserted into the queue. The algorithm and the C implementation
is given as follows.

Algorithm
o Step 1: Allocate the space for the new node PTR
o Step 2: SET PTR -> DATA = VAL
o Step 3: IF FRONT = NULL
SET FRONT = REAR = PTR
SET FRONT -> NEXT = REAR -> NEXT = NULL
ELSE
SET REAR -> NEXT = PTR
SET REAR = PTR
SET REAR -> NEXT = NULL
[END OF IF]
o Step 4: END

C Function
1. void insert(struct node *ptr, int item; )
2. {
3.
4.
5. ptr = (struct node *) malloc (sizeof(struct node));
6. if(ptr == NULL)
7. {
8. printf("\nOVERFLOW\n");
9. return;
10. }
11. else
12. {
13. ptr -> data = item;
14. if(front == NULL)
15. {
16. front = ptr;
17. rear = ptr;
18. front -> next = NULL;
19. rear -> next = NULL;
20. }
21. else
22. {
23. rear -> next = ptr;
24. rear = ptr;
25. rear->next = NULL;
26. }
27. }
28. }

Deletion
Deletion operation removes the element that is first inserted among all the queue elements.
Firstly, we need to check either the list is empty or not. The condition front == NULL becomes
true if the list is empty, in this case , we simply write underflow on the console and make
exit.
Otherwise, we will delete the element that is pointed by the pointer front. For this purpose,
copy the node pointed by the front pointer into the pointer ptr. Now, shift the front pointer,
point to its next node and free the node pointed by the node ptr. This is done by using the
following statements.
1. ptr = front;
2. front = front -> next;
3. free(ptr);
The algorithm and C function is given as follows.

Algorithm
o Step 1: IF FRONT = NULL
Write " Underflow "
Go to Step 5
[END OF IF]
o Step 2: SET PTR = FRONT
o Step 3: SET FRONT = FRONT -> NEXT
o Step 4: FREE PTR
o Step 5: END

C Function
1. void delete (struct node *ptr)
2. {
3. if(front == NULL)
4. {
5. printf("\nUNDERFLOW\n");
6. return;
7. }
8. else
9. {
10. ptr = front;
11. front = front -> next;
12. free(ptr);
13. }
14. }

Menu-Driven Program implementing all the operations


on Linked Queue
1. #include<stdio.h>
2. #include<stdlib.h>
3. struct node
4. {
5. int data;
6. struct node *next;
7. };
8. struct node *front;
9. struct node *rear;
10. void insert();
11. void delete();
12. void display();
13. void main ()
14. {
15. int choice;
16. while(choice != 4)
17. {
18. printf("\n*************************Main Menu*****************************\n");
19. printf("\n=================================================================\n");
20. printf("\n1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
21. printf("\nEnter your choice ?");
22. scanf("%d",& choice);
23. switch(choice)
24. {
25. case 1:
26. insert();
27. break;
28. case 2:
29. delete();
30. break;
31. case 3:
32. display();
33. break;
34. case 4:
35. exit(0);
36. break;
37. default:
38. printf("\nEnter valid choice??\n");
39. }
40. }
41. }
42. void insert()
43. {
44. struct node *ptr;
45. int item;
46.
47. ptr = (struct node *) malloc (sizeof(struct node));
48. if(ptr == NULL)
49. {
50. printf("\nOVERFLOW\n");
51. return;
52. }
53. else
54. {
55. printf("\nEnter value?\n");
56. scanf("%d",&item);
57. ptr -> data = item;
58. if(front == NULL)
59. {
60. front = ptr;
61. rear = ptr;
62. front -> next = NULL;
63. rear -> next = NULL;
64. }
65. else
66. {
67. rear -> next = ptr;
68. rear = ptr;
69. rear->next = NULL;
70. }
71. }
72. }
73. void delete ()
74. {
75. struct node *ptr;
76. if(front == NULL)
77. {
78. printf("\nUNDERFLOW\n");
79. return;
80. }
81. else
82. {
83. ptr = front;
84. front = front -> next;
85. free(ptr);
86. }
87. }
88. void display()
89. {
90. struct node *ptr;
91. ptr = front;
92. if(front == NULL)
93. {
94. printf("\nEmpty queue\n");
95. }
96. else
97. { printf("\nprinting values .....\n");
98. while(ptr != NULL)
99. {
100. printf("\n%d\n",ptr -> data);
101. ptr = ptr -> next;
102. }
103. }
104. }
Output:
***********Main Menu**********

==============================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?1


Enter value?
123

***********Main Menu**********

==============================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?1

Enter value?
90

***********Main Menu**********

==============================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?3

printing values .....

123

90

***********Main Menu**********

==============================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?2

***********Main Menu**********

==============================
1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?3

printing values .....


90

***********Main Menu**********

==============================

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?4

Circular Queue
Why was the concept of the circular queue introduced?
There was one limitation in the array implementation of Queue. If the rear reaches to the
end position of the Queue then there might be possibility that some vacant spaces are left
in the beginning which cannot be utilized. So, to overcome such limitations, the concept of
the circular queue was introduced.
As we can see in the above image, the rear is at the last position of the Queue and front is
pointing somewhere rather than the 0th position. In the above array, there are only two
elements and other three positions are empty. The rear is at the last position of the Queue;
if we try to insert the element then it will show that there are no empty spaces in the Queue.
There is one solution to avoid such wastage of memory space by shifting both the elements
at the left and adjust the front and rear end accordingly. It is not a practically good approach
because shifting all the elements will consume lots of time. The efficient approach to avoid
the wastage of the memory is to use the circular queue data structure.

What is a Circular Queue?


A circular queue is similar to a linear queue as it is also based on the FIFO (First In First Out)
principle except that the last position is connected to the first position in a circular queue
that forms a circle. It is also known as a Ring Buffer.

Operations on Circular Queue


The following are the operations that can be performed on a circular queue:
o Front: It is used to get the front element from the Queue.
o Rear: It is used to get the rear element from the Queue.
o enQueue(value): This function is used to insert the new value in the Queue. The new element
is always inserted from the rear end.
o deQueue(): This function deletes an element from the Queue. The deletion in a Queue always
takes place from the front end.

Applications of Circular Queue


The circular Queue can be used in the following scenarios:
o Memory management: The circular queue provides memory management. As we have
already seen that in linear queue, the memory is not managed very efficiently. But in case of
a circular queue, the memory is managed efficiently by placing the elements in a location
which is unused.
o CPU Scheduling: The operating system also uses the circular queue to insert the processes
and then execute them.
o Traffic system: In a computer-control traffic system, traffic light is one of the best examples
of the circular queue. Each light of traffic light gets ON one by one after every jinterval of
time. Like red light gets ON for one minute then yellow light for one minute and then green
light. After green light, the red light gets ON.

Enqueue operation
The steps of enqueue operation are given below:
o First, we will check whether the Queue is full or not.
o Initially the front and rear are set to -1. When we insert the first element in a Queue, front
and rear both are set to 0.
o When we insert a new element, the rear gets incremented, i.e., rear=rear+1.

Scenarios for inserting an element


There are two scenarios in which queue is not full:
o If rear != max - 1, then rear will be incremented to mod(maxsize) and the new value will be
inserted at the rear end of the queue.
o If front != 0 and rear = max - 1, it means that queue is not full, then set the value of rear to 0
and insert the new element there.

There are two cases in which the element cannot be inserted:


o When front ==0 && rear = max-1, which means that front is at the first position of the Queue
and rear is at the last position of the Queue.
o front== rear + 1;

Algorithm to insert an element in a circular queue


Step 1: IF (REAR+1)%MAX = FRONT
Write " OVERFLOW "
Goto step 4
[End OF IF]
Step 2: IF FRONT = -1 and REAR = -1
SET FRONT = REAR = 0
ELSE IF REAR = MAX - 1 and FRONT ! = 0
SET REAR = 0
ELSE
SET REAR = (REAR + 1) % MAX
[END OF IF]
Step 3: SET QUEUE[REAR] = VAL
Step 4: EXIT

Dequeue Operation
The steps of dequeue operation are given below:
o First, we check whether the Queue is empty or not. If the queue is empty, we cannot perform
the dequeue operation.
o When the element is deleted, the value of front gets decremented by 1.
o If there is only one element left which is to be deleted, then the front and rear are reset to -
1.

Algorithm to delete an element from the circular queue


Step 1: IF FRONT = -1
Write " UNDERFLOW "
Goto Step 4
[END of IF]
Step 2: SET VAL = QUEUE[FRONT]
Step 3: IF FRONT = REAR
SET FRONT = REAR = -1
ELSE
IF FRONT = MAX -1
SET FRONT = 0
ELSE
SET FRONT = FRONT + 1
[END of IF]
[END OF IF]
Step 4: EXIT
Let's understand the enqueue and dequeue operation through the diagrammatic
representation.
Implementation of circular queue using Array
1. #include <stdio.h>
2.
3. # define max 6
4. int queue[max]; // array declaration
5. int front=-1;
6. int rear=-1;
7. // function to insert an element in a circular queue
8. void enqueue(int element)
9. {
10. if(front==-1 && rear==-1) // condition to check queue is empty
11. {
12. front=0;
13. rear=0;
14. queue[rear]=element;
15. }
16. else if((rear+1)%max==front) // condition to check queue is full
17. {
18. printf("Queue is overflow..");
19. }
20. else
21. {
22. rear=(rear+1)%max; // rear is incremented
23. queue[rear]=element; // assigning a value to the queue at the rear position.
24. }
25. }
26.
27. // function to delete the element from the queue
28. int dequeue()
29. {
30. if((front==-1) && (rear==-1)) // condition to check queue is empty
31. {
32. printf("\nQueue is underflow..");
33. }
34. else if(front==rear)
35. {
36. printf("\nThe dequeued element is %d", queue[front]);
37. front=-1;
38. rear=-1;
39. }
40. else
41. {
42. printf("\nThe dequeued element is %d", queue[front]);
43. front=(front+1)%max;
44. }
45. }
46. // function to display the elements of a queue
47. void display()
48. {
49. int i=front;
50. if(front==-1 && rear==-1)
51. {
52. printf("\n Queue is empty..");
53. }
54. else
55. {
56. printf("\nElements in a Queue are :");
57. while(i<=rear)
58. {
59. printf("%d,", queue[i]);
60. i=(i+1)%max;
61. }
62. }
63. }
64. int main()
65. {
66. int choice=1,x; // variables declaration
67.
68. while(choice<4 && choice!=0) // while loop
69. {
70. printf("\n Press 1: Insert an element");
71. printf("\nPress 2: Delete an element");
72. printf("\nPress 3: Display the element");
73. printf("\nEnter your choice");
74. scanf("%d", &choice);
75.
76. switch(choice)
77. {
78.
79. case 1:
80.
81. printf("Enter the element which is to be inserted");
82. scanf("%d", &x);
83. enqueue(x);
84. break;
85. case 2:
86. dequeue();
87. break;
88. case 3:
89. display();
90.
91. }}
92. return 0;
93. }
Output:
Implementation of circular queue using linked list
As we know that linked list is a linear data structure that stores two parts, i.e., data part and
the address part where address part contains the address of the next node. Here, linked list
is used to implement the circular queue; therefore, the linked list follows the properties of
the Queue. When we are implementing the circular queue using linked list then both
the enqueue and dequeue operations take O(1) time.
1. #include <stdio.h>
2. // Declaration of struct type node
3. struct node
4. {
5. int data;
6. struct node *next;
7. };
8. struct node *front=-1;
9. struct node *rear=-1;
10. // function to insert the element in the Queue
11. void enqueue(int x)
12. {
13. struct node *newnode; // declaration of pointer of struct node type.
14. newnode=(struct node *)malloc(sizeof(struct node)); // allocating the memory to the newnode
15. newnode->data=x;
16. newnode->next=0;
17. if(rear==-1) // checking whether the Queue is empty or not.
18. {
19. front=rear=newnode;
20. rear->next=front;
21. }
22. else
23. {
24. rear->next=newnode;
25. rear=newnode;
26. rear->next=front;
27. }
28. }
29.
30. // function to delete the element from the queue
31. void dequeue()
32. {
33. struct node *temp; // declaration of pointer of node type
34. temp=front;
35. if((front==-1)&&(rear==-1)) // checking whether the queue is empty or not
36. {
37. printf("\nQueue is empty");
38. }
39. else if(front==rear) // checking whether the single element is left in the queue
40. {
41. front=rear=-1;
42. free(temp);
43. }
44. else
45. {
46. front=front->next;
47. rear->next=front;
48. free(temp);
49. }
50. }
51.
52. // function to get the front of the queue
53. int peek()
54. {
55. if((front==-1) &&(rear==-1))
56. {
57. printf("\nQueue is empty");
58. }
59. else
60. {
61. printf("\nThe front element is %d", front->data);
62. }
63. }
64.
65. // function to display all the elements of the queue
66. void display()
67. {
68. struct node *temp;
69. temp=front;
70. printf("\n The elements in a Queue are : ");
71. if((front==-1) && (rear==-1))
72. {
73. printf("Queue is empty");
74. }
75.
76. else
77. {
78. while(temp->next!=front)
79. {
80. printf("%d,", temp->data);
81. temp=temp->next;
82. }
83. printf("%d", temp->data);
84. }
85. }
86.
87. void main()
88. {
89. enqueue(34);
90. enqueue(10);
91. enqueue(23);
92. display();
93. dequeue();
94. peek();
95. }
Output:

Deque (or double-ended queue)


In this article, we will discuss the double-ended queue or deque. We should first see a brief
description of the queue.

What is a queue?
A queue is a data structure in which whatever comes first will go out first, and it follows the
FIFO (First-In-First-Out) policy. Insertion in the queue is done from one end known as
the rear end or the tail, whereas the deletion is done from another end known as the front
end or the head of the queue.
The real-world example of a queue is the ticket queue outside a cinema hall, where the
person who enters first in the queue gets the ticket first, and the person enters last in the
queue gets the ticket at last.

What is a Deque (or double-ended queue)


The deque stands for Double Ended Queue. Deque is a linear data structure where the
insertion and deletion operations are performed from both ends. We can say that deque is
a generalized version of the queue.
PlayNext

Unmute

Current Time 0:02

Duration 18:10

Loaded: 3.30%

Fullscreen
Though the insertion and deletion in a deque can be performed on both ends, it does not
follow the FIFO rule. The representation of a deque is given as follows -

Types of deque
There are two types of deque -
o Input restricted queue
o Output restricted queue

Input restricted Queue


In input restricted queue, insertion operation can be performed at only one end, while
deletion can be performed from both ends.

Output restricted Queue


In output restricted queue, deletion operation can be performed at only one end, while
insertion can be performed from both ends.
Operations performed on deque
There are the following operations that can be applied on a deque -
o Insertion at front
o Insertion at rear
o Deletion at front
o Deletion at rear

We can also perform peek operations in the deque along with the operations listed above.
Through peek operation, we can get the deque's front and rear elements of the deque. So,
in addition to the above operations, following operations are also supported in deque -
o Get the front item from the deque
o Get the rear item from the deque
o Check whether the deque is full or not
o Checks whether the deque is empty or not

Now, let's understand the operation performed on deque using an example.


Insertion at the front end
In this operation, the element is inserted from the front end of the queue. Before
implementing the operation, we first have to check whether the queue is full or not. If the
queue is not full, then the element can be inserted from the front end by using the below
conditions -
o If the queue is empty, both rear and front are initialized with 0. Now, both will point to the
first element.
o Otherwise, check the position of the front if the front is less than 1 (front < 1), then reinitialize
it by front = n - 1, i.e., the last index of the array.
Insertion at the rear end
In this operation, the element is inserted from the rear end of the queue. Before
implementing the operation, we first have to check again whether the queue is full or not. If
the queue is not full, then the element can be inserted from the rear end by using the below
conditions -
o If the queue is empty, both rear and front are initialized with 0. Now, both will point to the
first element.
o Otherwise, increment the rear by 1. If the rear is at last index (or size - 1), then instead of
increasing it by 1, we have to make it equal to 0.

Deletion at the front end


In this operation, the element is deleted from the front end of the queue. Before
implementing the operation, we first have to check whether the queue is empty or not.
If the queue is empty, i.e., front = -1, it is the underflow condition, and we cannot perform
the deletion. If the queue is not full, then the element can be inserted from the front end by
using the below conditions -
If the deque has only one element, set rear = -1 and front = -1.
Else if front is at end (that means front = size - 1), set front = 0.
Else increment the front by 1, (i.e., front = front + 1).

Deletion at the rear end


In this operation, the element is deleted from the rear end of the queue. Before
implementing the operation, we first have to check whether the queue is empty or not.
If the queue is empty, i.e., front = -1, it is the underflow condition, and we cannot perform
the deletion.
If the deque has only one element, set rear = -1 and front = -1.
If rear = 0 (rear is at front), then set rear = n - 1.
Else, decrement the rear by 1 (or, rear = rear -1).
Check empty
This operation is performed to check whether the deque is empty or not. If front = -1, it
means that the deque is empty.
Check full
This operation is performed to check whether the deque is full or not. If front = rear + 1, or
front = 0 and rear = n - 1 it means that the deque is full.
The time complexity of all of the above operations of the deque is O(1), i.e., constant.

Applications of deque
o Deque can be used as both stack and queue, as it supports both operations.
o Deque can be used as a palindrome checker means that if we read the string from both ends,
the string would be the same.

Implementation of deque
Now, let's see the implementation of deque in C programming language.
1. #include <stdio.h>
2. #define size 5
3. int deque[size];
4. int f = -1, r = -1;
5. // insert_front function will insert the value from the front
6. void insert_front(int x)
7. {
8. if((f==0 && r==size-1) || (f==r+1))
9. {
10. printf("Overflow");
11. }
12. else if((f==-1) && (r==-1))
13. {
14. f=r=0;
15. deque[f]=x;
16. }
17. else if(f==0)
18. {
19. f=size-1;
20. deque[f]=x;
21. }
22. else
23. {
24. f=f-1;
25. deque[f]=x;
26. }
27. }
28.
29. // insert_rear function will insert the value from the rear
30. void insert_rear(int x)
31. {
32. if((f==0 && r==size-1) || (f==r+1))
33. {
34. printf("Overflow");
35. }
36. else if((f==-1) && (r==-1))
37. {
38. r=0;
39. deque[r]=x;
40. }
41. else if(r==size-1)
42. {
43. r=0;
44. deque[r]=x;
45. }
46. else
47. {
48. r++;
49. deque[r]=x;
50. }
51.
52. }
53.
54. // display function prints all the value of deque.
55. void display()
56. {
57. int i=f;
58. printf("\nElements in a deque are: ");
59.
60. while(i!=r)
61. {
62. printf("%d ",deque[i]);
63. i=(i+1)%size;
64. }
65. printf("%d",deque[r]);
66. }
67.
68. // getfront function retrieves the first value of the deque.
69. void getfront()
70. {
71. if((f==-1) && (r==-1))
72. {
73. printf("Deque is empty");
74. }
75. else
76. {
77. printf("\nThe value of the element at front is: %d", deque[f]);
78. }
79.
80. }
81.
82. // getrear function retrieves the last value of the deque.
83. void getrear()
84. {
85. if((f==-1) && (r==-1))
86. {
87. printf("Deque is empty");
88. }
89. else
90. {
91. printf("\nThe value of the element at rear is %d", deque[r]);
92. }
93.
94. }
95.
96. // delete_front() function deletes the element from the front
97. void delete_front()
98. {
99. if((f==-1) && (r==-1))
100. {
101. printf("Deque is empty");
102. }
103. else if(f==r)
104. {
105. printf("\nThe deleted element is %d", deque[f]);
106. f=-1;
107. r=-1;
108.
109. }
110. else if(f==(size-1))
111. {
112. printf("\nThe deleted element is %d", deque[f]);
113. f=0;
114. }
115. else
116. {
117. printf("\nThe deleted element is %d", deque[f]);
118. f=f+1;
119. }
120. }
121.
122. // delete_rear() function deletes the element from the rear
123. void delete_rear()
124. {
125. if((f==-1) && (r==-1))
126. {
127. printf("Deque is empty");
128. }
129. else if(f==r)
130. {
131. printf("\nThe deleted element is %d", deque[r]);
132. f=-1;
133. r=-1;
134.
135. }
136. else if(r==0)
137. {
138. printf("\nThe deleted element is %d", deque[r]);
139. r=size-1;
140. }
141. else
142. {
143. printf("\nThe deleted element is %d", deque[r]);
144. r=r-1;
145. }
146. }
147.
148.int main()
149. {
150. insert_front(20);
151. insert_front(10);
152. insert_rear(30);
153. insert_rear(50);
154. insert_rear(80);
155. display(); // Calling the display function to retrieve the values of deque
156. getfront(); // Retrieve the value at front-end
157. getrear(); // Retrieve the value at rear-end
158. delete_front();
159. delete_rear();
160. display(); // calling display function to retrieve values after deletion
161. return 0;
162. }
Output:

What is a priority queue?


A priority queue is an abstract data type that behaves similarly to the normal queue except
that each element has some priority, i.e., the element with the highest priority would come
first in a priority queue. The priority of the elements in a priority queue will determine the
order in which elements are removed from the priority queue.
The priority queue supports only comparable elements, which means that the elements are
either arranged in an ascending or descending order.
For example, suppose we have some values like 1, 3, 4, 8, 14, 22 inserted in a priority queue
with an ordering imposed on the values is from least to the greatest. Therefore, the 1 number
would be having the highest priority while 22 will be having the lowest priority.

Characteristics of a Priority queue


A priority queue is an extension of a queue that contains the following characteristics:
o Every element in a priority queue has some priority associated with it.
o An element with the higher priority will be deleted before the deletion of the lesser priority.
o If two elements in a priority queue have the same priority, they will be arranged using the
FIFO principle.

Let's understand the priority queue through an example.


We have a priority queue that contains the following values:
1, 3, 4, 8, 14, 22
All the values are arranged in ascending order. Now, we will observe how the priority queue
will look after performing the following operations:
o poll(): This function will remove the highest priority element from the priority queue. In the
above priority queue, the '1' element has the highest priority, so it will be removed from the
priority queue.
o add(2): This function will insert '2' element in a priority queue. As 2 is the smallest element
among all the numbers so it will obtain the highest priority.
o poll(): It will remove '2' element from the priority queue as it has the highest priority queue.
o add(5): It will insert 5 element after 4 as 5 is larger than 4 and lesser than 8, so it will obtain
the third highest priority in a priority queue.

Types of Priority Queue


There are two types of priority queue:
o Ascending order priority queue: In ascending order priority queue, a lower priority number
is given as a higher priority in a priority. For example, we take the numbers from 1 to 5
arranged in an ascending order like 1,2,3,4,5; therefore, the smallest number, i.e., 1 is given as
the highest priority in a priority queue.

o Descending order priority queue: In descending order priority queue, a higher priority
number is given as a higher priority in a priority. For example, we take the numbers from 1
to 5 arranged in descending order like 5, 4, 3, 2, 1; therefore, the largest number, i.e., 5 is
given as the highest priority in a priority queue.

Representation of priority queue


Now, we will see how to represent the priority queue through a one-way list.
We will create the priority queue by using the list given below in which INFO list contains
the data elements, PRN list contains the priority numbers of each data element available in
the INFO list, and LINK basically contains the address of the next node.

Let's create the priority queue step by step.


In the case of priority queue, lower priority number is considered the higher priority,
i.e., lower priority number = higher priority.
Step 1: In the list, lower priority number is 1, whose data value is 333, so it will be inserted
in the list as shown in the below diagram:
Step 2: After inserting 333, priority number 2 is having a higher priority, and data values
associated with this priority are 222 and 111. So, this data will be inserted based on the FIFO
principle; therefore 222 will be added first and then 111.
Step 3: After inserting the elements of priority 2, the next higher priority number is 4 and
data elements associated with 4 priority numbers are 444, 555, 777. In this case, elements
would be inserted based on the FIFO principle; therefore, 444 will be added first, then 555,
and then 777.
Step 4: After inserting the elements of priority 4, the next higher priority number is 5, and
the value associated with priority 5 is 666, so it will be inserted at the end of the queue.

Implementation of Priority Queue


The priority queue can be implemented in four ways that include arrays, linked list, heap
data structure and binary search tree. The heap data structure is the most efficient way of
implementing the priority queue, so we will implement the priority queue using a heap data
structure in this topic. Now, first we understand the reason why heap is the most efficient
way among all the other data structures.
Analysis of complexities using different implementations

Implementation add Remove peek

Linked list O(1) O(n) O(n)

Binary heap O(logn) O(logn) O(1)


Binary search tree O(logn) O(logn) O(1)

What is Heap?
A heap is a tree-based data structure that forms a complete binary tree, and satisfies the
heap property. If A is a parent node of B, then A is ordered with respect to the node B for all
nodes A and B in a heap. It means that the value of the parent node could be more than or
equal to the value of the child node, or the value of the parent node could be less than or
equal to the value of the child node. Therefore, we can say that there are two types of heaps:
o Max heap: The max heap is a heap in which the value of the parent node is greater than the
value of the child nodes.
o Min heap: The min heap is a heap in which the value of the parent node is less than the value
of the child nodes.

Both the heaps are the binary heap, as each has exactly two child nodes.

Priority Queue Operations


The common operations that we can perform on a priority queue are insertion, deletion and
peek. Let's see how we can maintain the heap data structure.
o Inserting the element in a priority queue (max heap)

If we insert an element in a priority queue, it will move to the empty slot by looking from
top to bottom and left to right.
If the element is not in a correct place then it is compared with the parent node; if it is found
out of order, elements are swapped. This process continues until the element is placed in a
correct position.
o Removing the minimum element from the priority queue

As we know that in a max heap, the maximum element is the root node. When we remove
the root node, it creates an empty slot. The last inserted element will be added in this empty
slot. Then, this element is compared with the child nodes, i.e., left-child and right child, and
swap with the smaller of the two. It keeps moving down the tree until the heap property is
restored.
Applications of Priority queue
The following are the applications of the priority queue:
o It is used in the Dijkstra's shortest path algorithm.
o It is used in prim's algorithm
o It is used in data compression techniques like Huffman code.
o It is used in heap sort.
o It is also used in operating system like priority scheduling, load balancing and interrupt
handling.

Program to create the priority queue using the binary max heap.
1. #include <stdio.h>
2. #include <stdio.h>
3. int heap[40];
4. int size=-1;
5.
6. // retrieving the parent node of the child node
7. int parent(int i)
8. {
9.
10. return (i - 1) / 2;
11. }
12.
13. // retrieving the left child of the parent node.
14. int left_child(int i)
15. {
16. return i+1;
17. }
18. // retrieving the right child of the parent
19. int right_child(int i)
20. {
21. return i+2;
22. }
23. // Returning the element having the highest priority
24. int get_Max()
25. {
26. return heap[0];
27. }
28. //Returning the element having the minimum priority
29. int get_Min()
30. {
31. return heap[size];
32. }
33. // function to move the node up the tree in order to restore the heap property.
34. void moveUp(int i)
35. {
36. while (i > 0)
37. {
38. // swapping parent node with a child node
39. if(heap[parent(i)] < heap[i]) {
40.
41. int temp;
42. temp=heap[parent(i)];
43. heap[parent(i)]=heap[i];
44. heap[i]=temp;
45.
46.
47. }
48. // updating the value of i to i/2
49. i=i/2;
50. }
51. }
52.
53. //function to move the node down the tree in order to restore the heap property.
54. void moveDown(int k)
55. {
56. int index = k;
57.
58. // getting the location of the Left Child
59. int left = left_child(k);
60.
61. if (left <= size && heap[left] > heap[index]) {
62. index = left;
63. }
64.
65. // getting the location of the Right Child
66. int right = right_child(k);
67.
68. if (right <= size && heap[right] > heap[index]) {
69. index = right;
70. }
71.
72. // If k is not equal to index
73. if (k != index) {
74. int temp;
75. temp=heap[index];
76. heap[index]=heap[k];
77. heap[k]=temp;
78. moveDown(index);
79. }
80. }
81.
82. // Removing the element of maximum priority
83. void removeMax()
84. {
85. int r= heap[0];
86. heap[0]=heap[size];
87. size=size-1;
88. moveDown(0);
89. }
90. //inserting the element in a priority queue
91. void insert(int p)
92. {
93. size = size + 1;
94. heap[size] = p;
95.
96. // move Up to maintain heap property
97. moveUp(size);
98. }
99.
100. //Removing the element from the priority queue at a given index i.
101. void delete(int i)
102. {
103. heap[i] = heap[0] + 1;
104.
105. // move the node stored at ith location is shifted to the root node
106. moveUp(i);
107.
108. // Removing the node having maximum priority
109. removeMax();
110. }
111. int main()
112. {
113. // Inserting the elements in a priority queue
114.
115. insert(20);
116. insert(19);
117. insert(21);
118. insert(18);
119. insert(12);
120. insert(17);
121. insert(15);
122. insert(16);
123. insert(14);
124. int i=0;
125.
126. printf("Elements in a priority queue are : ");
127. for(int i=0;i<=size;i++)
128. {
129. printf("%d ",heap[i]);
130. }
131. delete(2); // deleting the element whose index is 2.
132. printf("\nElements in a priority queue after deleting the element are : ");
133. for(int i=0;i<=size;i++)
134. {
135. printf("%d ",heap[i]);
136. }
137. int max=get_Max();
138. printf("\nThe element which is having the highest priority is %d: ",max);
139.
140.
141. int min=get_Min();
142. printf("\nThe element which is having the minimum priority is : %d",min);
143. return 0;
144. }
In the above program, we have created the following functions:
o int parent(int i): This function returns the index of the parent node of a child node, i.e., i.
o int left_child(int i): This function returns the index of the left child of a given index, i.e., i.
o int right_child(int i): This function returns the index of the right child of a given index, i.e., i.
o void moveUp(int i): This function will keep moving the node up the tree until the heap
property is restored.
o void moveDown(int i): This function will keep moving the node down the tree until the heap
property is restored.
o void removeMax(): This function removes the element which is having the highest priority.
o void insert(int p): It inserts the element in a priority queue which is passed as an argument
in a function.
o void delete(int i): It deletes the element from a priority queue at a given index.
o int get_Max(): It returns the element which is having the highest priority, and we know that
in max heap, the root node contains the element which has the largest value, and highest
priority.
o int get_Min(): It returns the element which is having the minimum priority, and we know that
in max heap, the last node contains the element which has the smallest value, and lowest
priority.

Output
Linked list
In this article, we will see the introduction of linked list.

Linked list is a linear data structure that includes a series of connected nodes. Linked list can be
defined as the nodes that are randomly stored in the memory. A node in the linked list contains
two parts, i.e., first is the data part and second is the address part. The last node of the list
contains a pointer to the null. After array, linked list is the second most used data structure. In a
linked list, every link contains a connection to another link.

Representation of a Linked list


Linked list can be represented as the connection of nodes in which each node points to the next
node of the list. The representation of the linked list is shown below -

Till now, we have been using array data structure to organize the group of elements that are to be
stored individually in the memory. However, Array has several advantages and disadvantages
that must be known to decide the data structure that will be used throughout the program.
Now, the question arises why we should use linked list over array?

Why use linked list over array?


Linked list is a data structure that overcomes the limitations of arrays. Let's first see some of the
limitations of arrays -
o The size of the array must be known in advance before using it in the program.
o Increasing the size of the array is a time taking process. It is almost impossible to expand the
size of the array at run time.
o All the elements in the array need to be contiguously stored in the memory. Inserting an
element in the array needs shifting of all its predecessors.

Linked list is useful because -


o It allocates the memory dynamically. All the nodes of the linked list are non-contiguously
stored in the memory and linked together with the help of pointers.
o In linked list, size is no longer a problem since we do not need to define its size at the time of
declaration. List grows as per the program's demand and limited to the available memory
space.

How to declare a linked list?


It is simple to declare an array, as it is of single type, while the declaration of linked list is a bit
more typical than array. Linked list contains two parts, and both are of different types, i.e., one is
the simple variable, while another is the pointer variable. We can declare the linked list by using
the user-defined data type structure.

The declaration of linked list is given as follows -


1. struct node
2. {
3. int data;
4. struct node *next;
5. }
In the above declaration, we have defined a structure named as node that contains two variables,
one is data that is of integer type, and another one is next that is a pointer which contains the
address of next node.
Now, let's move towards the types of linked list.

Types of Linked list


Linked list is classified into the following types -
o Singly-linked list - Singly linked list can be defined as the collection of an ordered set of
elements. A node in the singly linked list consists of two parts: data part and link part. Data
part of the node stores actual information that is to be represented by the node, while the
link part of the node stores the address of its immediate successor.
o Doubly linked list - Doubly linked list is a complex type of linked list in which a node contains
a pointer to the previous as well as the next node in the sequence. Therefore, in a doubly-
linked list, a node consists of three parts: node data, pointer to the next node in sequence
(next pointer), and pointer to the previous node (previous pointer).
o Circular singly linked list - In a circular singly linked list, the last node of the list contains a
pointer to the first node of the list. We can have circular singly linked list as well as circular
doubly linked list.
o Circular doubly linked list - Circular doubly linked list is a more complex type of data
structure in which a node contains pointers to its previous node as well as the next node.
Circular doubly linked list doesn't contain NULL in any of the nodes. The last node of the list
contains the address of the first node of the list. The first node of the list also contains the
address of the last node in its previous pointer.

Now, let's see the benefits and limitations of using the Linked list.

Advantages of Linked list


The advantages of using the Linked list are given as follows -
o Dynamic data structure - The size of the linked list may vary according to the requirements.
Linked list does not have a fixed size.
o Insertion and deletion - Unlike arrays, insertion, and deletion in linked list is easier. Array
elements are stored in the consecutive location, whereas the elements in the linked list are
stored at a random location. To insert or delete an element in an array, we have to shift the
elements for creating the space. Whereas, in linked list, instead of shifting, we just have to
update the address of the pointer of the node.
o Memory efficient - The size of a linked list can grow or shrink according to the requirements,
so memory consumption in linked list is efficient.
o Implementation - We can implement both stacks and queues using linked list.

Disadvantages of Linked list


The limitations of using the Linked list are given as follows -
o Memory usage - In linked list, node occupies more memory than array. Each node of the
linked list occupies two types of variables, i.e., one is a simple variable, and another one is
the pointer variable.
o Traversal - Traversal is not easy in the linked list. If we have to access an element in the
linked list, we cannot access it randomly, while in case of array we can randomly access it
by index. For example, if we want to access the 3rd node, then we need to traverse all the
nodes before it. So, the time required to access a particular node is large.
o Reverse traversing - Backtracking or reverse traversing is difficult in a linked list. In a doubly-
linked list, it is easier but requires more memory to store the back pointer.

Applications of Linked list


The applications of the Linked list are given as follows -
o With the help of a linked list, the polynomials can be represented as well as we can perform
the operations on the polynomial.
o A linked list can be used to represent the sparse matrix.
o The various operations like student's details, employee's details, or product details can be
implemented using the linked list as the linked list uses the structure data type that can hold
different data types.
o Using linked list, we can implement stack, queue, tree, and other various data structures.
o The graph is a collection of edges and vertices, and the graph can be represented as an
adjacency matrix and adjacency list. If we want to represent the graph as an adjacency
matrix, then it can be implemented as an array. If we want to represent the graph as an
adjacency list, then it can be implemented as a linked list.
o A linked list can be used to implement dynamic memory allocation. The dynamic memory
allocation is the memory allocation done at the run-time.

Operations performed on Linked list


The basic operations that are supported by a list are mentioned as follows -
o Insertion - This operation is performed to add an element into the list.
o Deletion - It is performed to delete an operation from the list.
o Display - It is performed to display the elements of the list.
o Search - It is performed to search an element from the list using the given key.

Complexity of Linked list


Now, let's see the time and space complexity of the linked list for the operations search, insert,
and delete.

1. Time Complexity

Operations Average case time complexity Worst-case time complexity

Insertion O(1) O(1)

Deletion O(1) O(1)

Search O(n) O(n)


Where 'n' is the number of nodes in the given tree.

2. Space Complexity

Operations Space complexity

Insertion O(n)

Deletion O(n)

Search O(n)

The space complexity of linked list is O(n).

Types of Linked List


Before knowing about the types of a linked list, we should know what is linked list. So, to
know about the linked list, click on the link given below:

Types of Linked list


The following are the types of linked list:
o Singly Linked list
o Doubly Linked list
o Circular Linked list
o Doubly Circular Linked list

Singly Linked list


It is the commonly used linked list in programs. If we are talking about the linked list, it
means it is a singly linked list. The singly linked list is a data structure that contains two parts,
i.e., one is the data part, and the other one is the address part, which contains the address
of the next or the successor node. The address part in a node is also known as a pointer.
Suppose we have three nodes, and the addresses of these three nodes are 100, 200 and
300 respectively. The representation of three nodes as a linked list is shown in the below
figure:
We can observe in the above figure that there are three different nodes having address 100,
200 and 300 respectively. The first node contains the address of the next node, i.e., 200,
the second node contains the address of the last node, i.e., 300, and the third node contains
the NULL value in its address part as it does not point to any node. The pointer that holds
the address of the initial node is known as a head pointer.
The linked list, which is shown in the above diagram, is known as a singly linked list as it
contains only a single link. In this list, only forward traversal is possible; we cannot traverse
in the backward direction as it has only one link in the list.
Representation of the node in a singly linked list
1. struct node
2. {
3. int data;
4. struct node *next;
5. }
In the above representation, we have defined a user-defined structure named
a node containing two members, the first one is data of integer type, and the other one is
the pointer (next) of the node type.
To know more about a singly linked list, click on the link given below:
https://www.javatpoint.com/singly-linked-list

Doubly linked list


As the name suggests, the doubly linked list contains two pointers. We can define the
doubly linked list as a linear data structure with three parts: the data part and the other two
address part. In other words, a doubly linked list is a list that has three parts in a single node,
includes one data part, a pointer to its previous node, and a pointer to the next node.
Suppose we have three nodes, and the address of these nodes are 100, 200 and 300,
respectively. The representation of these nodes in a doubly-linked list is shown below:
As we can observe in the above figure, the node in a doubly-linked list has two address
parts; one part stores the address of the next while the other part of the node stores
the previous node's address. The initial node in the doubly linked list has the NULL value in
the address part, which provides the address of the previous node.
Representation of the node in a doubly linked list
1. struct node
2. {
3. int data;
4. struct node *next;
5. struct node *prev;
6. }
In the above representation, we have defined a user-defined structure named a node with
three members, one is data of integer type, and the other two are the pointers, i.e., next and
prev of the node type. The next pointer variable holds the address of the next node, and
the prev pointer holds the address of the previous node. The type of both the pointers,
i.e., next and prev is struct node as both the pointers are storing the address of the node of
the struct node type.
To know more about doubly linked list, click on the link given below:
https://www.javatpoint.com/doubly-linked-list

Circular linked list


A circular linked list is a variation of a singly linked list. The only difference between
the singly linked list and a circular linked list is that the last node does not point to any node
in a singly linked list, so its link part contains a NULL value. On the other hand, the circular
linked list is a list in which the last node connects to the first node, so the link part of the last
node holds the first node's address. The circular linked list has no starting and ending node.
We can traverse in any direction, i.e., either backward or forward. The diagrammatic
representation of the circular linked list is shown below:
1. struct node
2. {
3. int data;
4. struct node *next;
5. }
A circular linked list is a sequence of elements in which each node has a link to the next
node, and the last node is having a link to the first node. The representation of the circular
linked list will be similar to the singly linked list, as shown below:

To know more about the circular linked list, click on the link given below:
https://www.javatpoint.com/circular-singly-linked-list

Doubly Circular linked list


The doubly circular linked list has the features of both the circular linked list and doubly
linked list.

The above figure shows the representation of the doubly circular linked list in which the last
node is attached to the first node and thus creates a circle. It is a doubly linked list also
because each node holds the address of the previous node also. The main difference
between the doubly linked list and doubly circular linked list is that the doubly circular linked
list does not contain the NULL value in the previous field of the node. As the doubly circular
linked contains three parts, i.e., two address parts and one data part so its representation is
similar to the doubly linked list.
1. struct node
2. {
3. int data;
4. struct node *next;
5. struct node *prev;
6. }
To know more about the doubly circular linked list, click on the link given below:
https://www.javatpoint.com/circular-doubly-linked-list

Linked List
o Linked List can be defined as collection of objects called nodes that are randomly stored in
the memory.
o A node contains two fields i.e. data stored at that particular address and the pointer which
contains the address of the next node in the memory.
o The last node of the list contains pointer to the null.

Uses of Linked List


o The list is not required to be contiguously present in the memory. The node can reside any
where in the memory and linked together to make a list. This achieves optimized utilization
of space.
o list size is limited to the memory size and doesn't need to be declared in advance.
o Empty node can not be present in the linked list.
o We can store values of primitive types or objects in the singly linked list.

Why use linked list over array?


Till now, we were using array data structure to organize the group of elements that are to
be stored individually in the memory. However, Array has several advantages and
disadvantages which must be known in order to decide the data structure which will be
used throughout the program.
Array contains following limitations:
1. The size of array must be known in advance before using it in the program.
2. Increasing size of the array is a time taking process. It is almost impossible to expand the size
of the array at run time.
3. All the elements in the array need to be contiguously stored in the memory. Inserting any
element in the array needs shifting of all its predecessors.

Linked list is the data structure which can overcome all the limitations of an array. Using
linked list is useful because,
1. It allocates the memory dynamically. All the nodes of linked list are non-contiguously stored
in the memory and linked together with the help of pointers.
2. Sizing is no longer a problem since we do not need to define its size at the time of declaration.
List grows as per the program's demand and limited to the available memory space.

Singly linked list or One way chain


Singly linked list can be defined as the collection of ordered set of elements. The number of
elements may vary according to need of the program. A node in the singly linked list consist
of two parts: data part and link part. Data part of the node stores actual information that is
to be represented by the node while the link part of the node stores the address of its
immediate successor.
PlayNext

Unmute

Current Time 0:01

Duration 18:10

Loaded: 3.30%

Fullscreen

One way chain or singly linked list can be traversed only in one direction. In other words,
we can say that each node contains only next pointer, therefore we can not traverse the list
in the reverse direction.
Consider an example where the marks obtained by the student in three subjects are stored
in a linked list as shown in the figure.
In the above figure, the arrow represents the links. The data part of every node contains the
marks obtained by the student in the different subject. The last node in the list is identified
by the null pointer which is present in the address part of the last node. We can have as
many elements we require, in the data part of the list.

Complexity
Data Time Complexity Space
Structure Compleity

Average Worst Worst

Acces Searc Insertion Deletion Acces Searc Insertion Deletion


s h s h

Singly Linked List θ(n) θ(n) θ(1) θ(1) O(n) O(n) O(1) O(1) O(n)

Operations on Singly Linked List


There are various operations which can be performed on singly linked list. A list of all such
operations is given below.

Node Creation
1. struct node
2. {
3. int data;
4. struct node *next;
5. };
6. struct node *head, *ptr;
7. ptr = (struct node *)malloc(sizeof(struct node *));

Insertion
The insertion into a singly linked list can be performed at different positions. Based on the
position of the new node being inserted, the insertion is categorized into the following
categories.

SN Operation Description

1 Insertion at It involves inserting any element at the front of the list. We just need to a few link adjust
beginning to make the new node as the head of the list.

2 Insertion at end of It involves insertion at the last of the linked list. The new node can be inserted as th
the list node in the list or it can be inserted as the last one. Different logics are implemented in
scenario.

3 Insertion after It involves insertion after the specified node of the linked list. We need to skip the d
specified node number of nodes in order to reach the node after which the new node will be inserted

Deletion and Traversing


The Deletion of a node from a singly linked list can be performed at different positions. Based
on the position of the node being deleted, the operation is categorized into the following
categories.

SN Operation Description

1 Deletion at It involves deletion of a node from the beginning of the list. This is the simplest ope
beginning among all. It just need a few adjustments in the node pointers.

2 Deletion at the end It involves deleting the last node of the list. The list can either be empty or full. Differen
of the list is implemented for the different scenarios.

3 Deletion after It involves deleting the node after the specified node in the list. we need to skip the d
specified node number of nodes to reach the node after which the node will be deleted. This re
traversing through the list.

4 Traversing In traversing, we simply visit each node of the list at least once in order to perform
specific operation on it, for example, printing data part of each node present in the list
5 Searching In searching, we match each element of the list with the given element. If the element is
on any of the location then location of that element is returned otherwise null is return

Linked List in C: Menu Driven Program


1. #include<stdio.h>
2. #include<stdlib.h>
3. struct node
4. {
5. int data;
6. struct node *next;
7. };
8. struct node *head;
9.
10. void beginsert ();
11. void lastinsert ();
12. void randominsert();
13. void begin_delete();
14. void last_delete();
15. void random_delete();
16. void display();
17. void search();
18. void main ()
19. {
20. int choice =0;
21. while(choice != 9)
22. {
23. printf("\n\n*********Main Menu*********\n");
24. printf("\nChoose one option from the following list ...\n");
25. printf("\n===============================================\n");
26. printf("\n1.Insert in begining\n2.Insert at last\n3.Insert at any random location\n4.Delete from
Beginning\n
27. 5.Delete from last\n6.Delete node after specified location\n7.Search for an element\n8.Show\
n9.Exit\n");
28. printf("\nEnter your choice?\n");
29. scanf("\n%d",&choice);
30. switch(choice)
31. {
32. case 1:
33. beginsert();
34. break;
35. case 2:
36. lastinsert();
37. break;
38. case 3:
39. randominsert();
40. break;
41. case 4:
42. begin_delete();
43. break;
44. case 5:
45. last_delete();
46. break;
47. case 6:
48. random_delete();
49. break;
50. case 7:
51. search();
52. break;
53. case 8:
54. display();
55. break;
56. case 9:
57. exit(0);
58. break;
59. default:
60. printf("Please enter valid choice..");
61. }
62. }
63. }
64. void beginsert()
65. {
66. struct node *ptr;
67. int item;
68. ptr = (struct node *) malloc(sizeof(struct node *));
69. if(ptr == NULL)
70. {
71. printf("\nOVERFLOW");
72. }
73. else
74. {
75. printf("\nEnter value\n");
76. scanf("%d",&item);
77. ptr->data = item;
78. ptr->next = head;
79. head = ptr;
80. printf("\nNode inserted");
81. }
82.
83. }
84. void lastinsert()
85. {
86. struct node *ptr,*temp;
87. int item;
88. ptr = (struct node*)malloc(sizeof(struct node));
89. if(ptr == NULL)
90. {
91. printf("\nOVERFLOW");
92. }
93. else
94. {
95. printf("\nEnter value?\n");
96. scanf("%d",&item);
97. ptr->data = item;
98. if(head == NULL)
99. {
100. ptr -> next = NULL;
101. head = ptr;
102. printf("\nNode inserted");
103. }
104. else
105. {
106. temp = head;
107. while (temp -> next != NULL)
108. {
109. temp = temp -> next;
110. }
111. temp->next = ptr;
112. ptr->next = NULL;
113. printf("\nNode inserted");
114.
115. }
116. }
117. }
118. void randominsert()
119. {
120. int i,loc,item;
121. struct node *ptr, *temp;
122. ptr = (struct node *) malloc (sizeof(struct node));
123. if(ptr == NULL)
124. {
125. printf("\nOVERFLOW");
126. }
127. else
128. {
129. printf("\nEnter element value");
130. scanf("%d",&item);
131. ptr->data = item;
132. printf("\nEnter the location after which you want to insert ");
133. scanf("\n%d",&loc);
134. temp=head;
135. for(i=0;i<loc;i++)
136. {
137. temp = temp->next;
138. if(temp == NULL)
139. {
140. printf("\ncan't insert\n");
141. return;
142. }
143.
144. }
145. ptr ->next = temp ->next;
146. temp ->next = ptr;
147. printf("\nNode inserted");
148. }
149. }
150. void begin_delete()
151. {
152. struct node *ptr;
153. if(head == NULL)
154. {
155. printf("\nList is empty\n");
156. }
157. else
158. {
159. ptr = head;
160. head = ptr->next;
161. free(ptr);
162. printf("\nNode deleted from the begining ...\n");
163. }
164. }
165. void last_delete()
166. {
167. struct node *ptr,*ptr1;
168. if(head == NULL)
169. {
170. printf("\nlist is empty");
171. }
172. else if(head -> next == NULL)
173. {
174. head = NULL;
175. free(head);
176. printf("\nOnly node of the list deleted ...\n");
177. }
178.
179. else
180. {
181. ptr = head;
182. while(ptr->next != NULL)
183. {
184. ptr1 = ptr;
185. ptr = ptr ->next;
186. }
187. ptr1->next = NULL;
188. free(ptr);
189. printf("\nDeleted Node from the last ...\n");
190. }
191. }
192. void random_delete()
193. {
194. struct node *ptr,*ptr1;
195. int loc,i;
196. printf("\n Enter the location of the node after which you want to perform deletion \n");
197. scanf("%d",&loc);
198. ptr=head;
199. for(i=0;i<loc;i++)
200. {
201. ptr1 = ptr;
202. ptr = ptr->next;
203.
204. if(ptr == NULL)
205. {
206. printf("\nCan't delete");
207. return;
208. }
209. }
210. ptr1 ->next = ptr ->next;
211. free(ptr);
212. printf("\nDeleted node %d ",loc+1);
213. }
214. void search()
215. {
216. struct node *ptr;
217. int item,i=0,flag;
218. ptr = head;
219. if(ptr == NULL)
220. {
221. printf("\nEmpty List\n");
222. }
223. else
224. {
225. printf("\nEnter item which you want to search?\n");
226. scanf("%d",&item);
227. while (ptr!=NULL)
228. {
229. if(ptr->data == item)
230. {
231. printf("item found at location %d ",i+1);
232. flag=0;
233. }
234. else
235. {
236. flag=1;
237. }
238. i++;
239. ptr = ptr -> next;
240. }
241. if(flag==1)
242. {
243. printf("Item not found\n");
244. }
245. }
246.
247. }
248.
249. void display()
250. {
251. struct node *ptr;
252. ptr = head;
253. if(ptr == NULL)
254. {
255. printf("Nothing to print");
256. }
257. else
258. {
259. printf("\nprinting values . . . . .\n");
260. while (ptr!=NULL)
261. {
262. printf("\n%d",ptr->data);
263. ptr = ptr -> next;
264. }
265. }
266. }
267.
Output:
*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


1

Enter value
1

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


2

Enter value?
2

Node inserted

*********Main Menu*********

Choose one option from the following list ...


===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


3

Enter element value1

Enter the location after which you want to insert 1

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


8

printing values . . . . .

1
2
1

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


2

Enter value?
123

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


1

Enter value
1234

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


4

Node deleted from the begining ...


*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


5

Deleted Node from the last ...

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


6

Enter the location of the node after which you want to perform deletion
1

Deleted node 2

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


8

printing values . . . . .

1
1

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


7

Enter item which you want to search?


1
item found at location 1
item found at location 2

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete node after specified location
7.Search for an element
8.Show
9.Exit

Enter your choice?


9
Doubly linked list
Doubly linked list is a complex type of linked list in which a node contains a pointer to the
previous as well as the next node in the sequence. Therefore, in a doubly linked list, a node
consists of three parts: node data, pointer to the next node in sequence (next pointer) ,
pointer to the previous node (previous pointer). A sample node in a doubly linked list is
shown in the figure.

A doubly linked list containing three nodes having numbers from 1 to 3 in their data part, is
shown in the following image.

In C, structure of a node in doubly linked list can be given as :


1. struct node
2. {
3. struct node *prev;
4. int data;
5. struct node *next;
6. }
The prev part of the first node and the next part of the last node will always contain null
indicating end in each direction.
In a singly linked list, we could traverse only in one direction, because each node contains
address of the next node and it doesn't have any record of its previous nodes. However,
doubly linked list overcome this limitation of singly linked list. Due to the fact that, each node
of the list contains the address of its previous node, we can find all the details about the
previous node as well by using the previous address stored inside the previous part of each
node.

Memory Representation of a doubly linked list


Memory Representation of a doubly linked list is shown in the following image. Generally,
doubly linked list consumes more space for every node and therefore, causes more
expansive basic operations such as insertion and deletion. However, we can easily
manipulate the elements of the list since the list maintains pointers in both the directions
(forward and backward).
In the following image, the first element of the list that is i.e. 13 stored at address 1. The head
pointer points to the starting address 1. Since this is the first element being added to the list
therefore the prev of the list contains null. The next node of the list resides at address 4
therefore the first node contains 4 in its next pointer.
We can traverse the list in this way until we find any node containing null or -1 in its next
part.
Operations on doubly linked list
Node Creation
1. struct node
2. {
3. struct node *prev;
4. int data;
5. struct node *next;
6. };
7. struct node *head;
All the remaining operations regarding doubly linked list are described in the following table.

SN Operation Description
1 Insertion at beginning Adding the node into the linked list at beginning.

2 Insertion at end Adding the node into the linked list to the end.

3 Insertion after specified Adding the node into the linked list after the specified node.
node

4 Deletion at beginning Removing the node from beginning of the list

5 Deletion at the end Removing the node from end of the list.

6 Deletion of the node having Removing the node which is present just after the node containing the given d
given data

7 Searching Comparing each node data with the item to be searched and return the loca
the item in the list if the item found else return null.

8 Traversing Visiting each node of the list at least once in order to perform some specific ope
like searching, sorting, display, etc.

Menu Driven Program in C to implement all the


operations of doubly linked list
1. #include<stdio.h>
2. #include<stdlib.h>
3. struct node
4. {
5. struct node *prev;
6. struct node *next;
7. int data;
8. };
9. struct node *head;
10. void insertion_beginning();
11. void insertion_last();
12. void insertion_specified();
13. void deletion_beginning();
14. void deletion_last();
15. void deletion_specified();
16. void display();
17. void search();
18. void main ()
19. {
20. int choice =0;
21. while(choice != 9)
22. {
23. printf("\n*********Main Menu*********\n");
24. printf("\nChoose one option from the following list ...\n");
25. printf("\n===============================================\n");
26. printf("\n1.Insert in begining\n2.Insert at last\n3.Insert at any random location\n4.Delete from
Beginning\n
27. 5.Delete from last\n6.Delete the node after the given data\n7.Search\n8.Show\n9.Exit\n");
28. printf("\nEnter your choice?\n");
29. scanf("\n%d",&choice);
30. switch(choice)
31. {
32. case 1:
33. insertion_beginning();
34. break;
35. case 2:
36. insertion_last();
37. break;
38. case 3:
39. insertion_specified();
40. break;
41. case 4:
42. deletion_beginning();
43. break;
44. case 5:
45. deletion_last();
46. break;
47. case 6:
48. deletion_specified();
49. break;
50. case 7:
51. search();
52. break;
53. case 8:
54. display();
55. break;
56. case 9:
57. exit(0);
58. break;
59. default:
60. printf("Please enter valid choice..");
61. }
62. }
63. }
64. void insertion_beginning()
65. {
66. struct node *ptr;
67. int item;
68. ptr = (struct node *)malloc(sizeof(struct node));
69. if(ptr == NULL)
70. {
71. printf("\nOVERFLOW");
72. }
73. else
74. {
75. printf("\nEnter Item value");
76. scanf("%d",&item);
77.
78. if(head==NULL)
79. {
80. ptr->next = NULL;
81. ptr->prev=NULL;
82. ptr->data=item;
83. head=ptr;
84. }
85. else
86. {
87. ptr->data=item;
88. ptr->prev=NULL;
89. ptr->next = head;
90. head->prev=ptr;
91. head=ptr;
92. }
93. printf("\nNode inserted\n");
94. }
95.
96. }
97. void insertion_last()
98. {
99. struct node *ptr,*temp;
100. int item;
101. ptr = (struct node *) malloc(sizeof(struct node));
102. if(ptr == NULL)
103. {
104. printf("\nOVERFLOW");
105. }
106. else
107. {
108. printf("\nEnter value");
109. scanf("%d",&item);
110. ptr->data=item;
111. if(head == NULL)
112. {
113. ptr->next = NULL;
114. ptr->prev = NULL;
115. head = ptr;
116. }
117. else
118. {
119. temp = head;
120. while(temp->next!=NULL)
121. {
122. temp = temp->next;
123. }
124. temp->next = ptr;
125. ptr ->prev=temp;
126. ptr->next = NULL;
127. }
128.
129. }
130. printf("\nnode inserted\n");
131. }
132. void insertion_specified()
133.{
134. struct node *ptr,*temp;
135. int item,loc,i;
136. ptr = (struct node *)malloc(sizeof(struct node));
137. if(ptr == NULL)
138. {
139. printf("\n OVERFLOW");
140. }
141. else
142. {
143. temp=head;
144. printf("Enter the location");
145. scanf("%d",&loc);
146. for(i=0;i<loc;i++)
147. {
148. temp = temp->next;
149. if(temp == NULL)
150. {
151. printf("\n There are less than %d elements", loc);
152. return;
153. }
154. }
155. printf("Enter value");
156. scanf("%d",&item);
157. ptr->data = item;
158. ptr->next = temp->next;
159. ptr -> prev = temp;
160. temp->next = ptr;
161. temp->next->prev=ptr;
162. printf("\nnode inserted\n");
163. }
164. }
165. void deletion_beginning()
166. {
167. struct node *ptr;
168. if(head == NULL)
169. {
170. printf("\n UNDERFLOW");
171. }
172. else if(head->next == NULL)
173. {
174. head = NULL;
175. free(head);
176. printf("\nnode deleted\n");
177. }
178. else
179. {
180. ptr = head;
181. head = head -> next;
182. head -> prev = NULL;
183. free(ptr);
184. printf("\nnode deleted\n");
185. }
186.
187. }
188. void deletion_last()
189. {
190. struct node *ptr;
191. if(head == NULL)
192. {
193. printf("\n UNDERFLOW");
194. }
195. else if(head->next == NULL)
196. {
197. head = NULL;
198. free(head);
199. printf("\nnode deleted\n");
200. }
201. else
202. {
203. ptr = head;
204. if(ptr->next != NULL)
205. {
206. ptr = ptr -> next;
207. }
208. ptr -> prev -> next = NULL;
209. free(ptr);
210. printf("\nnode deleted\n");
211. }
212. }
213. void deletion_specified()
214. {
215. struct node *ptr, *temp;
216. int val;
217. printf("\n Enter the data after which the node is to be deleted : ");
218. scanf("%d", &val);
219. ptr = head;
220. while(ptr -> data != val)
221. ptr = ptr -> next;
222. if(ptr -> next == NULL)
223. {
224. printf("\nCan't delete\n");
225. }
226. else if(ptr -> next -> next == NULL)
227. {
228. ptr ->next = NULL;
229. }
230. else
231. {
232. temp = ptr -> next;
233. ptr -> next = temp -> next;
234. temp -> next -> prev = ptr;
235. free(temp);
236. printf("\nnode deleted\n");
237. }
238. }
239. void display()
240. {
241. struct node *ptr;
242. printf("\n printing values...\n");
243. ptr = head;
244. while(ptr != NULL)
245. {
246. printf("%d\n",ptr->data);
247. ptr=ptr->next;
248. }
249. }
250. void search()
251. {
252. struct node *ptr;
253. int item,i=0,flag;
254. ptr = head;
255. if(ptr == NULL)
256. {
257. printf("\nEmpty List\n");
258. }
259. else
260. {
261. printf("\nEnter item which you want to search?\n");
262. scanf("%d",&item);
263. while (ptr!=NULL)
264. {
265. if(ptr->data == item)
266. {
267. printf("\nitem found at location %d ",i+1);
268. flag=0;
269. break;
270. }
271. else
272. {
273. flag=1;
274. }
275. i++;
276. ptr = ptr -> next;
277. }
278. if(flag==1)
279. {
280. printf("\nItem not found\n");
281. }
282. }
283.
284. }
Output
*********Main Menu*********

Choose one option from the following list ...

===============================================
1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


8

printing values...

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


1

Enter Item value12

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


1
Enter Item value123

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


1

Enter Item value1234

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


8

printing values...
1234
123
12

*********Main Menu*********

Choose one option from the following list ...

===============================================
1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


2

Enter value89

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


3
Enter the location1
Enter value12345

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


8

printing values...
1234
123
12345
12
89

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


4

node deleted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


5

node deleted

*********Main Menu*********

Choose one option from the following list ...

===============================================
1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


8

printing values...
123
12345

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


6

Enter the data after which the node is to be deleted : 123

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


8
printing values...
123

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


7

Enter item which you want to search?


123

item found at location 1


*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


6

Enter the data after which the node is to be deleted : 123

Can't delete

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Insert at any random location
4.Delete from Beginning
5.Delete from last
6.Delete the node after the given data
7.Search
8.Show
9.Exit

Enter your choice?


9

Exited..

Circular Singly Linked List


In a circular Singly linked list, the last node of the list contains a pointer to the first node of
the list. We can have circular singly linked list as well as circular doubly linked list.
We traverse a circular singly linked list until we reach the same node where we started. The
circular singly liked list has no beginning and no ending. There is no null value present in the
next part of any of the nodes.
The following image shows a circular singly linked list.

Circular linked list are mostly used in task maintenance in operating systems. There are
many examples where circular linked list are being used in computer science including
browser surfing where a record of pages visited in the past by the user, is maintained in the
form of circular linked lists and can be accessed again on clicking the previous button.
Memory Representation of circular linked list:
In the following image, memory representation of a circular linked list containing marks of a
student in 4 subjects. However, the image shows a glimpse of how the circular list is being
stored in the memory. The start or head of the list is pointing to the element with the index
1 and containing 13 marks in the data part and 4 in the next part. Which means that it is linked
with the node that is being stored at 4th index of the list.
However, due to the fact that we are considering circular linked list in the memory therefore
the last node of the list contains the address of the first node of the list.

We can also have more than one number of linked list in the memory with the different start
pointers pointing to the different start nodes in the list. The last node is identified by its next
part which contains the address of the start node of the list. We must be able to identify the
last node of any linked list so that we can find out the number of iterations which need to
be performed while traversing the list.
Operations on Circular Singly linked list:
Insertion

SN Operation Description

1 Insertion at beginning Adding a node into circular singly linked list at the beginning.

2 Insertion at the end Adding a node into circular singly linked list at the end.

Deletion & Traversing

SN Operation Description

1 Deletion at Removing the node from circular singly linked list at the beginning.
beginning

2 Deletion at the end Removing the node from circular singly linked list at the end.

3 Searching Compare each element of the node with the given item and return the location at whi
item is present in the list otherwise return null.

4 Traversing Visiting each element of the list at least once in order to perform some specific operatio

Menu-driven program in C implementing all operations


on circular singly linked list
1. #include<stdio.h>
2. #include<stdlib.h>
3. struct node
4. {
5. int data;
6. struct node *next;
7. };
8. struct node *head;
9.
10. void beginsert ();
11. void lastinsert ();
12. void randominsert();
13. void begin_delete();
14. void last_delete();
15. void random_delete();
16. void display();
17. void search();
18. void main ()
19. {
20. int choice =0;
21. while(choice != 7)
22. {
23. printf("\n*********Main Menu*********\n");
24. printf("\nChoose one option from the following list ...\n");
25. printf("\n===============================================\n");
26. printf("\n1.Insert in begining\n2.Insert at last\n3.Delete from Beginning\n4.Delete from last\n5.
Search for an element\n6.Show\n7.Exit\n");
27. printf("\nEnter your choice?\n");
28. scanf("\n%d",&choice);
29. switch(choice)
30. {
31. case 1:
32. beginsert();
33. break;
34. case 2:
35. lastinsert();
36. break;
37. case 3:
38. begin_delete();
39. break;
40. case 4:
41. last_delete();
42. break;
43. case 5:
44. search();
45. break;
46. case 6:
47. display();
48. break;
49. case 7:
50. exit(0);
51. break;
52. default:
53. printf("Please enter valid choice..");
54. }
55. }
56. }
57. void beginsert()
58. {
59. struct node *ptr,*temp;
60. int item;
61. ptr = (struct node *)malloc(sizeof(struct node));
62. if(ptr == NULL)
63. {
64. printf("\nOVERFLOW");
65. }
66. else
67. {
68. printf("\nEnter the node data?");
69. scanf("%d",&item);
70. ptr -> data = item;
71. if(head == NULL)
72. {
73. head = ptr;
74. ptr -> next = head;
75. }
76. else
77. {
78. temp = head;
79. while(temp->next != head)
80. temp = temp->next;
81. ptr->next = head;
82. temp -> next = ptr;
83. head = ptr;
84. }
85. printf("\nnode inserted\n");
86. }
87.
88. }
89. void lastinsert()
90. {
91. struct node *ptr,*temp;
92. int item;
93. ptr = (struct node *)malloc(sizeof(struct node));
94. if(ptr == NULL)
95. {
96. printf("\nOVERFLOW\n");
97. }
98. else
99. {
100. printf("\nEnter Data?");
101. scanf("%d",&item);
102. ptr->data = item;
103. if(head == NULL)
104. {
105. head = ptr;
106. ptr -> next = head;
107. }
108. else
109. {
110. temp = head;
111. while(temp -> next != head)
112. {
113. temp = temp -> next;
114. }
115. temp -> next = ptr;
116. ptr -> next = head;
117. }
118.
119. printf("\nnode inserted\n");
120. }
121.
122. }
123.
124. void begin_delete()
125. {
126. struct node *ptr;
127. if(head == NULL)
128. {
129. printf("\nUNDERFLOW");
130. }
131. else if(head->next == head)
132. {
133. head = NULL;
134. free(head);
135. printf("\nnode deleted\n");
136. }
137.
138. else
139. { ptr = head;
140. while(ptr -> next != head)
141. ptr = ptr -> next;
142. ptr->next = head->next;
143. free(head);
144. head = ptr->next;
145. printf("\nnode deleted\n");
146.
147. }
148.}
149. void last_delete()
150. {
151. struct node *ptr, *preptr;
152. if(head==NULL)
153. {
154. printf("\nUNDERFLOW");
155. }
156. else if (head ->next == head)
157. {
158. head = NULL;
159. free(head);
160. printf("\nnode deleted\n");
161.
162. }
163. else
164. {
165. ptr = head;
166. while(ptr ->next != head)
167. {
168. preptr=ptr;
169. ptr = ptr->next;
170. }
171. preptr->next = ptr -> next;
172. free(ptr);
173. printf("\nnode deleted\n");
174.
175. }
176. }
177.
178. void search()
179. {
180. struct node *ptr;
181. int item,i=0,flag=1;
182. ptr = head;
183. if(ptr == NULL)
184. {
185. printf("\nEmpty List\n");
186. }
187. else
188. {
189. printf("\nEnter item which you want to search?\n");
190. scanf("%d",&item);
191. if(head ->data == item)
192. {
193. printf("item found at location %d",i+1);
194. flag=0;
195. }
196. else
197. {
198. while (ptr->next != head)
199. {
200. if(ptr->data == item)
201. {
202. printf("item found at location %d ",i+1);
203. flag=0;
204. break;
205. }
206. else
207. {
208. flag=1;
209. }
210. i++;
211. ptr = ptr -> next;
212. }
213. }
214. if(flag != 0)
215. {
216. printf("Item not found\n");
217. }
218. }
219.
220. }
221.
222. void display()
223. {
224. struct node *ptr;
225. ptr=head;
226. if(head == NULL)
227. {
228. printf("\nnothing to print");
229. }
230. else
231. {
232. printf("\n printing values ... \n");
233.
234. while(ptr -> next != head)
235. {
236.
237. printf("%d\n", ptr -> data);
238. ptr = ptr -> next;
239. }
240. printf("%d\n", ptr -> data);
241. }
242.
243. }
Output:
*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


1

Enter the node data?10

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


2

Enter Data?20

node inserted

*********Main Menu*********

Choose one option from the following list ...


===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


2

Enter Data?30

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


3

node deleted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


4

node deleted

*********Main Menu*********
Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


5

Enter item which you want to search?


20
item found at location 1
*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


6

printing values ...


20

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in begining
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search for an element
6.Show
7.Exit

Enter your choice?


7
Circular Doubly Linked List
Circular doubly linked list is a more complexed type of data structure in which a node
contain pointers to its previous node as well as the next node. Circular doubly linked list
doesn't contain NULL in any of the node. The last node of the list contains the address of the
first node of the list. The first node of the list also contain address of the last node in its
previous pointer.
A circular doubly linked list is shown in the following figure.

Due to the fact that a circular doubly linked list contains three parts in its structure therefore,
it demands more space per node and more expensive basic operations. However, a circular
doubly linked list provides easy manipulation of the pointers and the searching becomes
twice as efficient.

Memory Management of Circular Doubly linked list


The following figure shows the way in which the memory is allocated for a circular doubly
linked list. The variable head contains the address of the first element of the list i.e. 1 hence
the starting node of the list contains data A is stored at address 1. Since, each node of the
list is supposed to have three parts therefore, the starting node of the list contains address
of the last node i.e. 8 and the next node i.e. 4. The last node of the list that is stored at address
8 and containing data as 6, contains address of the first node of the list as shown in the
image i.e. 1. In circular doubly linked list, the last node is identified by the address of the first
node which is stored in the next part of the last node therefore the node which contains the
address of the first node, is actually the last node of the list.
Operations on circular doubly linked list :
There are various operations which can be performed on circular doubly linked list. The
node structure of a circular doubly linked list is similar to doubly linked list. However, the
operations on circular doubly linked list is described in the following table.

SN Operation Description

1 Insertion at beginning Adding a node in circular doubly linked list at the beginning.

2 Insertion at end Adding a node in circular doubly linked list at the end.
3 Deletion at beginning Removing a node in circular doubly linked list from beginning.

4 Deletion at end Removing a node in circular doubly linked list at the end.

Traversing and searching in circular doubly linked list is similar to that in the circular singly
linked list.

C program to implement all the operations on circular


doubly linked list
1. #include<stdio.h>
2. #include<stdlib.h>
3. struct node
4. {
5. struct node *prev;
6. struct node *next;
7. int data;
8. };
9. struct node *head;
10. void insertion_beginning();
11. void insertion_last();
12. void deletion_beginning();
13. void deletion_last();
14. void display();
15. void search();
16. void main ()
17. {
18. int choice =0;
19. while(choice != 9)
20. {
21. printf("\n*********Main Menu*********\n");
22. printf("\nChoose one option from the following list ...\n");
23. printf("\n===============================================\n");
24. printf("\n1.Insert in Beginning\n2.Insert at last\n3.Delete from Beginning\n4.Delete from last\n
5.Search\n6.Show\n7.Exit\n");
25. printf("\nEnter your choice?\n");
26. scanf("\n%d",&choice);
27. switch(choice)
28. {
29. case 1:
30. insertion_beginning();
31. break;
32. case 2:
33. insertion_last();
34. break;
35. case 3:
36. deletion_beginning();
37. break;
38. case 4:
39. deletion_last();
40. break;
41. case 5:
42. search();
43. break;
44. case 6:
45. display();
46. break;
47. case 7:
48. exit(0);
49. break;
50. default:
51. printf("Please enter valid choice..");
52. }
53. }
54. }
55. void insertion_beginning()
56. {
57. struct node *ptr,*temp;
58. int item;
59. ptr = (struct node *)malloc(sizeof(struct node));
60. if(ptr == NULL)
61. {
62. printf("\nOVERFLOW");
63. }
64. else
65. {
66. printf("\nEnter Item value");
67. scanf("%d",&item);
68. ptr->data=item;
69. if(head==NULL)
70. {
71. head = ptr;
72. ptr -> next = head;
73. ptr -> prev = head;
74. }
75. else
76. {
77. temp = head;
78. while(temp -> next != head)
79. {
80. temp = temp -> next;
81. }
82. temp -> next = ptr;
83. ptr -> prev = temp;
84. head -> prev = ptr;
85. ptr -> next = head;
86. head = ptr;
87. }
88. printf("\nNode inserted\n");
89. }
90.
91. }
92. void insertion_last()
93. {
94. struct node *ptr,*temp;
95. int item;
96. ptr = (struct node *) malloc(sizeof(struct node));
97. if(ptr == NULL)
98. {
99. printf("\nOVERFLOW");
100. }
101. else
102. {
103. printf("\nEnter value");
104. scanf("%d",&item);
105. ptr->data=item;
106. if(head == NULL)
107. {
108. head = ptr;
109. ptr -> next = head;
110. ptr -> prev = head;
111. }
112. else
113. {
114. temp = head;
115. while(temp->next !=head)
116. {
117. temp = temp->next;
118. }
119. temp->next = ptr;
120. ptr ->prev=temp;
121. head -> prev = ptr;
122. ptr -> next = head;
123. }
124. }
125. printf("\nnode inserted\n");
126. }
127.
128.void deletion_beginning()
129. {
130. struct node *temp;
131. if(head == NULL)
132. {
133. printf("\n UNDERFLOW");
134. }
135. else if(head->next == head)
136. {
137. head = NULL;
138. free(head);
139. printf("\nnode deleted\n");
140. }
141. else
142. {
143. temp = head;
144. while(temp -> next != head)
145. {
146. temp = temp -> next;
147. }
148. temp -> next = head -> next;
149. head -> next -> prev = temp;
150. free(head);
151. head = temp -> next;
152. }
153.
154. }
155.void deletion_last()
156. {
157. struct node *ptr;
158. if(head == NULL)
159. {
160. printf("\n UNDERFLOW");
161. }
162. else if(head->next == head)
163. {
164. head = NULL;
165. free(head);
166. printf("\nnode deleted\n");
167. }
168. else
169. {
170. ptr = head;
171. if(ptr->next != head)
172. {
173. ptr = ptr -> next;
174. }
175. ptr -> prev -> next = head;
176. head -> prev = ptr -> prev;
177. free(ptr);
178. printf("\nnode deleted\n");
179. }
180. }
181.
182.void display()
183. {
184. struct node *ptr;
185. ptr=head;
186. if(head == NULL)
187. {
188. printf("\nnothing to print");
189. }
190. else
191. {
192. printf("\n printing values ... \n");
193.
194. while(ptr -> next != head)
195. {
196.
197. printf("%d\n", ptr -> data);
198. ptr = ptr -> next;
199. }
200. printf("%d\n", ptr -> data);
201. }
202.
203. }
204.
205. void search()
206. {
207. struct node *ptr;
208. int item,i=0,flag=1;
209. ptr = head;
210. if(ptr == NULL)
211. {
212. printf("\nEmpty List\n");
213. }
214. else
215. {
216. printf("\nEnter item which you want to search?\n");
217. scanf("%d",&item);
218. if(head ->data == item)
219. {
220. printf("item found at location %d",i+1);
221. flag=0;
222. }
223. else
224. {
225. while (ptr->next != head)
226. {
227. if(ptr->data == item)
228. {
229. printf("item found at location %d ",i+1);
230. flag=0;
231. break;
232. }
233. else
234. {
235. flag=1;
236. }
237. i++;
238. ptr = ptr -> next;
239. }
240. }
241. if(flag != 0)
242. {
243. printf("Item not found\n");
244. }
245. }
246.
247. }
Output:
*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


1

Enter Item value123


Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


2

Enter value234

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


1

Enter Item value90

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


2

Enter value80

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


3

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


4

node deleted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


6

printing values ...


123

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


5

Enter item which you want to search?


123
item found at location 1
*********Main Menu*********

Choose one option from the following list ...

============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?


7

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy