Module 3 DSA 24
Module 3 DSA 24
FACULTY OF ENGINEERING
Course outcomes
Topic CO
Introduction to an Array, Representation of Arrays 1
Introduction to Stack, Stack-Definitions & Concepts 2
Operations On Stacks, Applications of Stacks 3
Polish Expression, Reverse Polish Expression And Their 3
Compilation
Recursion, Tower of Hanoi 3
Linked List 3
Applications of Linked List 4
SPECIFIC LEARNING OBJECTIVES
S/No Learning objectives Level
• Order Preservation: The order in which elements are added to the data structure is
preserved. This means that the first element added will be the first one to be
accessed.
• Fixed or Dynamic Size: Linear data structures can have either fixed or dynamic sizes.
Arrays typically have a fixed size when they are created, while other structures like
linked lists, stacks, and queues can dynamically grow or shrink as elements are added
or removed.
An array is a linear data structure that collects elements of the same data type and
stores them in contiguous and adjacent memory locations. Arrays work on an index
system starting from 0 to (n-1), where n is the size of the array.
Why Do You Need an Array in Data Structures?
Let's suppose a class consists of ten students, and the class has to
publish their results. If you had declared all ten variables individually, it
would be challenging to manipulate and maintain the data.
1D ARRAY
2D ARRAY
3D ARRAY
How Do You Declare an Array?
Arrays are typically defined with square brackets with the size of the arrays
as its argument.
Here is the syntax for arrays:
1D Arrays: int arr[n];
2D Arrays: int arr[m][n];
3D Arrays: int arr[m][n][o];
How Do You Initialize an Array?
•Method 1:
int a[6] = {2, 3, 5, 7, 11, 13};
• Method 2:
int arr[]= {2, 3, 5, 7, 11};
•Method 3:
int arr[5];
arr[0]=1;
arr[1]=2;
arr[2]=3;
arr[3]=4;
arr[4]=5;
How Can You Access Elements of Arrays in Data Structures?
You can access elements with the help of the index at which you stored them.
printf(“%d\n”,a[2]);
Basic Operations Performed with an Array
Operations in Array are like features of it, what an Array can do with the
elements inside it is the operation of arrays. Arrays have 5 basic operations:
Deleting elements has the same scenario too. If the element has to be deleted from the beginning
or anywhere from the middle of the array, remaining elements will have to shift their index so it will
take n steps even if the index of element to be deleted is known, that means average or worst time
complexity, however if the element deleted is the last element of the array, best time complexity.
Searching for an Element
The method of searching for a specific value in an array is known
as searching.
2D arrays are actually there from the user point of view but the storage process
of 2D array is the same as one-dimensional arrays we have been using this
far. 2D arrays are created to give a tabular representation (in form of rows and
columns).
The size of a 2D array is equal to the multiplication of the number of rows and columns
of the array.
There are two major techniques of storing 2D arrays in memory,
giving us two formulas to map a 2D array into 1D or finding the
address of a random element in a 2D array.
Row Major Order: All the rows of the array are stored in the memory continuously.
2D array Index 0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 2,3
2D array elements 1 2 3 4 5 6 7 8 9 10 11 12
Column Major Order: All the columns of the array are stored in the memory
continuously.
2D array Index
0,0 1,0 2,0 0,1 1,1 2,1 0,2 1,2 2,2 0,3 1,3 3,3
2D array elements
1 5 9 2 6 10 3 7 11 4 8 12
Sparse Matrix
What is a matrix?
A matrix can be defined as a two-dimensional array having 'm' rows and 'n'
columns. A matrix with m rows and n columns is called m × n matrix. It is a
set of numbers that are arranged in the horizontal or vertical lines of
entries.
What is a sparse matrix?
Sparse matrices are those matrices that have the majority of their
elements equal to zero. In other words, the sparse matrix can be defined
as the matrix that has a greater number of zero elements than the non-
zero elements.
Why is a sparse matrix required if we can use the simple
matrix to store elements?
•Array representation
•Linked list representation
Array representation of the sparse matrix
In a linked list representation, the linked list data structure is used to represent the sparse matrix. The
advantage of using a linked list to represent the sparse matrix is that the complexity of inserting or
deleting a node in a linked list is lesser than the array.
Unlike the array representation, a node in the linked list representation consists of four fields. The four
fields of the linked list are given as follows –
•Row - It represents the index of the row where the non-zero element is located.
•Column - It represents the index of the column where the non-zero element is located.
•Value - It is the value of the non-zero element that is located at the index (row, column).
•Next node - It stores the address of the next node.
In the above figure, we can observe a 4x4 sparse matrix containing 5 non-zero
elements and 11 zero elements. Above matrix occupies 4x4 = 16 memory space.
Increasing the size of matrix will increase the wastage space.
The linked list representation of the above matrix is given below -
Stack
By definition, a stack is an ordered list in which insertion and deletion are done at one end,
where the end is generally called the top. The last inserted element is available first and is the
first one to be deleted. Hence, it is known as Last In, First Out (LIFO) or First In, Last Out (FILO).
In a stack, the element at the top is known as the top element.
what is the difference between arrays and stacks?
Stacks differ from the arrays in a way that in arrays random access is possible; this means that we can
access any element just by using its index in the array. Whereas, in a stack only limited access is
possible and only the top element is directly available.
Consider an array, arr = [1, 2, 3, 4]. To access 2, we can simply write arr[1], where 1 is the index of the
array element, 2. But if the same is implemented using a stack, we can only access the topmost
element which is 4.
Features of Stack in Data Structure
⮚ Stacks are dynamic in nature; this means that they do not have a fixed size and
their size can be increased or decreased depending upon the number of elements.
⮚ In stacks, only one end is available to perform actions like insertion or deletion of
the elements
⮚ Stacks follow LIFO, which is Last In, First Out mechanism. Inserting an element is
known as push, and deleting an element is known as pop
Working of Stack in Data Structure
Initially, the stack is empty,
and we can add elements one
by one using the push
operation until the stack
becomes full. Let's say we
want to push the elements 1,
2, 3, 4, and 5 onto the stack.
We start by pushing 1 onto
the stack, which becomes the
top element. Then, we push 2,
3, 4, and 5 in the same way, as
shown
Stack Operations in Data Structure
1. push(x)
⮚ The process of inserting new data into a stack is known as push. The push (x)
operation takes the element to be added as a parameter
⮚ If we are implementing a stack using an array, it may have a pre-defined
capacity , which means that only a specific number of elements can be stored
in it.
⮚ In this case, if the stack is full, it results in a condition called stack overflow. It
indicates that we have utilized the entire capacity of the given stack, and there
is no space for any new element.
The steps involved in a push operation are –
1.Before inserting the element, check whether the stack is full.
2.If the stack is full, print “stack overflow” and terminate the program.
3.If the stack is not full, add data into the stack.
4.We can repeat the above steps until the maximum capacity of the stack is achieved.
Recall the above example of the elevator, the event of people walking into the elevator closely relates
to pushing the elements into a stack.
2. pop()
The process of deleting the topmost element from the stack is known as pop.
In stacks, if we try to pop or remove elements if the stack is empty, it results in a condition
known as underflow. It means that there is no element in the stack that can be removed.
The steps involved in a pop operation are –
1.Before removing the topmost element, check whether the stack is empty
2.If the stack is empty, print “Stack underflow” and terminate the program
3.If the stack is not empty, access the topmost element and let the top point to the element
just before it
4.We can repeat the above until all the elements from the stack are removed
3. topElement()/peek()
5. isFull()
This operation is used to check if the given stack is full. It returns a boolean
value; that is true when the stack is full, otherwise false.
6. size()
This operation determines the current size of the stack
Implementation of Stack in Data Structure
•Infix Notation
•Prefix (Polish) Notation
•Postfix (Reverse-Polish) Notation
Infix Notation
• A Queue is an abstract linear data structure serving as a collection of elements that are
inserted (enqueue operation) and removed (dequeue operation) according to the First
in First Out (FIFO) approach.
• Insertion happens at the rear end of the queue whereas deletion happens at the front
end of the queue. The front of the queue is returned using the peek operation.
What is Queue?
Enqueue
The Enqueue operation is used to add an element to the front of the queue.
•Steps of the algorithm:
•Check if the Queue is full.
•Set the front as 0 for the first element.
•Increase rear by 1.
•Add the new element at the rear index.
Dequeue
The Dequeue operation is used to remove an element from the rear of the queue.
•Steps of the algorithm:
•Check if the Queue is empty.
•Return the value at the front index.
•Increase front by 1.
•Set front and rear as -1 for the last element.
Peek
The Peek operation is used to return the front most element of the queue.
•Steps of the algorithm:
•Check if the Queue is empty.
•Return the value at the front index.
isFull
The isFull operation is used to check if the queue is full or not.
•Steps of the algorithm:
•Check if the number of elements in the queue (size) is equal to
the capacity, if yes, return True.
•Return False.
isEmpty
The isEmpty operation is used to check if the queue is empty or not.
•Steps of the algorithm:
•Check if the number of elements in the queue (size) is equal to 0, if yes,
return True.
•Return False.
Types of Queues
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.
Circular Queue
• 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.
• 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.
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.
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.
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.
Linked List
A Linked List is a linear data structure consisting of connected nodes where
each node has corresponding data and a pointer to the address of the next
node. The first node of a linked list is called the Head, and it acts as an
access point.
Representation of linked list
Why use linked list over array?
• 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 can not traverse the list in the reverse
direction.
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.
Circular 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.
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.
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.
Memory Management of Circular Doubly linked list
Operations of Linked List
Travers
al
We can traverse the entire linked list starting from the head node. If there are n nodes then
the time complexity for traversal becomes O(n) as we hop through each and every node.
Insertion
• We are given the reference to a node, and the new node is inserted after the given node.
Deletion
To delete a node from a linked list, we need to do these steps
•Find the previous node of the node to be deleted.
•Change the next pointer of the previous node
•Free the memory of the deleted node.
• Given a particular key (data), we need to search for a node whose data
matches the key.
• In the best-case scenario, the head would be the node we are looking for,
whereas in the worst-case the required node would be the tail.
• In terms of time complexity the best case, the average case, and the worst
case of searching are denoted as Ω(1), Θ(n), and O(n) respectively.
Advantages of Linked List
• Dynamic in nature - Linked lists are dynamic in nature, and their size can be
adjusted according to our requirements.
• Ease of Insertion and Deletion - Insertion and deletion of a node in a linked list
remain efficient as the nodes are stored in random locations, and we only need to
update the next pointer of a constant number of nodes.
• Memory efficient - Memory consumption of a linked list is efficient as its size can
grow or shrink dynamically according to our requirements.
• Implementation - Various advanced data structures can be implemented using a
linked list vis-a-vis stack, queue, graph, hash maps, etc.
Disadvantages of Linked List
• Memory usage - A node in a linked list occupies more memory than an element in
an array as each node occupies at least two kinds of variables.
• Accessing a node - If you want to access a node in a linked list, you have to traverse
starting from the head. We cannot access any random nodes directly except for the
head itself, since nodes don't share a linear order in the physical memory and are
only referenced by pointers.
• Traversing in reverse order - Traversing in reverse order is difficult. Although a
doubly-linked list makes it easier but requires more memory to store those extra
'prev' pointers.
Applications of Linked List
BAQ
1.Define linear data structure.
2.Enlist types of data structure.
SAQ
3.Illustrate the types of arrays.
4.Illustrate the concept of sparse matrix.
LAQ
5.Explain Polish Expression.
6.Explain various operations on stack.
7.Explain types of linked list
References
1. Data structure using C and C++-AM Tanenbaum, Y Langsam& MJ Augustein,Prentice Hall India.
2. Data structures & Program Design in C -Robert Kruse, Bruse Leung,Pearson Education.