DSA Notes2
DSA Notes2
As can be seen, the length (size) of the array above is 9. But what if
there is a requirement to change this length (size)? For example,
• If there is a situation where only 5 elements are needed to be
entered in this array. In this case, the remaining 4 indices are just
wasting memory in this array. So there is a requirement to lessen the
length (size) of the array from 9 to 5.
• Take another situation. In this, there is an array of 9 elements with
Syntax of malloc()
C calloc()
The name "calloc" stands for contiguous allocation.
Syntax of calloc()
C free()
Dynamically allocated memory created with
either calloc() or malloc() doesn't get freed on their own. You must
explicitly use free() to release the space.
Syntax of free()
free(ptr);
This statement frees the space allocated in the memory pointed by ptr.
C realloc()
If the dynamically allocated memory is insufficient or more than
required, you can change the size of previously allocated memory using
the realloc() function.
Syntax of realloc()
• Infix Notation
• Prefix (Polish) Notation
• Postfix (Reverse-Polish) Notation
The following table briefly tries to show the difference in all three
notations −
Postfix
Sr.No. Infix Notation Prefix Notation
Notation
2 (a + b) ∗ c ∗+abc ab+c∗
3 a ∗ (b + c) ∗a+bc abc+∗
elements
• Insertion/Deletion: Efficient
• Access: Sequential
Array:
• Data Structure: Contiguous
• Insertion/Deletion: Inefficient
• Access: Random
• The list of songs in the music player are linked to the previous and
next songs.
• In a web browser, previous and next web page URLs can be linked
through the previous and next buttons (Doubly Linked List)
• In image viewer, the previous and next images can be linked with
the help of the previous and next buttons (Doubly Linked List)
• Circular Linked Lists can be used to implement things in round
manner where we go to every element one by one.
• Linked List are preferred over arrays for implementations of Queue
and Deque data structures because of fast deletions (or insertions)
from the front of the linked lists.
• Searching
• Length
• Insertion:
• Deletion:
Traversal involves visiting each node in the linked list and performing
some operation on the data. A simple traversal function would print or
process the data of each node.
Step-by-step approach:
• Initialize a pointer current to the head of the list.
• Use a while loop to iterate through the list until the current pointer
reaches NULL.
• Inside the loop, print the data of the current node and move the
Step-by-step approach:
• Create a new node with the given value.
• Set the next pointer of the new node to the current head.
Step-by-step approach:
• Create a new node with the given value.
We mainly find the node after which we need to insert the new node. If
we encounter a NULL before reaching that node, it means that the
given position is invalid.
Deletion in Singly Linked List
Steps-by-step approach:
• Check if the head is NULL.
Step-by-step approach:
• Check if the head is NULL.
• Check if the head’s next is NULL (only one node in the list).
• If the head needs to be deleted, update the head and delete the node.
Node Definition
Here is how a node in a Doubly Linked List is typically represented:
List
Let’s go through each of the operations mentioned above, one by one.
Traversal in Doubly Linked List
To Traverse the doubly list, we can use the following steps:
a. Forward Traversal:
• Initialize a pointer to the head of the linked list.
b. Backward Traversal:
• Initialize a pointer to the tail of the linked list.
To insert a new node at the beginning of the doubly list, we can use the
following steps:
• Create a new node, say new_node with the given data and set its
To insert a new node at the end of the doubly linked list, we can use
the following steps:
• Allocate memory for a new node and assign the provided value to
o Traverse the list starting from the head to reach the last node.
o Set the next pointer of the last node to point to the new node.
o Set the previous pointer of the new node to point to the last
node.
say curr.
• If the position is valid, create a new node with given data,
say new_node.
• Update the next pointer of new node to the next of current node and
• Update the head of linked list to the node next to the current
To delete a node at the end in doubly linked list, we can use the
following steps:
• Check if the doubly linked list is empty. If it is empty, then there is
nothing to delete.
• If the list is not empty, then move to the last node of the doubly
>prev->next = NULL.
• Free the memory allocated for the node that was deleted.
deleted.
o If curr is not the head of the linked list, update the next
visited pages.
• Music player applications to manage playlists and navigate through
songs efficiently.
• Implementing data structures like Deque (double-ended queue) for
• Insertion
o Insertion at the empty list
• Deletion
o Delete the first node
• Searching
Insertion in the circular linked list:
Insertion is a fundamental operation in linked lists that involves adding
a new node to the list. The only extra step is connecting the last node to
the first one. In the circular linked list mentioned below, we can insert
nodes in four ways:
1. Insertion in an empty List in the circular linked list
To insert a node in empty circular linked list, creates a new node with
the given data, sets its next pointer to point to itself, and updates the
last pointer to reference this new node.
linked lists.
• Traversing a circular linked list without a clear stopping condition
between players. After the last player’s turn, the list cycles back to
the first player.
• Circular linked lists are often used in buffering applications, such as
Working of Queue
Queue operations work as follows:
• two pointers FRONT and REAR
• FRONT track the first element of the queue
• REAR track the last element of the queue
• initially, set value of FRONT and REAR to -1
Enqueue Operation
• check if the queue is full
• for the first element, set the value of FRONT to 0
• increase the REAR index by 1
• add the new element in the position pointed to by REAR
Dequeue Operation
• check if the queue is empty
• return the value pointed by FRONT
• increase the FRONT index by 1
• for the last element, reset the values of FRONT and REAR to -1
Types of Queue
There are four different types of queue that are listed as follows -
• 2. 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.
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.
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
There are two types of deque that are discussed as follows -
The data structure is called a "tree" because it looks like a tree, only
upside down
• A parent node has links to its child nodes. Another word for a
parent node is internal node.
• Nodes without links to other child nodes are called leaves, or leaf
nodes.
• The tree height is the maximum number of edges from the root
node to a leaf node. The height of the tree above is 2.
Root
It is the topmost node of a tree.
Height of a Node
The height of a node is the number of edges from the node to the deepest
leaf (ie. the longest path from the node to a leaf node).
Depth of a Node
The depth of a node is the number of edges from the root to the node.
Height of a Tree
The height of a Tree is the height of the root node or the depth of the
deepest node.
Degree of a Node
The degree of a node is the total number of branches of that node.
Forest
A collection of disjoint trees is called a forest
Basic Terminologies In Tree Data Structure:
• Parent Node: The node which is a predecessor of a node is called
the parent node of that node. {B} is the parent node of {D, E}.
• Root Node: The topmost node of a tree or the node which does not
have any parent node is called the root node. {A} is the root node of
the tree. A non-empty tree must contain exactly one root node and
exactly one path from the root to all other nodes of the tree.
• Leaf Node or External Node: The nodes which do not have any
child nodes are called leaf nodes. {I, J, K, F, G, H} are the leaf
nodes of the tree.
• Ancestor of a Node: Any predecessor nodes on the path of the root
to that node are called Ancestors of that node. {A,B} are the ancestor
nodes of the node {E}
• Level of a node: The count of edges on the path from the root node
to that node. The root node has level 0.
General Trees
General trees are unordered tree data structures where the root node has
minimum 0 or maximum ‘n’ subtrees.
The General trees have no constraint placed on their hierarchy. The root
node thus acts like the superset of all the other subtrees.
Binary Trees
Binary Trees are general trees in which the root node can only hold up to
maximum 2 subtrees: left subtree and right subtree. Based on the
number of children, binary trees are divided into three types.
• A full binary tree is a binary tree type where every node has either
0 or 2 child nodes.
• A complete binary tree is a binary tree type where all the leaf nodes
must be on the same level. However, root and internal nodes in a
complete binary tree can either have 0, 1 or 2 child nodes.
Perfect Binary Tree
• A perfect binary tree is a binary tree type where all the leaf nodes
are on the same level and every node except leaf nodes have 2
children.
Binary Search Trees possess all the properties of Binary Trees including
some extra properties of their own, based on some constraints, making
them more efficient than binary trees.
The data in the Binary Search Trees (BST) is always stored in such a
way that the values in the left subtree are always less than the values in
the root node and the values in the right subtree are always greater than
the values in the root node, i.e. left subtree < root node ≤ right subtree.
Balanced Binary Search Trees
Consider a Binary Search Tree with ‘m’ as the height of the left subtree
and ‘n’ as the height of the right subtree. If the value of (m-n) is equal to
0,1 or -1, the tree is said to be a Balanced Binary Search Tree.
The trees are designed in a way that they self-balance once the height
difference exceeds 1. Binary Search Trees use rotations as self-balancing
algorithms. There are four different types of rotations: Left Left, Right
Right, Left Right, Right Left.
• AVL Trees
• Red Black Trees
• B Trees
• B+ Trees
• Splay Trees
• Priority Search Trees