dsa All
dsa All
Sparse Matrix
Time-Space Trade-Off in Algorithms
It is matrix in which most of the elements of the matrix have
It is a problem solving technique in which we solve the zero value .
problem: Only we stored non-zero elements with triples- (Row,
Either in less me and using more space, or Column, value).
In very li le space by spending more me. Array representa on of Sparse Matrix –
The best algorithm is that which helps to solve a problem
that requires less space in memory as well as takes less me
to generate the output.
it is not always possible to achieve both of these condi ons
at the same me.
struct Node* addAtPos(int data , int pos , struct Node* head) A DLL is a complex version of a SLL .
{ A DLL has each node pointed to next node as well as previous node.
if(pos==1){
return addAtBeg(data,head); }
struct Node* temp=head;
for (int i = 1; i <=pos; i++)
{ if(i!=pos && temp==NULL ){
return head; //invalid position
}
if(i==pos-1){ Representa on Node of DLL :
struct Node * newNode=Node(data);
newNode->next=temp->next; struct node
temp->next=newNode; {
return head; int data; //data item for storing value of the node
} struct node *next; //address of the next node
temp=temp->next; struct node *prev; //address of the previous node
}
};
return head;
} create Node of DLL:
Delete at beginning : struct Node* Node(int data){
struct Node* newNode=(struct Node*)malloc(sizeof(struct
struct Node * deleteAtBeg( struct Node* head){
Node ));
if(head==NULL){
newNode->prev= NULL;
return NULL;
newNode->data=data;
}
newNode->next=NULL;
return head->next;
return newNode;
}
}
Delete at End :
Operations on DLL
struct Node * deleteAtEnd( struct Node* head){
if( head==NULL || head->next == NULL){ Insert At beginning :
return NULL;
} struct Node * addAtBeg(int data, struct Node* head){
struct Node* temp=head; struct Node* newNode=Node(data);
while (temp->next->next !=NULL){ if(head==NULL){
temp=temp->next; return newNode;
} }
temp->next=NULL; newNode->next=head;
return head; head->prev=newNode;
} return newNode;
}
Insert At End : Circular Linked List (CLL)
struct Node * addAtEnd(int data, struct Node* head){ All nodes are connected to form a circle.
struct Node* newNode=Node(data);
the first node and the last node are connected to each other
if(head==NULL){
return newNode; which forms a circle.
} There is no NULL at the end.
struct Node* temp=head;
while ( temp->next !=NULL)
{
temp=temp->next;
}
temp->next=newNode;
newNode->prev=temp;
return head;
Operations on CLL
}
Delete At beginning: Insert at beginning
struct Node * deleteAtBeg( struct Node* head){ Insert at specific Posi on
if(head==NULL || head->next==NULL){ Insert at end
return NULL; delete at beginning
} delete at specific posi on
head ->next->prev = NULL; delete at end
return head->next;
} Advantage & disadvantage of CLL
delete At End :
Advantages:
struct Node * deleteAtEnd( struct Node* head){ No need for a NULL pointer
if( head==NULL || head->next == NULL){ Efficient inser on and dele on
return NULL;
Flexibility
}
struct Node* temp=head; Disadvantages :
while (temp->next->next !=NULL){ Traversal can be more complex
temp=temp->next; Reversing of circular list is a complex as SLL.
}
temp->next=NULL; Row major order & Column major order
return head;
} int arr[2][3]=
Traverse DLL : { {1,2,3},
{4,5,6} } //2D array
void traverse(struct Node* head){
while (head!=NULL){ //row major order
printf("%d ", head->data); {1,2,3,4,5,6}
head=head->next; } } //column major order
ReverseTraverse DLL: {1,4,2,5,3,6}
Address of any element in 1D array
void traverseRev(struct Node* head){
if(head==NULL) Address of A[I] = B + W * (I – LB)
return;
while (head->next!=NULL) I =element, B = Base address, LB = Lower Bound
head=head->next;
W = size of element in any array(in byte),
while (head!=NULL){
printf("%d ", head->data); Example: Given the base address of an array A[1300 ………… 1900] as
head=head->prev; 1020 and the size of each element is 2 bytes in the memory, find the
} address of A[1700].
}
Advantage & disadvantage of DLL Solution :
= 100 + 1 * (110)=210
Solution:
7 7
5 7,5
2 7,5,2
+ 7,(5+2)
* 7*(5+2)
Tower of Hanoi is a mathematical puzzle where we have
three rods (A, B, and C) and N disks. Initially, all the disks
Iteration are stacked in decreasing value of diameter
Itera on is when same procedure is repeated mul ple mes Only one disk can be moved at a time.
Each repe on of process is a single itera on Each move consists of taking the upper disk from one of
Result of each itera on is star ng point of next itera on. the stacks
No disk may be placed on top of a smaller disk.
Itera on allows us to simplify our algorithm .
Total no. of steps to solve of n disk = 2n – 1 = 2*3 – 1 = 7
Itera on done by using loop of the languages
Example : factorial , fibonocci , sum of array etc Algorithm of Tower of Hnoi
int arr[5]={1,2,3,3,4} , sum =0 ; void TOH(n , s , a , d):
for (int i = 0; i < 5; i++) 1. if n==0
{ 2. return
sum+=arr[i]; 3. TOH(n-1,s,d,a) //recursive call
} 4. print(s+"to"+d)
printf("%d",sum); 5. TOH(n-1,a,s,d) // recursive call
Tower of Hnoi program in C void show()
{
#include<stdio.h> if (Front == - 1){
void towers( int num, char S, char A, char D) printf("Empty Queue \n");
{ return ;
if (num == 0) }
return; for (int i = Front; i <= Rear; i++){
towers (num - 1, S,D , A); printf("%d ", queue[i]);
printf ("\n Move disk %d from peg %c to peg %c", num, S, D); }
towers (num - 1, A, S, D); }
} int main()
int main() {
{ show(); // show the items of the queue
int num; insert(4); // insert the item on the top of queue
printf ("Enter the number of disks : "); insert(2); // insert the item on the top of queue
scanf ("%d", &num); show(); // show the items of the queue
printf ("The sequence of moves :\n"); delete(); // insert the item on the top of queue
towers (num, 'A', 'B', 'C'); show(); //show the items of the queue
return 0; }
} Implementation of queue using Linked List
Queue
#include<stdio.h>
A Queue is defined as a linear data structure #include <stdlib.h>
struct Queue {
Queue uses two pointers − front and rear.
int data;
Dele on done using front pointer.inser on done using rear struct Queue* next;
pointer. };
Queue follows the First In First Out (FIFO) rule . struct Queue* front = NULL;
all opera on of done at constant O(1) me struct Queue* rear = NULL;
First, we have to traverse the array elements using a for loop. In schools, roll number to retrieve information about
In each itera on, compare the search element with the that student.
current array element, and - A library has an infinite number of books. The librarian
If the element matches, then return the index of the assigns a unique number to each book. This unique
corresponding array element. number helps in identifying the position of the books on
If the element does not match, then move to the next the bookshelf.
element.
If there is no match or the search element is not present in Hash function and their types
the given array, return -1.
The hash function is used to arbitrary size of data to fixed-
Binary Search sized data.
It is search technique that works efficiently on sorted lists. hash = hashfunction(key)
we must ensure that the list is sorted.
Binary search follows the divide and conquer approach a. Division method :
Array divided into two parts and compared with middle
The hash func on H is defined by :
index of the element of the array
If the middle elements matched with the desired element H(k) = k (mod m) or H(k) = k (mod m) + 1
then we return the index of the element Here k (mod m) denotes the remainder when k is divided
Time complexity of the algo is O(logn) by m.
Example: k=53 , m=10 then h(53)=53mod10 =3
b. Midsquare method :
hash collision or hash clash is when two pieces of data in a Garbage collec on in hashing reclaims memory/resources
hash table share the same hash value from deleted elements that are no longer in use
It enhances hash table efficiency. Typically automa c, it's
Collision resolution technique managed by the data structure or language run me.
Mechanisms vary by language/implementa on.
We have two method to resolve this collision in our hashing .
these are following below : Insertion sort
1. Open addressing 2.seperate chaining
This is an in-place comparison-based sor ng algorithm.
1.Open addressing Here, a sub-list is maintained which is always sorted.
The array is searched sequen ally and unsorted items are
Open addressing stores all elements in the hash table itself. moved and inserted into the sorted sub-list (in the same
It systema cally checks table slots when searching for an array).
element. average and worst case complexity are of Ο(n2)
In open addressing, the load factor (λ) cannot exceed 1.
Load Factor (λ) = Number of Elements Stored / Total Number
of Slots
Probing is the process of examining hash table loca ons.
Linear Probing
it systema cally checks the next slot in a linear manner
un l an empty slot is found.
This process con nues un l the desired element is
located
method of linear probing uses the hash func on
h(k,i)= (k %m + i) mod m , where m is size of table
Quadra c Probing
it checks slots in a quadra c sequence (e.g., slot + 1, slot
+ 4, slot + 9, and so on) un l an empty slot is found.
This con nues un l the desired element is located or the
table is en rely probed.
method of Quadra c probing uses the hash func on Algorithm of Insertion sort
h(k,i)= (k %m + i^2) mod m
Double Probing 1. for j =2 to length[A]
it uses a second hash func on to calculate step size for 2. set key = A[j] and i=j-1
probing, providing a different sequence of slots to check. 3. while i > 0 and A[i] > key then
This con nues un l an empty slot is found or the desired 4. A[i + 1] = A[i]
element is located. 5. i=i–1
method of Quadra c probing uses the hash func on 6. endwhile
H1(k) = k%N and H2(k) = P - (k%P) 7. A[i + 1] = key
H(k, i) = (H1(k) + i*H2(k))%N 8. endfor
Where p is the prime Number less than k Bubble sort
Merge sort
Algorithm of Selection sort Merge sort is a sor ng algorithm that uses the idea of divide
and conquer.
1. Selection-Sort (A,n) : This algorithm divides the array into two subarray , sorts
2. for j = 1 to n – 1: them separately and then merges them.
3. sm = j
4. for i = j + 1 to n:
5. if A [i] < A[sm] then sm = i
6. Swap (A[j], A[sm])
Quick sort
radixSort(arr)
1. max = largest element in arr
2. d = number of digits in max
3. Now, create d buckets of size 0 - 9
4. for i -> 0 to d
5. sort the arr elements using counting sort
complexity of Radix sort :
1.Adjacency Matrix
An adjacency matrix is a way of represen ng a graph as a
matrix of boolean (0’s and 1’s).
Let’s assume there are n ver ces in the graph So, create a
Acyclic graph 2D matrix adjMat[n][n] having dimension n x n.
If a graph (digraph) does not have any cycle then it is If there is an edge from vertex i to j, mark adjMat[i][j] as 1.
called as acyclic graph. If there is no edge from vertex i to j, mark adjMat[i][j] as 0.
Cyclic graph
A graph that has cycles is called a cyclic graph.
Regular graph
all graph ver ces should have the same degree.
Applications Graph
Graph theory is used to find shortest path in road or a
network.
2. Adjacency List Implement DFS algorithm (Numerical)
An array is used to store edges between two ver ces
The size of array is equal to number of ver ces.
Each index in array represents a specific vertex in the
graph.
The entry at the index i of the array contains a linked list
containing the ver ces that are adjacent to vertex i.
1 2, 7
23
3 5, 4, 1
46
54
6 2, 5, 1
7 3, 6
1. Ini ally set unvisited for all vertex
2. Push 1 onto stack
3. Stack =1
4. Pop 1 from stack , set vis[1]=1 and Push 2, 7 onto stack
DFS = 1 stack = 2 7
5. Pop 7 from stack , set vis[7]=1 Push 3, 6;
DFS = 1, 7 stack =2 3 6 .
6. Pop 6 from stack , set vis[6]=1 Push 5;
DFS = 1, 7, 6 stack =2 3 5 .
Graph traversal
7. Pop 5 from stack , set vis[5]=1 Push 4;
Graph is represented by its nodes and edges, so traversal
DFS = 1, 7, 6, 5 stack = 2 3 4
of each node is the traversing in graph.
8. Pop 4 from stack, set vis[4]=1
There are two standard ways of traversing a graph
DFS = 1, 7, 6, 5, 4 stack= 2,3
1.Depth first search 2. Breadth first search
9. Pop 3 from stack , set vis[3]=1
1.Depth-first-search [DFS] DFS = 1, 7, 6, 5, 4, 3 stack =2
10. Pop 2 from stack, set vis[2]=1
Dfs is the searching or traversing algorithm , in which we DFS = 1, 7, 6, 5, 4, 3,2
used the stack data structure . 11. Now, the stack is empty, so the depth first traversal of a
In dfs ,we will first focus on the depth then go to the given graph is 1, 7, 6, 5, 4, 3 2.
breadth at that level.
Time complexity : O( V + E) & space complexity :O(v) 2.Breadth-first-search [BFS]
Algorithm: Bfs is the searching or traversing algorithm , in which we
used the queue data structure .
Step 1: SET STATUS = 1 (ready state) for each node in G
In bfs ,we will first focus on the breadth then go to the
Step 2: Push the star ng node A on the stack and set its
depth at that level.
STATUS = 2 (wai ng state)
Time complexity : O( V + E ) & space complexity :O(v)
Step 3: Repeat Steps 4 and 5 un l STACK is empty Algorithm:
Step 4: Pop the top node N. Process it and set its STATUS = 3 Step 1: SET STATUS = 1 (ready state) for each node in G
(processed state) Step 2: Enqueue the star ng node A into the queue and set its
STATUS = 2 (wai ng state)
Step 5: Push on the stack all the neighbors of N that are in the
ready state (whose STATUS = 1) and set their STATUS = 2 Step 3: Repeat Steps 4 and 5 un l queue is empty
(wai ng state)
Step 4: dequeue node N. Process it and set its STATUS = 3
(processed state)
Step 5: Push on the queue all the neighbors of N that are in the Connected component
ready state (whose STATUS = 1) and set their STATUS = 2 A connected component in a graph is a subgraph in which
(wai ng state) there is a path between every pair of ver ces. In other
Implement BFS algorithm (Numerical) words, all ver ces in a connected component are mutually
reachable.
A F, C, B
B G, C
C F
D C
E D, C, J
F D
G C, E Spanning Tree
J D, K A spanning tree of an undirected graph is a sub-graph that
K E, G is a tree which contains all the ver ces of graph.
A spanning tree of a connected graph G contains all the
Ini ally set unvisited for all vertex
ver ces and has the edges which connect all the ver ces.
Push A into queue So, the number of edges will be 1 less than the number of
Queue =A nodes.
Delete A from queue, set vis[A]=1 , insert F,C,B into queue A connected graph may have more than one spanning
BFS = A queue = F,C,B trees.
Delete F from queue, set vis[F]=1 and insert D into queue
BFS = A,F queue = C,B,D
Delete C from queue, set vis[C]=1
BFS = A,F ,C queue = B,D
Delete B from queue, set vis[B]=1 and insert G into queue
BFS = A,F ,C,B queue = D,G
Minimum Spanning Tree [MST]
Delete D from queue, set vis[D]=1
In weighted graphs, a minimum spanning tree is spanning
BFS = A,F ,C,B,D queue = G
tree with the minimum possible sum of edge weights.
Delete G from queue, set vis[G]=1 and insert E into queue
BFS = A,F ,C,B,D,G queue = E
Delete E from queue, set vis[E]=1 and insert J into queue
BFS = A,F ,C,B,D,G,E queue = J
Delete J from queue, set vis[J]=1 and insert K into queue
BFS = A,F ,C,B,D,G,E,J queue = K
Delete K from queue, set vis[K]=1
BFS = A,F ,C,B,D,G,E,J,K
Now, the queue is empty, so the breadth first traversal of a
given graph is A,F ,C,B,D,G,E,J,K
Prim’s algorithm Algorithm :
It is a greedy algorithm that is used to find the minimum
spanning tree from a graph. 1. Create a forest where each vertex is a separate tree.
Prim's algorithm starts with the single node and explores 2. Sort all the edges in non-decreasing order of their weights.
all the adjacent nodes with all the connec ng edges at 3. Pick the smallest edge. Check if it does not form a cycle then
every step. It is used for undirected graph . include int the spanning tree .
me complexity :O(E Log V)) & space complexity : O(V) 4. Repeat step 3 un l there are (V-1) edges in the minimum
spanning tree, where V is the number of ver ces.
Algorithm:
Implement kruskal’s algorithm (Numerical)
Step1. Choose a star ng vertex.
Step2. Repeat un l there are fringe ver ces:
a. Select the minimum-weight edge (e) connec ng the tree
and fringe vertex[not included].
b. Add the chosen edge and vertex to the minimum
spanning tree (T).
Step3. Exit.
Dijkstra algorithm
Dijkstra's algorithm is an algorithm for finding the shortest
paths between nodes in a weighted graph,
It is a type of Greedy Algorithm that only works on
Weighted Graphs having posi ve weights.
It can also be used for finding the shortest paths from a
single node to a single des na on
me complexity : O( E log V) & space complexity : O( V)
Algorithm :
Step 1: First, we will mark the source node with a current
distance of 0 and set the rest of the nodes to INFINITY.
Step 2: We will then set the unvisited node with the smallest
current distance as the current node “curr”.
Kruskal's Algorithm
It is a greedy algorithm that is used to find the minimum Step 3: For each neighbor N of the current node “curr”:
spanning tree from a graph. If dist[curr]+weight[N] < dist[N] then Set dist[N] =
In Kruskal's algorithm, we start from edges with the lowest dist[curr]+weight[N]
weight and keep adding the edges un l the goal is
reached. Step 4: We will then mark the current node “curr” as visited.
me complexity :O(E Log E)) & space complexity : O(V)
Step 5: We will repeat the process from 'Step 2' if there is any
node unvisited le in the graph.
Implement dijkstra algorithm (Numerical) Implement Floyd warshall algorithm (Numerical)
matrix A0
0 1 2 3 4
0 0 3 8 ∞ -4
1 ∞ 0 ∞ 1 7
2 ∞ 4 0 ∞ ∞
3 2 ∞ -5 0 ∞
4 ∞ ∞ ∞ 6 0
matrix A1 matrix A2
0 1 2 3 4 0 1 2 3 4
0 0 3 8 ∞ -4 0 0 3 8 4 -4
1 ∞ 0 ∞ 1 7 1 ∞ 0 ∞ 1 7
2 ∞ 4 0 ∞ ∞ 2 ∞ 4 0 5 11
3 2 5 -5 0 -2 3 2 5 -5 0 -2
4 ∞ ∞ ∞ 6 0 4 ∞ ∞ ∞ 6 0
matrix A3 matrix A4
0 1 2 3 4 0 1 2 3 4
0 0 3 8 4 -4 0 0 3 -1 4 -4
1 ∞ 0 ∞ 1 7 1 3 0 -4 1 -1
2 ∞ 4 0 5 11 2 7 4 0 5 3
Floyd warshall algorithm 3 2 -1 -5 0 -2 3 2 -1 -5 0 -2
It is a dynamic programming algorithm used to discover 4 ∞ ∞ ∞ 6 0 4 8 5 1 6 0
the shortest paths in a weighted graph
In which includes both posi ve & nega ve weight cycles.
It is also called all pair shortest path algorithm Final matrix
Time complexity : O(N^3) & space complexity: O(V^2)
0 1 2 3 4
Algorithm 0 0 1 -3 2 -4
1. Create a matrix 'dist' of size VxV (V is number of ver ces)
and ini alize it with the weights of the edges in the graph. 1 3 0 -4 1 -1
- If there is no direct edge between ver ces i and j, set 2 7 4 0 5 11
dist[i][j] to infinity.
- If there is a direct edge between ver ces i and j with weight 3 2 -1 -5 0 -2
w, set dist[i][j] to w. 4 8 5 1 6 0
2. For each vertex 'k' from 1 to V:
a. For each pair of ver ces 'i' and 'j':
i. If dist[i][k] + dist[k][j] is less than dist[i][j],
update dist[i][j] to dist[i][k] + dist[k][j]
3. The final 'dist' matrix contains the shortest path distances
between all pairs of ver ces.
Tree Binary tree:
A tree is a nonlinear hierarchical data structure . When any tree has at most two child , those tree is said
It consists of nodes connected by edges. to be binary tree.
In which , easy to navigate and search.
Terminologies of Tree
Node
A node is an entity that contains a key or value and
pointers to its child nodes.
Edge
It is the link between any two nodes.
Root Complete binary tree
It is the topmost node of a tree. [10] All levels are filled, except possibly the last.
Child node: Nodes are filled from left to right on all levels.
Any subnode of a given node is called a child node.
Ex: 20 & 30 & 50 are children of 10 etc.
Parent:
If node contains any sub-node, then node is called
parent of that sub-node.
Ex: 30 is parent of 60 and 40 is parent of 70 etc.
Sibling:
The nodes that have the same parent are known as
siblings.
Leaf Node:-
The node of the tree, which doesn't have any child
node Extended binary tree
Leaf nodes can also be called external nodes. A binary tree T is said to be 2-tree or extended binary
Ex : 70 ,80, 90 , 25,20, 50 tree if each node
Internal nodes: has either 0 or 2 children.
A node has atleast one child node . b. Nodes with 2 children are called internal nodes and
Ex: 10 , 30 , 40 , 60 nodes with 0 children
are called external nodes.
Height of a Node
The height of a node is the number of edges from
the node to the deepest leaf
Ex:height(30) =2 &height(20) = 0 &height(10) =3
Depth of a Node
The depth of a node is the number of edges from
the root to the node.
Ex : depth(30) =1 & depth(80) = 3 depth(10) =0
Height of a Tree Binary tree
The height of a Tree is the height of the root node . extended binary tree
Ex: Height(root=10) = 3
Representation of Binary Tree using Tree traversal is the process of visiting and processing
each node in a tree data structure.
linked list The three main types of tree traversal are:
Node structure : In-order: 2 7 5 6 11 1 5 9 9
Each node in tree is represented by an object . Pre-order: 1 7 2 6 5 11 9 9 5
Post-order: 2 5 11 6 7 5 9 9 1
In-order traversal: ( L N R)
Algorithm :
1. Traverse the left sub-tree.
2. Visit the root node.
Data : the value stored in node . 3. Traverse the right sub-tree.
Left child: pointer of left subtree of that node
Right child : pointer of right subtree of that node Pseudo-code :
1.void in-order(struct node *root)
2. {
3. if(root!= NULL)
4. {
5. in-order(root→ left);
6. printf("%d",root→ data);
7. in-order(tree→ right);
8. }
9. }
Pre-order traversal: (N L R)
Algorithm :
Representation of Binary Tree using 1.Visit the root node.
2.Traverse the left subtree.
array 3.Traverse the right subtree.
Root Node : index 0 of the array
Parent-child relationship : for any element at index I, its Pseudo-code :
left child is at index 2* I +1 and its right child is at index 1.void in-order(struct node *root)
2*1 +2 2. {
3. if(root!= NULL)
4. {
printf("%d",root→ data);
5. in-order(root→ left);
6.
7. in-order(tree→ right);
8. }
9. }
Post-order traversal: ( L R N )
Algorithm :
8. }
9. }
Draw a binary tree with following traversals :
In-order : B C A E G D H F I J
Pre-order : A B C D E F G H I J
Find the post-order of the tree.
Insertion in BST:
1.if root== null, create BST node with key and return the
node pointer.
2.If root.key > key , recursively insert the new node to the
left subtree.
3.If root.key < key , recursively insert the new node to the
right subtree.
Postorder of tree : C B G E H J I F D A
algorithm
AVL TREE