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

Data Structures Unit 1

Data structure notes Unit 1

Uploaded by

ganaroy2001
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

Data Structures Unit 1

Data structure notes Unit 1

Uploaded by

ganaroy2001
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 70

1

Aurora’s Technological and Research Institute


Department of Computer Science and Engineering

Data Structures
R18 CSE/IT II year

By
D. Subhashini
Associate Professor
CSE dept
Aurora’s Technological and Research Institute Department of
Computer Science and Engineering

D. Subhashini, Assoc. prof


2
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

UNIT I
Introduction to Data Structures, abstract data
types, Linear list – singly linked list implementation,
insertion, deletion and searching operations on linear
list, Stacks-Operations, array and linked
representations of stacks, stack applications,
Queues-operations, array and linked representations.

D. Subhashini, Assoc. prof


3
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Data Structures
Data Structure is a way to store and organize data so that it can be used efficiently.

What is Data Structure?


The data structure name indicates itself that organizing the data in memory. There are
many ways of organizing the data in the memory. One of the data structures is array in C
language. Array is a collection of memory elements in which data is stored sequentially, i.e.,
one after another. This organization of data is done with the help of an array of data
structures. There are also other ways to organize the data in memory. Let's see the
different types of data structures.

The data structure is not any programming language like C, C++, java, etc. It is a set of
algorithms that we can use in any programming language to structure the data in the
memory.

To structure the data in memory, 'n' number of algorithms were proposed, and all these
algorithms are known as Abstract data types. These abstract data types are the set of rules.

D. Subhashini, Assoc. prof


4
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Types of Data Structures


There are two types of data structures:

o Primitive data structure


o Non-primitive data structure

Primitive Data structure

The primitive data structures are primitive data types. The int, char, float, double, and
pointer are the primitive data structures that can hold a single value.

Non-Primitive Data structure

The non-primitive data structure is divided into two types:

o Linear data structure


o Non-linear data structure

Linear Data Structure

The arrangement of data in a sequential manner is known as a linear data structure. The
data structures used for this purpose are Arrays, Linked list, Stacks, and Queues. In
these data structures, one element is connected to only one another element in a linear
form.

Non-linear data structure

When one element is connected to the 'n' number of elements known as a non-linear
data structure. The best example is trees and graphs. In this case, the elements are
arranged in a random manner.

Data structures can also be classified as:

o Static data structure: It is a type of data structure where the size is allocated at
the compile time. Therefore, the maximum size is fixed.
o Dynamic data structure: It is a type of data structure where the size is allocated at
the run time. Therefore, the maximum size is flexible.

Major Operations
The major or the common operations that can be performed on the data structures are:

o Searching: We can search for any element in a data structure.

D. Subhashini, Assoc. prof


5
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

o Sorting: We can sort the elements of a data structure either in an ascending or


descending order.
o Insertion: We can also insert the new element in a data structure.
o Updation: We can also update the element, i.e., we can replace the element with
another element.
o Deletion: We can also perform the delete operation to remove the element from the
data structure.

Which Data Structure?


A data structure is a way of organizing the data so that it can be used efficiently. Here, we
have used the word efficiently, which in terms of both the space and time. For example, a
stack is an ADT (Abstract data type) which uses either arrays or linked list data structure for
the implementation. Therefore, we say that we require some data structure to implement a
particular ADT.

An ADT tells what is to be done and data structure tells how it is to be done. In other
words, we can say that ADT gives us the blueprint while data structure provides the
implementation part.

As the different data structures can be implemented in a particular ADT, but the different
implementations are compared for time and space. For example, the Stack ADT can be
implemented by both Arrays and linked list. Suppose the array is providing time efficiency
while the linked list is providing space efficiency, so the one which is the best suited for the
current user's requirements will be selected.

Advantages of Data structures


The following are the advantages of a data structure:

o Efficiency: If the choice of a data structure for implementing a particular ADT is


proper, it makes the program very efficient in terms of time and space.
o Reusability: he data structures provide reusability means that multiple client
programs can use the data structure.
o Abstraction: The data structure specified by an ADT also provides the level of
abstraction. The client cannot see the internal working of the data structure, so it
does not have to worry about the implementation part. The client can only see the
interface.

D. Subhashini, Assoc. prof


6
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Data Structure Classification

Linear Data Structures: A data structure is called linear if all of its elements are arranged
in the linear order. In linear data structures, each element has the successors and
predecessors except the first and last element.

Types of Linear Data Structures are given below:

Arrays: An array is a collection of similar type of data items and each data item is called an
element of the array. The data type of the element may be any valid data type like char,
int, float or double.

The elements of array share the same variable name but each one carries a different index
number known as subscript. The array can be one dimensional, two dimensional or
multidimensional.

The individual elements of the array age are:

age[0], age[1], age[2], age[3],......... age[98], age[99].

Linked List: Linked list is a linear data structure which is used to maintain a list in the
memory. It can be seen as the collection of nodes stored at non-contiguous memory
locations. Each node of the list contains a pointer to its adjacent node.

Stack: Stack is a linear list in which insertion and deletions are allowed only at one end,
called top.

D. Subhashini, Assoc. prof


7
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

A stack is an abstract data type (ADT), can be implemented in most of the programming
languages. It is named as stack because it behaves like a real-world stack, for example: -
piles of plates or deck of cards etc.

Queue: Queue is a linear list in which elements can be inserted only at one end
called rear and deleted only at the other end called front.

It is an abstract data structure, similar to stack. Queue is opened at both end therefore it
follows First-In-First-Out (FIFO) methodology for storing the data items.

Non Linear Data Structures: This data structure does not form a sequence i.e. each item
or element is connected with two or more other items in a non-linear arrangement. Types of
Non Linear Data Structures are given below:

Trees: Trees are multilevel data structures with a hierarchical relationship among its
elements known as nodes. The bottommost nodes in the herierchy are called leaf
node while the topmost node is called root node. Each node contains pointers to point
adjacent nodes.

Tree data structure is based on the parent-child relationship among the nodes. Each node in
the tree can have more than one children except the leaf nodes whereas each node can
have at most one parent except the root node.

Graphs: Graphs can be defined as the pictorial representation of the set of elements
(represented by vertices) connected by the links known as edges. A graph is different from
tree in the sense that a graph can have cycle while the tree cannot have the one.

Operations on data structure


1) Traversing: Every data structure contains the set of data elements. Traversing the data
structure means visiting each element of the data structure in order to perform some
specific operation like searching or sorting.

Example: If we need to calculate the average of the marks obtained by a student in 6


different subject, we need to traverse the complete array of marks and calculate the total
sum, then we will divide that sum by the number of subjects i.e. 6, in order to find the
average.

2) Insertion: Insertion can be defined as the process of adding the elements to the data
structure at any location.

3) Deletion: The process of removing an element from the data structure is called Deletion.
We can delete an element from the data structure at any random location.

If we try to delete an element from an empty data structure then underflow occurs.

4) Searching: The process of finding the location of an element within the data structure is
called Searching. There are two algorithms to perform searching, Linear Search and Binary
Search.

D. Subhashini, Assoc. prof


8
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

5) Sorting: The process of arranging the data structure in a specific order is known as
Sorting. There are many algorithms that can be used to perform sorting, for example,
insertion sort, selection sort, bubble sort, etc.

6) Merging: When two lists List A and List B of size M and N respectively, of similar type of
elements, clubbed or joined to produce the third list, List C of size (M+N), then this process
is called merging

D. Subhashini, Assoc. prof


9
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Pointer
Pointer is used to points the address of the value stored anywhere in the computer memory.
To obtain the value stored at the location is known as dereferencing the pointer. Pointer
improves the performance for repetitive process such as:

o Traversing String
o Lookup Tables
o Control Tables
o Tree Structures

Pointer Details
o Pointer arithmetic: There are four arithmetic operators that can be used in
pointers: ++, --, +, -
o Array of pointers: You can define arrays to hold a number of pointers.
o Pointer to pointer: C allows you to have pointer on a pointer and so on.
o Passing pointers to functions in C: Passing an argument by reference or by
address enable the passed argument to be changed in the calling function by the
called function.
o Return pointer from functions in C: C allows a function to return a pointer to the
local variable, static variable and dynamically allocated memory as well.

D. Subhashini, Assoc. prof


10
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Program
Pointer
#include <stdio.h>

int main( )
{
int a = 5;
int *b;
b = &a;

printf ("value of a = %d\n", a);


printf ("value of a = %d\n", *(&a));
printf ("value of a = %d\n", *b);
printf ("address of a = %u\n", &a);
printf ("address of a = %d\n", b);
printf ("address of b = %u\n", &b);
printf ("value of b = address of a = %u", b);
return 0;
}
Output
value of a = 5
value of a = 5
address of a = 3010494292

address of a = -
1284473004
address of b = 3010494296

value of b = address of a = 3010494292

D. Subhashini, Assoc. prof


11
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Structure
A structure is a composite data type that defines a grouped list of variables that are to be
placed under one name in a block of memory. It allows different variables to be accessed by
using a single pointer to the structure.

Syntax

struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeber;
};

Advantages
o It can hold variables of different data types.
o We can create objects containing different types of attributes.
o It allows us to re-use the data layout across programs.
o It is used to implement other data structures like linked lists, stacks, queues, trees,
graphs etc.

Program

#include<stdio.h>
#include<conio.h>
void main( )
{
struct employee
{
int id ;
float salary ;
int mobile ;
};
struct employee e1,e2,e3 ;
clrscr();
printf ("\nEnter ids, salary & mobile no. of 3 employee\n"
scanf ("%d %f %d", &e1.id, &e1.salary, &e1.mobile);

D. Subhashini, Assoc. prof


12
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

scanf ("%d%f %d", &e2.id, &e2.salary, &e2.mobile);


scanf ("%d %f %d", &e3.id, &e3.salary, &e3.mobile);
printf ("\n Entered Result ");
printf ("\n%d %f %d", e1.id, e1.salary, e1.mobile);
printf ("\n%d%f %d", e2.id, e2.salary, e2.mobile);
printf ("\n%d %f %d", e3.id, e3.salary, e3.mobile);
getch();
}

D. Subhashini, Assoc. prof


13
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Linked List
If we want to store the value in a memory, we need a memory manager that manages the
memory for every variable. For example, if we want to create a variable of integer type like:

int x;

In the above example, we have created a variable 'x' of type integer. As we know that
integer variable occupies 4 bytes, so 'x' variable will occupy 4 bytes to store the value.

Suppose we want to create an array of integer type like:

int x[3];

In the above example, we have declared an array of size 3. As we know, that all the values
of an array are stored in a continuous manner, so all the three values of an array are stored
in a sequential fashion. The total memory space occupied by the array would be 3*4 = 12
bytes.

There are two major drawbacks of using array:

o We cannot insert more than 3 elements in the above example because only 3 spaces
are allocated for 3 elements.
o In the case of an array, lots of wastage of memory can occur. For example, if we
declare an array of 50 size but we insert only 10 elements in an array. So, in this
case, the memory space for other 40 elements will get wasted and cannot be used
by another variable as this whole space is occupied by an array.

In array, we are providing the fixed-size at the compile-time, due to which wastage of
memory occurs. The solution to this problem is to use the linked list.

What is Linked List?


A linked list is also a collection of elements, but the elements are not stored in a consecutive
location.

Suppose a programmer made a request for storing the integer value then size of 4-byte
memory block is assigned to the integer value. The programmer made another request for
storing 3 more integer elements; then, three different memory blocks are assigned to these
three elements but the memory blocks are available in a random location. So, how are the
elements connected?.

These elements are linked to each other by providing one additional information along with
an element, i.e., the address of the next element. The variable that stores the address of
the next element is known as a pointer. Therefore, we can say that the linked list contains
two parts, i.e., the first one is the data element, and the other is the pointer. The pointer
variable will occupy 4 bytes which is pointing to the next element.

D. Subhashini, Assoc. prof


14
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

A linked list can also be defined as the collection of the nodes in which one node is
connected to another node, and node consists of two parts, i.e., one is the data
part and the second one is the address part, as shown in the below figure:

In the above figure, we can observe that each node contains the data and the address of
the next node. The last node of the linked list contains the NULL value in the address part.

Advantages of using a Linked list over Array


The following are the advantages of using a linked list over an array:

o Dynamic data structure:


The size of the linked list is not fixed as it can vary according to our requirements.
o Insertion and Deletion:
Insertion and deletion in linked list are easier than array as the elements in an array
are stored in a consecutive location. In contrast, in the case of a linked list, the
elements are stored in a random location. The complexity for insertion and deletion
of elements from the beginning is O(1) in the linked list, while in the case of an
array, the complexity would be O(n). If we want to insert or delete the element in an
array, then we need to shift the elements for creating the space. On the other hand,
in the linked list, we do not have to shift the elements. In the linked list, we just
need to update the address of the pointer in the node.
o Memory efficient
Its memory consumption is efficient as the size of the linked list can grow or shrink
according to our requirements.
o Implementation
Both the stacks and queues can be implemented using a linked list.

D. Subhashini, Assoc. prof


15
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Disadvantages of Linked list


The following are the disadvantages of linked list:

o Memory usage
The node in a linked list occupies more memory than array as each node occupies
two types of variables, i.e., one is a simple variable, and another is a pointer variable
that occupies 4 bytes in the memory.
o Traversal
In a linked list, the traversal is not easy. If we want to access the element in a linked
list, we cannot access the element randomly, but in the case of an array, we can
randomly access the element 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
In a linked list, backtracking or reverse traversing is difficult. 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 below:

o With the help of a linked list, the polynomials can be represented as well as we can
perform the operations on the polynomial. We know that polynomial is a collection of
terms in which each term contains coefficient and power. The coefficients and power
of each term are stored as node and link pointer points to the next element in a
linked list, so linked list can be used to create, delete and display the polynomial.

o A sparse matrix is used in scientific computation and numerical analysis. So, a linked
list is 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.

D. Subhashini, Assoc. prof


16
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

o Stack, Queue, tree and various other data structures can be implemented using a
linked list.
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 To implement hashing, we require hash tables. The hash table contains entries that
are implemented using 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.

D. Subhashini, Assoc. prof


17
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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


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

struct node
{
int data;
struct node *next;
}

D. Subhashini, Assoc. prof


18
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

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

struct node
{
int data;
struct node *next;
struct node *prev;
}

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.

D. Subhashini, Assoc. prof


19
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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:

struct node
{
int data;
struct node *next;
}

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:

Doubly Circular linked list


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

D. Subhashini, Assoc. prof


20
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

struct node
{
int data;
struct node *next;
struct node *prev;
}

D. Subhashini, Assoc. prof


21
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

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

Operations on Singly Linked List


There are various operations which can be performed on singly linked list.

 Creating a linked list


 Traversing a linked list
 Inserting an item into a linked list.
 Deleting an item from the linked list.
 Searching an item in the linked list
 Merging two or more linked lists.

Node Creation
struct node
{
int data;
struct node *next;
};

D. Subhashini, Assoc. prof


22
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

struct node *head, *ptr;


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 It involves inserting any element at the front of the list. We just
at need to a few link adjustments to make the new node as the
beginning head of the list.

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

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

Insertion in singly linked list at beginning


Inserting a new element into a singly linked list at beginning is quite simple. We just need
to make a few adjustments in the node links. The following steps need to be followed in
order to insert a new node in the list at beginning.

o Allocate the space for the new node and store data into the data part of the node.
This will be done by the following statements.

ptr = (struct node *) malloc(sizeof(struct node *));


ptr → data = item

D. Subhashini, Assoc. prof


23
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

o Make the link part of the new node pointing to the existing first node of the list. This
will be done by using the following statement.

ptr->next = head;

o At the last, we need to make the new node as the first node of the list this will be
done by using the following statement.

head = ptr;

C Function
#include<stdio.h>
#include<stdlib.h>
void insert_first(int);
struct node
{
int data;
struct node *next;
};
struct node *head;
void main ()
{
int choice,item;
do
{

D. Subhashini, Assoc. prof


24
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

printf("\nEnter the item which you want to insert?\n");


scanf("%d",&item);
insert_first(item);
printf("\nPress 0 to insert more ?\n");
scanf("%d",&choice);
}while(choice == 0);
}
void insert_first(int item)
{
struct node *ptr = (struct node *)malloc(sizeof(struct node *));
if(ptr == NULL)
{
printf("\nOVERFLOW\n");
}
else
{
ptr->data = item;
ptr->next = head;
head = ptr;
printf("\nNode inserted\n");
}

Insertion in singly linked list at the end


In order to insert a node at the last, there are two following scenarios which need to be
mentioned.

1. The node is being added to an empty list


2. The node is being added to the end of the linked list

In the first case,


o The condition (head == NULL) gets satisfied. Hence, we just need to allocate the
space for the node by using malloc statement in C. Data and the link part of the
node are set up by using the following statements.

ptr->data = item;
ptr -> next = NULL;

D. Subhashini, Assoc. prof


25
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

o Since, ptr is the only node that will be inserted in the list hence, we need to make
this node pointed by the head pointer of the list. This will be done by using the
following Statements.

head = ptr

In the second case,


o The condition Head = NULL would fail, since Head is not null. Now, we need to
declare a temporary pointer temp in order to traverse through the list. temp is made
to point the first node of the list.

temp = head

o Then, traverse through the entire linked list using the statements:

while (temp→ next != NULL)


temp = temp → next;

o At the end of the loop, the temp will be pointing to the last node of the list. Now,
allocate the space for the new node, and assign the item to its data part. Since, the
new node is going to be the last node of the list hence, the next part of this node
needs to be pointing to the null. We need to make the next part of the temp node
(which is currently the last node of the list) point to the new node (ptr) .

temp = head;
while (temp -> next != NULL)
{
temp = temp -> next;
}
temp->next = ptr;
ptr->next = NULL;

D. Subhashini, Assoc. prof


26
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

C Function
#include<stdio.h>
#include<stdlib.h>
void insert_last(int);
struct node
{
int data;
struct node *next;
};
struct node *head;
void main ()
{
int choice,item;
do
{
printf("\nEnter the item which you want to insert?\n");
scanf("%d",&item);
insert_last(item);
printf("\nPress 0 to insert more ?\n");
scanf("%d",&choice);
}while(choice == 0);
}
Void insert_last(int item)
{
struct node *ptr = (struct node*)malloc(sizeof(struct node));
struct node *temp;

D. Subhashini, Assoc. prof


27
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

if(ptr == NULL)
{
printf("\nOVERFLOW");
}
else
{
ptr->data = item;
if(head == NULL)
{
ptr -> next = NULL;
head = ptr;
printf("\nNode inserted");
}
else
{
temp = head;
while (temp -> next != NULL)
{
temp = temp -> next;
}
temp->next = ptr;
ptr->next = NULL;
printf("\nNode inserted");

}
}
}

Insertion in singly linked list after specified


Node
o In order to insert an element after the specified number of nodes into the linked list,
we need to skip the desired number of elements in the list to move the pointer at the
position after which the node will be inserted. This will be done by using the following
statements.

temp=head;
for(i=0;i<loc;i++)
{
temp = temp->next;

D. Subhashini, Assoc. prof


28
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

if(temp == NULL)
{
return;
}

}
o Allocate the space for the new node and add the item to the data part of it. This will
be done by using the following statements.

ptr = (struct node *) malloc (sizeof(struct node));


ptr->data = item;
o Now, we just need to make a few more link adjustments and our node will be
inserted at the specified position. Since, at the end of the loop, the loop pointer temp
would be pointing to the node after which the new node will be inserted. Therefore,
the next part of the new node ptr must contain the address of the next part of the
temp (since, ptr will be in between temp and the next of the temp). This will be done
by using the following statements.

ptr→ next = temp → next

o now, we just need to make the next part of the temp, point to the new node ptr. This
will insert the new node ptr, at the specified position.

temp ->next = ptr;

D. Subhashini, Assoc. prof


29
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

C Function
#include<stdio.h>
#include<stdlib.h>
void insertatpos(int);
void create(int);
struct node
{
int data;
struct node *next;
};
struct node *head;
void main ()
{
int choice,item,loc;
do
{
printf("\nEnter the item which you want to insert?\n");
scanf("%d",&item);
if(head == NULL)
{
create(item);
}
else
{
insertatpos(item);
}
printf("\nPress 0 to insert more ?\n");
scanf("%d",&choice);
}while(choice == 0);
}
void create(int item)
{

struct node *ptr = (struct node *)malloc(sizeof(struct node *));


if(ptr == NULL)
{
printf("\nOVERFLOW\n");
}
else

D. Subhashini, Assoc. prof


30
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

{
ptr->data = item;
ptr->next = head;
head = ptr;
printf("\nNode inserted\n");
}
}
void insertatpos(int item)
{
struct node *ptr = (struct node *) malloc (sizeof(struct node));
struct node *temp;
int i,loc;
if(ptr == NULL)
{
printf("\nOVERFLOW");
}
else
{

printf("Enter the location");


scanf("%d",&loc);
ptr->data = item;
temp=head;
for(i=0;i<loc;i++)
{
temp = temp->next;
if(temp == NULL)
{
printf("\ncan't insert\n");
return;
}

}
ptr ->next = temp ->next;
temp ->next = ptr;
printf("\nNode inserted");
}

D. Subhashini, Assoc. prof


31
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

INSERT in Singly Linked List


#include<stdio.h>
#include<stdlib.h>
void insertatpos (int);
struct node
{
int data;
struct node *next;
};
struct node *head;
void insertatpos(int item)
{
struct node *ptr = (struct node *) malloc (sizeof(struct node));
struct node *temp;
int i,loc;
if(ptr == NULL)
{
printf("\nOVERFLOW");
}
else
{
printf("\nEnter the item which you want to insert?\n");
scanf("%d",&item);
printf("Enter the location");
scanf("%d",&loc);
ptr->data = item;
if (loc == 0)
{
ptr->next = head;
head = ptr;
printf("\n Node Inserted");
}
else
{
temp=head;
for(i=1;i<loc;i++)
{
temp = temp->next;
if(temp == NULL)
{

D. Subhashini, Assoc. prof


32
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

printf("\ncan't insert\n");
return;
}
}
ptr ->next = temp ->next;
temp ->next = ptr;
printf("\nNode inserted");
}
}
}

Deletion
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 It involves deletion of a node from the beginning of the list. This
at is the simplest operation among all. It just need a few
beginning adjustments in the node pointers.

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

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

Deletion in singly linked list at beginning


Deleting a node from the beginning of the list is the simplest operation of all. It just need a
few adjustments in the node pointers. Since the first node of the list is to be deleted,

D. Subhashini, Assoc. prof


33
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

therefore, we just need to make the head, point to the next of the head. This will be done
by using the following statements.

ptr = head;
head = ptr->next;

Now, free the pointer ptr which was pointing to the head node of the list. This will be done
by using the following statement.

free(ptr)

Deletion in singly linked list at the end


There are two scenarios in which, a node is deleted from the end of the linked list.

1. There is only one node in the list and that needs to be deleted.
2. There are more than one node in the list and the last node of the list will be deleted.

In the first scenario,


the condition head → next = NULL will survive and therefore, the only node head of the list
will be assigned to null. This will be done by using the following statements.

ptr = head
head = NULL
free(ptr)

D. Subhashini, Assoc. prof


34
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

In the second scenario,


The condition head → next = NULL would fail and therefore, we have to traverse the node in
order to reach the last node of the list.

For this purpose, just declare a temporary pointer temp and assign it to head of the list. We
also need to keep track of the second last node of the list. For this purpose, two pointers ptr
and ptr1 will be used where ptr will point to the last node and ptr1 will point to the second
last node of the list.

this all will be done by using the following statements.

ptr = head;
while(ptr->next != NULL)
{
ptr1 = ptr;
ptr = ptr ->next;
}

Now, we just need to make the pointer ptr1 point to the NULL and the last node of the list
that is pointed by ptr will become free. It will be done by using the following statements.

ptr1->next = NULL;
free(ptr);

D. Subhashini, Assoc. prof


35
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Deletion in singly linked list after the


specified node :
In order to delete the node, which is present after the specified node, we need to skip the
desired number of nodes to reach the node after which the node will be deleted. We need to
keep track of the two nodes. The one which is to be deleted the other one is the node which
is present before that node. For this purpose, two pointers are used: ptr and ptr1.

Use the following statements to do so.

ptr=head;
for(i=0;i<loc;i++)
{
ptr1 = ptr;
ptr = ptr->next;
if(ptr == NULL)
{
printf("\nThere are less than %d elements in the list..",loc);
return;
}
}

Now, our task is almost done, we just need to make a few pointer adjustments. Make the
next of ptr1 (points to the specified node) point to the next of ptr (the node which is to be
deleted).This will be done by using the following statements.

ptr1 ->next = ptr ->next;


free(ptr);

D. Subhashini, Assoc. prof


36
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Searching in singly linked list


Searching is performed in order to find the location of a particular element in the list.
Searching any element in the list needs traversing through the list and make the
comparison of every element of the list with the specified element. If the element is
matched with any of the list element then the location of the element is returned from the
function.

C function
void search()
{
int pos=0,element;
printf("\nEnter Elent to be searched:");
scanf("%d",&element);
struct node *temp;
temp = head;
while ((temp != NULL) && (temp->data != element))
{
pos++;
temp = temp->next;
}
if (temp == NULL)
printf("\nUnsuccessful Search");
else
printf ("\nElement found at %d node",pos+1);
}

D. Subhashini, Assoc. prof


37
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Singly Linked List Program (Create, Insert, Delete, Display,


Search)

#include<stdio.h>
#include<stdlib.h>
void insertatpos();
void create();
void display();
void deletenode();
void search();
struct node
{
int data;
struct node *next;
};
struct node *head;
void main ()
{
int choice;
head = NULL;
do
{
printf("\nMENU\n");
printf("1. Create\n2. Insert\n3. Delete\n4.Display\n5. Search\n6. Exit");
printf("\nenter your choice");
scanf("%d",&choice);
switch (choice)
{
case 1:
if(head == NULL)
{
create();
}
else
printf ("List already created");
break;
case 2:
insertatpos();
break;
case 3: deletenode();
break;
case 4: printf("\nContents of List are \n");
display();
break;
case 5: search();
break;
case 6: exit(0);
}

D. Subhashini, Assoc. prof


38
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

}while(1);
}
void create()
{
int item;
struct node *ptr = (struct node *)malloc(sizeof(struct node *));
if(ptr == NULL)
{
printf("\nOVERFLOW\n");
}
else
{
printf("\nEnter the element\n");
scanf("%d",&item);
ptr->data = item;
ptr->next = head;
head = ptr;
printf("\nList Created\n");
}
}
void insertatpos()
{
int item;
struct node *ptr = (struct node *) malloc (sizeof(struct node));
struct node *temp;
int i,loc;
if(ptr == NULL)
{
printf("\nOVERFLOW");
}
else
{
printf("\nEnter the element to insert\n");
scanf("%d",&item);
printf("Enter the location after which you want to insert");
scanf("%d",&loc);
ptr->data = item;
if (loc == 0)
{
ptr->next = head;
head = ptr;
printf("\n Inserted");
}
else
{
temp=head;
for(i=1;i<loc;i++)
{
temp = temp->next;

D. Subhashini, Assoc. prof


39
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

if(temp == NULL)
{
printf("\ncan't insert\n");
return;
}

ptr ->next = temp ->next;


temp ->next = ptr;
printf("\n Inserted");
}

}
}
void deletenode()
{
int loc,i;
struct node *ptr,*ptr1;
printf("Enter the location of the node you want to delete");
scanf("%d",&loc);
ptr = head;
if (loc == 1)
{
head = head->next;
free(ptr);
}
else
{
for(i=1;i<loc;i++)
{
ptr1 = ptr;
ptr = ptr->next;
if(ptr == NULL)
{
printf("\nthe node to be deleted is not existing");
return;
}
}
ptr1->next = ptr->next;
free(ptr);
}
printf("\n Deleted");
}

void display()
{
struct node *temp;

D. Subhashini, Assoc. prof


40
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

temp = head;
while (temp != NULL)
{
printf (" -> %d",temp->data);
temp = temp->next;
}
}
void search()
{
int pos=0,element;
printf("\nEnter Elent to be searched:");
scanf("%d",&element);
struct node *temp;
temp = head;
while ((temp != NULL) && (temp->data != element))
{
pos++;
temp = temp->next;
}
if (temp == NULL)
printf("\nUnsuccessful Search");
else
printf ("\nElement found at %d node",pos+1);
}

D. Subhashini, Assoc. prof


41
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Stacks
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). Stack 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 top of 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.

Some key points related to 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.

D. Subhashini, Assoc. prof


42
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Since our stack is full as the size of the stack is 5. In the above cases, we can observe that
it grows from the top when we were entering the new element in the stack.

When we perform the delete operation on the stack, it follows the LIFO pattern, which
means that the value entered last will be removed first. In the above case, the value 5 is
entered last, so it will be removed first.

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 count(): It returns the total number of elements available in a stack.
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.

D. Subhashini, Assoc. prof


43
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

D. Subhashini, Assoc. prof


44
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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

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

int main()
{
cout<<"Hello";
cout<<"Students";
}

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 problem occurs in a program.

o String reversal: Stack is also used for reversing a string. 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.

D. Subhashini, Assoc. prof


45
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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

D. Subhashini, Assoc. prof


46
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

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:

begin
if top = n then stack full
top = top + 1
stack (top) : = item;
end

Time Complexity : o(1)

implementation of push algorithm in C language


void push (int val, int n) //n is size of the stack
{
if (top == n )
printf("\n Overflow");
else
{
top = top +1;
stack[top] = val;
}
}

D. Subhashini, Assoc. prof


47
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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

begin
if top = 0 then stack empty;
item := stack(top);
top = top - 1;
end;

Time Complexity : o(1)

Implementation of POP algorithm using C language


int pop ()
{
if(top == -1)
{
printf("Underflow");
return 0;
}
else
{
return stack[top - - ];
}
}

D. Subhashini, Assoc. prof


48
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

C program to implement stack using Array

#include <stdio.h>
int stack[100],n, top=-1;
void push();
void pop();
void display();

void main ()
{
int choice;
printf("Enter the number of elements in the stack ");
scanf("%d",&n);
printf("*********Stack operations using array*********");
printf("\n----------------------------------------------\n");
do
{
printf("Chose one from the below options...\n");
printf("\n1.Push\n2.Pop\n3.Show\n4.Exit");
printf("\n Enter your choice \n");
scanf("%d",&choice);
switch(choice)
{
case 1: push();
break;
case 2: pop();
break;
case 3:display();
break;
case 4:printf("Exiting....");
exit(0);
break;
default: printf("Please Enter valid choice ");
}
} while(1);
}

D. Subhashini, Assoc. prof


49
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

void push ()
{
int val;
if (top == n )
printf("\n Overflow");
else
{
printf("Enter the value?");
scanf("%d",&val);
top = top +1;
stack[top] = val;
}
}

void pop ()
{
if(top == -1)
printf("Underflow");
else
top = top -1;
}

void show()
{
for (i=top;i>=0;i--)
{
printf("%d\n",stack[i]);
}
if(top == -1)
{
printf("Stack is empty");
}
}

D. Subhashini, Assoc. prof


50
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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

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.

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.

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)

D. Subhashini, Assoc. prof


51
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

C implementation :
void push ()
{
int val;
struct node *ptr =(struct node*)malloc(sizeof(struct node));
if(ptr == NULL)
{
printf("not able to push the element");
}
else
{
printf("Enter the value");
scanf("%d",&val);
if(head==NULL)
{
ptr->val = val;
ptr -> next = NULL;

D. Subhashini, Assoc. prof


52
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

head=ptr;
}
else
{
ptr->val = val;
ptr->next = head;
head=ptr;

}
printf("Item pushed");
}
}

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 :

1. 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.
2. 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(1)

C implementation
void pop()
{
int item;
struct node *ptr;
if (head == NULL)
printf("Underflow");
else
{

D. Subhashini, Assoc. prof


53
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

item = head->val;
ptr = head;
head = head->next;
free(ptr);
printf("Item popped");
}
}

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.

1. Copy the head pointer into a temporary pointer.


2. 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
void display()
{
int i;
struct node *ptr;
ptr=head;
if(ptr == NULL)
printf("Stack is empty\n");
else
{
printf("Printing Stack elements \n");
while(ptr!=NULL)
{
printf("%d\n",ptr->val);
ptr = ptr->next;
}
}
}

D. Subhashini, Assoc. prof


54
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Menu Driven program in C implementing stack operations using linked list :

#include <stdio.h>
#include <stdlib.h>
void push();
void pop();
void display();
struct node
{
int val;
struct node *next;
};
struct node *head;
void main ()
{
int choice=0;
printf("\n*********Stack operations using linked list*********\n");
printf("\n----------------------------------------------\n");
do
{
printf("\n\nChose one from the below options...\n");
printf("\n1.Push\n2.Pop\n3.Show\n4.Exit");
printf("\n Enter your choice \n");
scanf("%d",&choice);
switch(choice)
{
case 1: push();
break;
case 2: pop();
break;
case 3: display();
break;
case 4: printf("Exiting....");
break;
default: printf("Please Enter valid choice ");
exit(0);
}
}while(1);
}

D. Subhashini, Assoc. prof


55
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

void push ()
{
int val;
struct node *ptr = (struct node*)malloc(sizeof(struct node));
if(ptr == NULL)
printf("not able to push the element");
else
{
printf("Enter the value");
scanf("%d",&val);
if(head==NULL)
{
ptr->val = val;
ptr -> next = NULL;
head=ptr;
}
else
{
ptr->val = val;
ptr->next = head;
head=ptr;
}
printf("Item pushed");
}
}

void pop()
{
int item;
struct node *ptr;
if (head == NULL)
printf("Underflow");
else
{
item = head->val;
ptr = head;
head = head->next;
free(ptr);
printf("Item popped");
}
}

D. Subhashini, Assoc. prof


56
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

void display()
{
int i;
struct node *ptr;
ptr=head;
if(ptr == NULL)
printf("Stack is empty\n");
else
{
printf("Printing Stack elements \n");
while(ptr!=NULL)
{
printf("%d\n",ptr->val);
ptr = ptr->next;
}
}
}

D. Subhashini, Assoc. prof


57
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Queue
 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.
 Queue is referred to be as First In First Out list.
 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.

D. Subhashini, Assoc. prof


58
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Complexity

Data Time Complexity


Struct
ure

Average Worst

Access Search Insertion Deletion Access Search Insertion Deletion

Queue θ(n) θ(n) θ(1) θ(1) O(n) O(n) O(1) O(1)

Implementations of Queue
There are two ways of implementing the Queue:

 Sequential allocation: The sequential allocation in a Queue can be implemented


using an array.
 Linked list allocation: The linked list allocation in a Queue can be implemented
using a linked list.

Types of Queue
There are four types of Queues:

 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 linear Queue can be represented, as shown in the below figure:

The above figure shows that the elements are inserted from the rear end, and if we insert
more elements in a Queue, then the rear value gets incremented on every insertion. If we
want to show the deletion, then it can be represented as:

D. Subhashini, Assoc. prof


59
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

In the above figure, we can observe that the front pointer points to the next element, and
the element which was previously pointed by the front pointer was deleted.

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.

 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 the ends are connected to another end. The circular queue can be
represented as:

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.

 Priority Queue

A priority queue is another special type of Queue data structure in which each element has
some priority associated with it. Based on the priority of the element, the elements are
arranged in a priority queue. If the elements occur with the same priority, then they are
served according to the FIFO principle.

In priority Queue, the insertion takes place based on the arrival while the deletion occurs
based on the priority.

 Deque

In Deque, the insertion and deletion can occur from both ends.

D. Subhashini, Assoc. prof


60
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

Array representation of Queue


We can easily represent queue by using linear arrays. There are two variables i.e. front and
rear. Front and rear variables point to the position from where insertions and deletions are
performed in a queue. Initially, the value of front and rare 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.

D. Subhashini, Assoc. prof


61
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

C Function
void insert (int queue[], int max, int front, int rear, int item)
{
if (rear + 1 == max)
{
printf("overflow");
}
else
{
if(front == -1 && rear == -1)
{
front = 0;
rear = 0;
}

D. Subhashini, Assoc. prof


62
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

else
{
rear = rear + 1;
}
queue[rear]=item;
}
}

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.

C Function
int delete (int queue[], int max, int front, int rear)
{
int y;
if (front == -1 || front > rear)
printf("underflow");
else
{
y = queue[front];
if(front == rear)
front = rear = -1;
else
front = front + 1;
return y;
}
}

Menu driven program to implement queue using array


#include<stdio.h>
#include<stdlib.h>
#define maxsize 5

D. Subhashini, Assoc. prof


63
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

void insert();
void delete();
void display();
int front = -1, rear = -1;
int queue[maxsize];

void main ()
{
int choice;
while(choice != 4)
{
printf("\n ********Main Menu******\n");
printf("\n===================\n");
printf("\n1.insert\n2.Delete\n3.Display\n4.Exit\n");
printf("\nEnter your choice ?");
scanf("%d",&choice);
switch(choice)
{
case 1: insert();
break;
case 2: delete();
break;
case 3: display();
break;
case 4: exit(0);
Default: printf("\nEnter valid choice??\n");
}
}
}

void insert()
{
int item;
printf("\nEnter the element\n");
scanf("\n%d",&item);
if(rear == maxsize-1)
{
printf("\nOVERFLOW\n");
return;
}
if(front == -1 && rear == -1)

D. Subhashini, Assoc. prof


64
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

{
front = 0;
rear = 0;
}
else
{
rear = rear+1;
}
queue[rear] = item;
printf("\nValue inserted ");
}

void delete()
{
int item;
if (front == -1 || front > rear)
{
printf("\nUNDERFLOW\n");
return;
}
else
{
item = queue[front];
if(front == rear)
{
front = -1;
rear = -1 ;
}
else
{
front = front + 1;
}
printf("\nvalue deleted ");
}
}

void display()
{
int i;
if(rear == -1)
{

D. Subhashini, Assoc. prof


65
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

printf("\nEmpty queue\n");
}
else
{ printf("\nprinting values .....\n");
for(i=front;i<=rear;i++)
{
printf("\n%d\n",queue[i]);
}
}

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

D. Subhashini, Assoc. prof


66
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

Ptr = (struct node *) malloc (sizeof(struct node));

There can be the two scenario of inserting this new node ptr into the linked queue.

D. Subhashini, Assoc. prof


67
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

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.

ptr -> data = item;


if(front == NULL)
{
front = ptr;
rear = ptr;
front -> next = NULL;
rear -> next = NULL;
}

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.

rear -> next = ptr;


rear = ptr;
rear->next = NULL;

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.

ptr = front;
front = front -> next;
free(ptr);

Menu-Driven Program implementing all the operations


on Linked Queue
#include<stdio.h>
#include<stdlib.h>

D. Subhashini, Assoc. prof


68
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

struct node
{
int data;
struct node *next;
};
struct node *front;
struct node *rear;
void insert();
void delete();
void display();

void main ()
{
int choice;
while(choice != 4)
{
printf("\n********Main Menu********\n");
printf("\n===================\n");
printf("\n1.insert\n2.Delete\n3.Display\n4.Exit\n");
printf("\nEnter your choice ?");
scanf("%d",& choice);
switch(choice)
{
case 1: insert();
break;
case 2: delete();
break;
case 3: display();
break;
case 4: exit(0);
break;
default: printf("\nEnter valid choice??\n");
}
}
}

void insert()
{
struct node *ptr;
int item;
ptr = (struct node *) malloc (sizeof(struct node));

D. Subhashini, Assoc. prof


69
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

if(ptr == NULL)
{
printf("\nOVERFLOW\n");
return;
}
else
{
printf("\nEnter value?\n");
scanf("%d",&item);
ptr -> data = item;
if(front == NULL)
{
front = ptr;
rear = ptr;
front -> next = NULL;
rear -> next = NULL;
}
else
{
rear -> next = ptr;
rear = ptr;
rear->next = NULL;
}
}
}

void delete ()
{
struct node *ptr;
if(front == NULL)
{
printf("\nUNDERFLOW\n");
return;
}
else
{
ptr = front;
front = front -> next;
free(ptr);
}
}

D. Subhashini, Assoc. prof


70
Aurora’s Technological and Research Institute
Department of Computer Science and Engineering

void display()
{
struct node *ptr;
ptr = front;
if(front == NULL)
printf("\nEmpty queue\n");
else
{
printf("\nprinting values .....\n");
while(ptr != NULL)
{
printf("\n%d\n",ptr -> data);
ptr = ptr -> next;
}
}
}

D. Subhashini, Assoc. prof

You might also like