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

Data Structures Class Notes

1. The document contains class notes on data structures by Mahesh Jangid. 2. It discusses different categories of data structures including arrays and linked lists. 3. For arrays, it covers creation, insertion, deletion, and binary search of arrays. It also discusses dynamic allocation of 1D and 2D arrays in C. 4. For linked lists, it discusses creation, insertion, and deletion in single linked lists through examples in C code.

Uploaded by

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

Data Structures Class Notes

1. The document contains class notes on data structures by Mahesh Jangid. 2. It discusses different categories of data structures including arrays and linked lists. 3. For arrays, it covers creation, insertion, deletion, and binary search of arrays. It also discusses dynamic allocation of 1D and 2D arrays in C. 4. For linked lists, it discusses creation, insertion, and deletion in single linked lists through examples in C code.

Uploaded by

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

Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Categories of Data Structures

1.Array
Array is a kind of data structure that can store a fixed-size sequential
collection of elements of the same type. An array is used to store a collection
of data, but it is often more useful to think of an array as a collection of
variables of the same type.

1.1 Array Creation

Assume a[n]
Print “enter no of elements”
Read n
for(i=0;i<n;i++)
{
Print “ enter the element”
Read a[i]
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

1.2 Array Insertion

Assume a[n],fai \\fai - Filled Array Index (index of the last


element of Array)
Read pos
if(fai<n-1)
{
Read ele
for(i=fai;i>pos-1;i--)
{
a[i+1]=a[i]
}
a[pos-1]=ele;
}

1.3 Array Deletion

assume a[n], fai, pos, ele, size = n.


if( fai > -1) \\ element is present or not
{
read pos, ele.
if(pos-1<= fai) \\position is under limit
{
for(i=pos-1; i< fai; i++)
{
a[i]=a[i+1]
}
fai- -
}
else print (Invalid Position)
}
else print (No element )

1.3 Array binary search

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

assume a[10], l=0, u=9, mid, ele.


read ele \\ to be find
while(l<=u)
{
mid=(l+u)/2
if(ele>a[mid])
l=mid+1
else if(ele<a[mid])
u=mid-1
else
{
print (element found)
break
}
}

1.4 How to dynamically allocate a 1D array in C?

#include <stdio.h>
#include <stdlib.h>

int main()
{

// This pointer will hold the


// base address of the block created
int* ptr;
int n, i, sum = 0;

// Get the number of elements for the array


n = 5;

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using malloc()


ptr = (int*)malloc(n * sizeof(int));

// Check if the memory has been successfully


// allocated by malloc or not
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {

// Memory has been successfully allocated


printf("Memory successfully allocated using malloc.\n");

// Get the elements of the array


for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}

// Print the elements of the array


printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}

return 0;
}
Output:
Enter number of elements: 5
Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5,

To know more:-
https://www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-mall
oc-calloc-free-and-realloc/

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

1.4 How to dynamically allocate a 2D array in C?


Following are different ways to create a 2D array on heap (or dynamically allocate a 2D
array).
In the following examples, we have considered ‘r‘ as number of rows, ‘c‘ as number of
columns and we created a 2D array with r = 3, c = 4 and following values

1 2 3 4
5 6 7 8
9 10 11 12

1) Using a single pointer:


A simple way is to allocate memory block of size r*c and access elements using simple
pointer arithmetic.

#include <stdio.h>
#include <stdlib.h>

int main() {
int r = 3, c = 4;
int * arr = (int * ) malloc(r * c * sizeof(int));

int i, j, count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i * c + j) = ++count;

for (i = 0; i < r; i++)


for (j = 0; j < c; j++)
printf("%d ", *(arr + i * c + j));

/* Code for further processing and free the dynamically


allocated memory */
return 0;
}
Output:
1 2 3 4 5 6 7 8 9 10 11 12

2) Using an array of pointers


We can create an array of pointers of size r. After creating an array of pointers, we
can dynamically allocate memory for every row.

#include <stdio.h>

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

#include <stdlib.h>

int main()
{
int r = 3, c = 4, i, j, count;

int *arr[r];
for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));

// Note that arr[i][j] is same as *(*(arr+i)+j)


count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count; // Or *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)


for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);

/* Code for further processing and free the


dynamically allocated memory */

return 0;
}
Output:

1 2 3 4 5 6 7 8 9 10 11 12

3) Using pointer to a pointer


We can create an array of pointers also dynamically using a double pointer. Once we
have an array of pointers allocated dynamically, we can dynamically allocate memory
and for every row like method 2.

filter_none
edit
play_arrow

Brightness_4

#include <stdio.h>

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

#include <stdlib.h>

int main()
{
int r = 3, c = 4, i, j, count;

int **arr = (int **)malloc(r * sizeof(int *));


for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));

// Note that arr[i][j] is same as *(*(arr+i)+j)


count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)


for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);

/* Code for further processing and free the


dynamically allocated memory */

return 0;
}
Output:

1 2 3 4 5 6 7 8 9 10 11 12

4) Using double pointer and one malloc call

filter_none
edit
play_arrow

Brightness_4

#include<stdio.h>

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

#include<stdlib.h>

int main()
{
int r=3, c=4, len=0;
int *ptr, **arr;
int count = 0,i,j;

len = sizeof(int *) * r + sizeof(int) * c * r;


arr = (int **)malloc(len);

// ptr is now pointing to the first element in of 2D array


ptr = (int *)(arr + r);

// for loop to point rows pointer to appropriate location in


2D array
for(i = 0; i < r; i++)
arr[i] = (ptr + c * i);

for (i = 0; i < r; i++)


for (j = 0; j < c; j++)
arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)


for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);

return 0;
}
Output:

1 2 3 4 5 6 7 8 9 10 11 12

To know more:- https://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

2. Linked list

2.1 Single Linked List


In computer science, a linked list is a linear collection of data elements, called
nodes, each pointing to the next node by means of a pointer.

2.1.1 Linked list creation


#include <stdio.h>
#include <stdlib.h>
int main()
{
struct node
{
int data;
struct node*next;
};
struct node *head;
head=0;
struct node *newnode,*temp;
int choice;

while (choice!=0)
{
printf("Enter data?(1/0)=");
scanf("%d",&choice);
newnode=(struct node*)malloc(sizeof(struct node));

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

printf("\n\n Enter data=");


scanf("%d",&newnode->data);
newnode->next=0;

if(head==0)
{
head=temp=newnode;
}
else
{
temp->next=newnode;
temp=newnode;
}
}
//printing(traversal)
temp=head;
while(temp->next!=0)
{
printf("\ndata=%d",temp->data);
temp=temp->next;
}
return 0;
}

2.1.2 Linked list insertion

struct node
{
int data.
struct node *ptr.
}*start == NULL;

assume *start, *last

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

t = (struct node*) malloc( sizeof (struct node) ) .


read t -> data.
read pos.
if (pos == 1)
{
t -> ptr = start.
start = t.
}
else
{
t1 = start
for (i=2; i<pos && t1->ptr! = NULL; i++)
{
t1 = t1 -> ptr.
}
t -> ptr = t1 -> ptr.
t1 -> prt = t.
}

2.1.3 Linked list deletion

struct node
{
int data.
struct node *ptr.
}*start = NULL.

read pos.
if (pos == 1)
{
t = start.
start = start->ptr.
free (t).
}
else
{
t = t1 = start.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

for ( i=1; i< pos; i++)


{
t1 = t.
t = t->ptr.
if (t == NULL)
{
f=1.
break.
}
}
if (f != 1)
{
t1 -> ptr = t ->ptr.
}
else
{
print (Error)
}

2.2 Circular Linked List.


In a circularly linked list, all nodes are linked in a continuous circle, without using
null.The next node after the last node is the first node.

2.2.1 Circular LL creation.


struct node
{
int data.
struct node *ptr.
}*start = NULL.

declare struct node *t, *last.


read n.
for ( i = 1 to n )

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

{
t = (struct node*) malloc( sizeof (struct node) ) .
read t -> data.
if (start == NULL)
{
start = t.
}
else
{
last -> ptr = t.
}
t -> ptr = start.
last = start.
}

2.2.2 Circular LL Traversing


struct node
{
int data.
struct node *ptr.
}*start = NULL.
1. assume *start.
2. declare struct node *t.
3. for (t=start; start != NULL; t = t -> ptr)
4. {
5. print ( t -> data)
6. if (t -> ptr = start)
7. break
8. }

2.2.3 Circular LL insertion.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

struct node
{
int data.
struct node *ptr.
}*start = NULL.

1. assume *start, *last.


2. declare struct node *t, *t1.
3. read pos.
4. t = (struct node*) malloc( sizeof (struct node) ) .
5. read t-> data.
6. if (pos == 1)
7. {
8. t -> ptr = start.
9. start =t.
10. last -> ptr = t.
11. }
12. else
13. {
14. t1 = start.
15. for (i=2; i<pos && t1 -> ptr !=start; i++)
16. {
17. t1 = t1 -> ptr.
18. t1 -> ptr = t.
19. } }

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

2.2.4 Circular LL deletion

struct node
{
int data.
struct node *ptr.
}*start = NULL.
1. assume *start, *last.
2. declare struct node *t, *t1.
3. if (start != NULL)
4. {
5. read pos.
6. if (pos == 1)
7. {
8. t = start.
9. start = start -> ptr.
10. free (t).
11. last -> ptr = start.
12. }
13. else
14. {
15. t = start.
16. for (i=1; i < pos; i++)
17. {
18. t1 = t.
19. t = t -> ptr.
20. }
21. t1 -> ptr = t -> ptr.
22. free (t).
23. }

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

2.3 Doubly Linked List


A doubly linked list is a linked data structure that consists of a set of sequentially linked records
called nodes. Each node contains two fields, called links, that are references to the previous and
the next node in the sequence of nodes. The beginning and ending nodes' previous and next
links, respectively, point to NULL.

2.3.1 Doubly linked list creation.

struct node
{
int data;
struct node *pre, *next;
}*start = NULL.
declare struct node *t, *last.
read n.
for (i = 1 to n)
{
t = (struct node*) malloc( sizeof (struct node) )
read t -> data.
t -> next = NULL.
if ( start == NULL)
{
start = t.
t -> pre = NULL.
}
else
{
last -> next = t.
t -> pre = last.
}
last = t. }

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

2.3.2 Doubly LL insertion.

assume *start, *last.


Declare struct node *t, *t1.
read pos.
t = (struct node*) malloc( sizeof (struct node) )
read t -> data.
If ( pos == 1)
{
t -> next = start.
start -> pre = t.
start = t.
t -> pre = NULL.
}
else
{
t1 = start.
for (i=2; i<pos; i++)
{
t1=t1->next;
}
t -> next = t1 -> next.
t -> pre = t1.
if( t1 ->next!= NULL)
{
(t1->next)->pre=t
}
t1->next=t

2.3.3 Doubly LL deletion.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

1. assume a DLL *start, *last.


2. Declare struct node *t, *t1.
3. if( start!=NULL)
4. {
5. Read pos
6. If(pos==1)
7. {
8. t=start.
9. start=start->next
10. free(t).
11. }
12. else
13. {
14. t=t1=start.
15. for( i=1; i<pos; i++)
16. {
17. t1=t
18. t=t->next.
19. }
20. t1->next=t->next.
21. if( t->next != NULL)
22. {
23. (t->next)->pre=t1.
24. }
25. free(t) }

3. Stack

A Stack is an abstract data structure which is used to store data in a particular order.
It is either implemented with the help of an array or a linked list. Two operations that
can be performed on a Stack are: Push operation which inserts an element into the
stack. Pop operation which removes the last element that was added into the stack.
It follows the Last In First Out(LIFO) Order.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

3.1 Stack implementation by Array.

Declare int stack[10],size=10,top=-1


push (int ele)
{
if (top==size-1)
print (overflow)
else
stack[++top]=ele.
}

int pop()
{
if(top==-1)
print(overflow)
else
return stack[top--]
}

3.2 Stack implementation by Linked list


struct node
{
int data
struct node *ptr.
}*top=NULL;

push( int ele)


{
t = (struct node*) malloc( sizeof (struct node) )
if (t!=NULL)
{
t->data=ele
t->ptr=top
top= t
}
else
print (overflow)
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

int pop()
{
if(top!=NULL)
{
t=top.
top=top->ptr
ele =t->data
free(t)
return ele
}
else
print underflow
}

3.2 Stack Applications

3.2.1 Parenthesis checking

Declare stack[20],top=-1 // for stack implementation

void push(char ele)


{ stack[++top]=ele; }

char pop()
{ if(top==-1)
return '#'
else
return stack[top--] }

Declare FILE *fp


fp=fopen("demo.c","r")
while((ch=fgetc(fp)!=EOF)
{
if(ch=='{')
push('{')
Else if (ch=='}')
{

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

ch1=pop();
if(ch1=='#')
Break;
}
}
if(ch=='#' || top!=-1)
print("incorrect sequence")
Else
print("Correct sequence")

3.2.2 Solving postfix expression


Assume a postfix expression in p[]
while(p[i]!='\0')
{
if(p[i] is equal to ('+','-','/','*'))
{
op2=pop();
op1=pop();
switch(p[i])
{
case '+' : push(op1+op2);
break.
case '-' : push(op1-op2);
break.
case '/' : push(op1/op2);
break.
case '*' : push(op1*op2);
break.
} }
else
push(p[i]-'0').
i++;
}
print (result = pop()).

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

3.2.3 Infix to Postfix


Declare char p[ ]; char q[ ], ch; int ind=0
read p
push('#')
for(i=0;p[i]!=0;i++)
{
if(p[i]>='0' && p[i]<='9')
q[ind++]=p[i]
else if(p[i]=='(')
push('(')
else if(p[i]==')') {
ch=pop()
while(ch!='(')
{
q[ind++]=ch
ch=pop()
}
}
else
{
op=pop()
while(prio(op)>=prio(p[i]))
{
q[ind++]=op
op=pop()
}
push(op)
push(p[i])
}
}//end of for
ch=pop()
while(ch!='#')
{
q[ind++]=ch.
ch=pop()
}
q[ind]='\0'

int prio(char ele)

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

{
if(ele=='+'|| ele=='-')
return 2.
else if(ele=='/'||ele=='*')
return 3.
Else
return 1. }

3.2.4 Infix to postfix conversion by stack (Stepwise solution)


[(3+5*2)+8/2] Stack (pop only priority Q(array/output)
is equal and high)

[ [

( [(

3 [( 3

+ [(+ 3

5 [(+ 35

* [(+ * 35

2 [( + * 352

) [( 352*+

+ [+ 352*+

8 [+ 352*+8

/ [ +/ 352*+8

2 [+/ 352*+82

] 352*+82/+

Evaluation of postfix expression :


2, 3, 5, *, +, /, - stack Partial Result

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

2 2

2, 3 2, 3

2, 3, 5 2, 3, 5 Op1 (opr) Op2

2, 3, * 2, 15 3*5=15

2, 3, *, + 17 2+15=17

2, 3, *, +,/ 17, 1

2, 3, *, +, / , - 16 17-1=16

3.2.5 Infix to prefix conversion

declare char p[], char q[], int x


read p
x = strlen(p)
push('#')
for (i = x; i > 0; i--) {
if (p[i] >= '0' && p[i] <= '9')
q[ind++] = p[i]
else if (p[i] == ')')
push(')')
else if (p[i] == '(')
ch = pop();
while (ch != ')') {
q[ind++] = ch
ch = pop()
}
else {
op = pop()
while (prio(op) > prio(p[i])) {
q[ind++] = op
op = pop()
}
push(op)
push(p[i])
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

} //end of for
ch = pop()
while (ch != '#') {
q[ind++] = ch.
ch = pop()
}

int prio(char ele)


{
if(ele=='+'|| ele=='-')
return 2.
else if(ele=='/'||ele=='*')
return 3.
else
return 1.
}

Infix to Prefix conversion by Stack (Stepwise solution)


a+b-c*d+(e-f) Stack (Pop only priority Q(array/output)
(right to left) is high)

) #)

f #) f

- #)- f

e #)- fe

( # fe-

+ #+ fe-

d #+ fe-d

* #+* fe-d

c #+* fe-dc

- #+- fe-dc*

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

b #+- fe–dc*b

+ #+-+ fe–dc*b

A #+-+ fe–dc*ba

fe–dc*ba+-+
Reverse the expression +, -, +, a, b, *, c, d, –, e, f

3.2.6 Evaluation of prefix.


-, +,2,3,*,/,8,2,3 (R to L) Stack Result

3 3

2 3, 2

8 3, 2, 8

/ 3, 4 8/2=4

* 12 4*3=12

3 12, 3

2 12, 3, 2

+ 12, 5 3+2=5

- -7 5-12=-7

3.2.7 Tower of Hanoi.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

TOH(n, A, B, C) // ( S, M, D)
{
if(n==1)
{
Print("move %c disk from %c to %c", n, A, C)
Return
}
TOH( n-1, A, C, B) // (S, D, M)
Print( "move %c disk from %c to %c", n, A, C)
TOH(n-1, B, A, C) //( M, S, D)
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

4.Queue

4.1 Implementation of Queue by Array.


define queue[10], front=-1, rear=-1, size=10;

insertionQA(int ele)
{
if(rear==size-1)
{
print(Overflow)
}
else if(rear==-1)
{
rear=front=0
queue[rear]=ele
}
else
{
rear=rear+1;
queue[rear]=ele
}

}//end of insertionQA

int deletionQA()
{
if(front==-1)
{

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

print(overflow)
}
else if(front==rear)
{
ele=queue[front]
front=rear=-1
return ele
}
else
{
ele=queue[front]
front=front+1
return ele
}}

printQA()
{
if(front==-1)
{
print(underflow)
}
else
{
for(i=front;i<=rear;i++)
Print(queue[i])
}
}

4.2 Circular Queue.


declare int cq[], front=-1,rear=-1,size=10;
insertionCQA(int ele)
{
if (front==(rear+1)%size)) or
//if (front==0&&rear==size-1||front==rear+1)
print(Overflow)
else if(rear==-1)
{
front=rear=0

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

cq[rear]=ele
}
else
{
rear=(rear+1)%size
cq[rear]=ele
}
}

DeletionQA()
{
if(front==-1)
print(overflow)
else if (front==rear)
front=rear=-1
else
front=(front+1)%size
}

print()
{

for(i=front;front!=-1;i=(i+1)%size)
{
print(cq[i])
if(i==rear)
break;
}
}

OR //alternate for print()

print()
{
if(front<=rear)
{
for(i=front;i<=rear;i++)
print(cq[i])
}
else
{

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

for(i=front;i<=size-1;i++)
print(cq[i])
for(i=0;i<=rear;i++)
print(cq[i])
}
}

4.3 Queue- Linked List


struct node
{
int data
struct node *ptr
}*front=NULL,*rear=NULL

insertionQLL(int ele)
{
struct node *t
t=malloc()
if(t!=NULL)
{
t->data=ele
t->ptr=NULL
if(rear==NULL)
front=rear=t
else
{
rear->ptr=t
rear=t
}
}

deletionQLL()
{
if(front==NULL)
print(underflow)
else if(front==rear)
{
free (front)

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

front=rear=NULL
}
else
{
t=front
front=front->ptr
free(t)
}
}

printQLL
{
for(t=front;t!=NULL;t=t->ptr)
print(t->data)
}

4.4 Priority Queue by linked list


struct node
{
int data, pri
struct node *ptr
}*front=NULL;

insertionPQLL(int ele, int priority)


{
t= malloc;
if(t!=NULL)
{
t->data=ele
t->pri=priority

if(front==NULL)
{
front=t;
t->ptr=NULL;
}
else
{
if(t->pri < front->pri)

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

{
t->ptr=front
front=t
}
else
{
for(t2=front; t->pri >= t2->pri && t2!=NULL; )
{
t1=t2
t2=t2->ptr
}
t->ptr=t1->ptr
t1->ptr=t;
}//end of inner else
}// end of outer else
}// end of if
}

4.5 Priority using array:


Declare mq[3][5], fr[3][2]={-1,-1,-1,-1,-1,-1};
rsize=3, csize=5;

InsertionPQA(in ele, int priority)


{
if(fr[priority][0]==(fr[priority][1]+1)%csize)
Print (Overflow)
else if(fr[priority][0]==-1)
{
fr[priority][0]=fr[priority][1]=0
mq[priority][0]=ele;
}
else
{
fr[priority][1]=(fr[priority][1]+1)%csize
mq[priority][fr[priority][1]]=ele;
}
}

deletionPQA()

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

{
for(i=0;i<rsize;i++)
{
if(fr[i][0]!=-1)
{
if(fr[i][0]==fr[i][1])
{
print(mq[priority][fr[priority][0]])
fr[priority][0]=fr[priority][1]=-1
break;
}
else
{
print(mq[i][fr[i][0]])
fr[i][0]=(fr[i][0]+1)%csize
break;
}
}
if(i==rsize)
print(“underflow”);
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

5.Trees

5.1 Binary Tree

5.1.1 Binary Tree Creation :


struct node
{
int data;
struct node *lc,*rc;
} *root=NULL;

struct node * Binarytreecreation()


{
Print “Enter data otherwise -1”
Read data
if( data!=-1)

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

{
t=malloc()
t->data=data;

Print “Enter left child of %d”,data


t->lc=binarytreecreation()
Print “Enter right child of %d”,data
t->rc=binarytreecreation()
return t;
}
else
return NULL;
}

main()
{
root=binarytreecreation();
preorder(root);
}

5.1.2 Pre Order:


// using recursion
preorder(struct node *t)
{
if(t!=NULL)
{
Print:- t->data;
preorder(t->lc);
preorder(t->rc);
}
}

Ptr is pointing binary tree(Root) //using stack


preorder(struct node *ptr)
{
While(ptr!=NULL)
{

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Print(ptr->data)
If(ptr->rc!=NULL)
push(ptr->rc)
else if(ptr->lc!=NULL)
ptr=ptr->lc;
else
ptr=pop()
}
}

5.1.3 Inorder:
//using recursion
inorder(struct node * t)
{
if(t!=NULL)
{
inorder(t->lc);
Print:- t->data;
inorder(t->rc);
}
}

// using stack

again: While(ptr != NULL)


{
push(ptr)
ptr=ptr->lc
}
ptr=pop()
while(ptr!=NULL)
{
Print(ptr->data)
If(ptr->rc!=NULL)
{
ptr=ptr->rc
goto again
}
Else

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

ptr=pop()
}

5.1.4 Postorder
postorder(struct node * t) //using recursion
{
if(t!=NULL)
{
postorder(t->lc);
postorder(t->rc);
Print:- t->data;
}
}
1.

5.2 Binary Search Tree

5.2.1 Searching in BST


search(struct node *root1, int ele)
{
If(root1==NULL)
Print(Not Found)
Else if(root1->data==ele)
Print(Found)
Else if(ele>root1->data)
search(root1->rc,ele)
Else if(ele<root1->data)
search(root1->lc,ele)
}

5.2.2 BST Insertion and Creation.


struct node
{
int data
struct node *lc,*rc;
};

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

struct node *insertion(struct node* root1, int ele)


{
If(root1==NULL)
{
struct node *t=malloc()
t->data=ele
t->lc=t->rc=NULL
return t
}
else if(ele>root1->data)
root1->rc=insertion(root1->rc,ele)
else if(ele<root1->data)
root1->lc=insertion(root1->lc,ele)

return root1 }
main()
{
struct node *root =NULL
read ele
root=insertion(root,ele)
}

5.2.3 Deletion in BST


struct node* deletion(struct node* root1, int ele)
{
If(root1==NULL)
return root1;
else if(ele >root1->data)
root1->rc=deletion(root1->rc,ele)
else if(ele<root1->data)
root1->lc=deletion(root1->lc,ele)
else
{
If(root1->lc==NULL)
{
struct node *temp=root1->rc

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

free root1
return temp
}
If(root1->rc==NULL)
struct node *temp=root1->lc
free root1
return temp
}
struct node *temp=minvalue(root1->rc)
root1->data=temp->data
root1->rc=deletion(root1->rc,temp->data)
} //end of else
return root1
}
struct node *minvalue(struct node *t)
{
while(t->lc!=NULL)
{
t=t->lc }

return root1
}

5.3 AVL Tree

5.3.1 AVL Tree Insertion


struct node
{
int data
struct node *lc, *rc
int ht
}

int height(struct node *t)

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

if(t==NULL)
return 0;
else
{
int lh, rh;
lh=height(t->lc);
rh=height(t->rc);

if(lh>rh)
return (lh+1);
else
return (rh+1);
}
}

int balfact(struct node *t)


{
int lh, rh
if(t==NULL)
return 0

if(t->lc==NULL)
lh=0
else
lh=t->lc->ht
if(t->rc==NULL)
rh=0
else
rh=t->rc->ht

return (lh-rh)
}

struct node * insertion(struct node * t, int ele)


{
If(t == NULL)
{

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

t = malloc()
t - > data = ele
t - > lc = t - > rc = NULL
}
else if (ele > t - > data)
{
t - > rc = insertion(t - > rc, ele)
if (balfact(t) == -2)
{
if(ele > t - > rc - > data)
t = RRrotation(t)
else
t = RLrotation(t)
}
}
else if (ele < t - > data)
{
t - > lc = insertion(t - > lc, ele)
if (balfact(t) == 2)
{
if(ele < t - > lc - > data)
t = LLrotation(t)
else
t = LRrotation(t)
}
t - > ht = height(t)
return t
}
}

LLrotation(struct node *t)


{
t=RightRotate(t)
return t
}

RRrotation(struct node *t)


{
t=LeftRotate(t)
return t

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

LeftRotate(*a)
{
struct node *b=a->rc
a->rc=b->lc
b->lc=a
a->ht=height(a)
b->ht=height(b)
return b
}

RightRotate(*a)
{
struct node *b=a->lc
a->lc=b->rc
b->rc=a
a->ht=height(a)
b->ht=height(b)
return b
}

RLrotation(struct node *t)


{
t->rc=RightRotate(t->rc)
t=LeftRotate(t)
return t
}

LRrotation(struct node *t)


{
t->lc=LeftRotate(t->lc)
t=RightRotate(t)
return t

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

5.3.2 AVL Tree Deletion


deletion( * t, ele)
{
if (t == NULL)
{
print "Not Found!"
return NULL;
}

if (ele > t - > data)


{
t - > rc = deletion(t - > rc = ele);
if (balfact(t) == 2)
{
if (balfact(t - > lc) >= 0)
t = LLrotation(t);
else
t = LRrotation(t);
}
}
else if (ele < t - > data)
{
t - > lc = deletion(t - > lc, ele)
if (balfact(t) == -2) {
if (balfact(t - > lc) <= 0)
RRrotation(t);
else
RLrotation(t);
}

if (t - > rc != NULL)
{
* temp = t - > rc;
while (temp - > lc = NULL)
temp = temp - > lc;
t - > data = temp - > data;
t - > rc = deletion(t - > rc, temp - > data);
if (balfact(t) == 2)
{
if (balfact(t - > lc) >= 0)
t = LLrotation(t);

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

else
t = LRrotation(t);
}
else
{
return (t - > lc)
}
t - > ht = height(t - > lc)
return t;
}
}

5.4 Heap sorting (Max Heap)

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

5.4.1 Heap Insertion

Max heap
1. Assume a[max] \\n=last index of max heap tree
2. n=n+1, ptr=n, ele=a[n]
3. While (ptr>0)
4. {
5. par=(ptr-1)/2
6. if(ele=<a[par])
7. {
8. a[ptr]=ele;
9. Return;
10. }
11. a[ptr]=a[par]
12. ptr=par;
13. }
14. a[ptr]=ele;
15. exit

5.4.2 Heap Deletion

Max heap
1. Assume a[max]
2. ele=a[n],n=n-1, ptr=0, left=1, right=2
3. While (right<=n)
4. {
5. if(ele>=a[left] and ele>=a[right] )
6. {
7. a[ptr]=ele;
8. Return;
9. }
10. else if (a[left]<a[right])
11. {
12. a[ptr]=a[right]
13. ptr=right;

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

14. }
15. else if (a[left]>a[right])
16. {
17. a[ptr]=a[left]
18. ptr=left;
19. }
20. left=(2*ptr)+1;
21. right=left+1;
22. }
23. if(left==n and ele<=a[left])
24. a[ptr]=ele;
25. else
26. {
27. a[ptr]=a[left]
28. a[left]=ele;
29. }
30. exit

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

6. Graph
Source:- https://www.geeksforgeeks.org/graph-and-its-representations/

A Graph is a non-linear data structure consisting of nodes and edges. The nodes are
sometimes also referred to as vertices and edges are lines or arcs that connect any
two nodes in the graph. More formally a Graph can be defined as,

A Graph consists of a finite set of vertices(or nodes) and set of Edges which connect

a pair of nodes.

In the above Graph, the set of vertices V = {0,1,2,3,4} and the set of edges E = {01, 12,

23, 34, 04, 14, 13}.

Graphs are used to solve many real-life problems. Graphs are used to represent

networks. The networks may include paths in a city or telephone network or circuit

network. Graphs are also used in social networks like linkedIn, Facebook. For

example, on Facebook, each person is represented by a vertex(or node). Each node

is a structure and contains information like person id, name, gender, locale etc.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

6.1 Graph and its representations


Graph is a data structure that consists of the following two components:

1. A finite set of vertices also called as nodes.

2. A finite set of ordered pair of the form (u, v) called as edge. The pair is ordered

because (u, v) is not the same as (v, u) in the case of a directed graph(di-graph). The

pair of the form (u, v) indicates that there is an edge from vertex u to vertex v. The

edges may contain weight/value/cost.

Graphs are used to represent many real-life applications: Graphs are used to

represent networks. The networks may include paths in a city or telephone network

or circuit network. Graphs are also used in social networks like linkedIn, Facebook.

For example, on Facebook, each person is represented by a vertex(or node). Each

node is a structure and contains information like person id, name, gender and locale.

See this for more applications of graph.

Following is an example of an undirected graph with 5 vertices.

Following two are the most commonly used representations of a graph.

1. Adjacency Matrix

2. Adjacency List

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

There are other representations also like, Incidence Matrix and Incidence List. The

choice of the graph representation is situation specific. It totally depends on the type

of operations to be performed and ease of use.

6.1.1 Adjacency Matrix:

Adjacency Matrix is a 2D array of size V x V where V is the number of vertices in a

graph. Let the 2D array be adj[][], a slot adj[i][j] = 1 indicates that there is an edge from

vertex i to vertex j. Adjacency matrix for undirected graph is always symmetric.

Adjacency Matrix is also used to represent weighted graphs. If adj[i][j] = w, then there

is an edge from vertex i to vertex j with weight w.

The adjacency matrix for the above example graph is:

Pros: Representation is easier to implement and follow. Removing an edge takes

O(1) time. Queries like whether there is an edge from vertex ‘u’ to vertex ‘v’ are

efficient and can be done O(1).

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Cons: Consumes more space O(V^2). Even if the graph is sparse(contains less

number of edges), it consumes the same space. Adding a vertex is O(V^2) time.

Please see this for a sample Python implementation of adjacency matrix.

6.1.2 Adjacency List:

An array of lists is used. Size of the array is equal to the number of vertices. Let the

array be array[]. An entry array[i] represents the list of vertices adjacent to the ith

vertex. This representation can also be used to represent a weighted graph. The

weights of edges can be represented as lists of pairs. Following is adjacency list

representation of the above graph.

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

Note that in the below implementation, we use dynamic arrays (vector in

C++/ArrayList in Java) to represent adjacency lists instead of linked lists. The vector

implementation has advantages of cache friendliness.

// A simple representation of graphs using STL


#include<bits/stdc++.h>

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

using namespace std;

// A utility function to add an edge in an


// undirected graph.
void addEdge(vector<int> adj[], int u, int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}

// A utility function to print the adjacency list


// representation of graph
void printGraph(vector<int> adj[], int V)
{
for (int v = 0; v < V; ++v)
{
cout << "\n Adjacency list of vertex "
<< v << "\n head ";
for (auto x : adj[v])
cout << "-> " << x;
printf("\n");
}
}

// Driver code
int main()
{
int V = 5;
vector<int> adj[V];
addEdge(adj, 0, 1);
addEdge(adj, 0, 4);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);
printGraph(adj, V);
return 0;
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

6.2 Graph traversing


6.2.1 Breadth First Search (BFS )
Breadth First Traversal (or Search) for a graph is similar to Breadth First Traversal of

a tree (See method 2 of this post). The only catch here is, unlike trees, graphs may

contain cycles, so we may come to the same node again. To avoid processing a

node more than once, we use a boolean visited array. For simplicity, it is assumed

that all vertices are reachable from the starting vertex.

For example, in the following graph, we start traversal from vertex 2. When we come

to vertex 0, we look for all adjacent vertices of it. 2 is also an adjacent vertex of 0. If

we don’t mark visited vertices, then 2 will be processed again and it will become a

non-terminating process. A Breadth First Traversal of the following graph is 2, 0, 3, 1.

Recommended: Please solve it on “PRACTICE ” first, before moving on to the solution.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Following are the implementations of simple Breadth First Traversal from a given

source.

The implementation uses adjacency list representation of graphs. STL‘s list

container is used to store lists of adjacent nodes and queue of nodes needed for

BFS traversal.

BFS Algorithm:-
BFS (G, s) //Where G is a graph and s is the source node
let Q be queue.
Q.enqueue( s ) //Inserting s in queue until all its neighbour vertices
are marked.
mark s as visited.
while ( Q is not empty)
//Removing that vertex from queue,whose neighbour will be visited now
v = Q.dequeue( )
//processing all the neighbours of v
for all neighbours w of v in Graph G
if w is not visited
Q.enqueue( w )//Stores w in Q to further visit its neighbour
mark w as visited.

vector <int> v[10] ; //Vector for maintaining adjacency list explained


above
int level[10]; //To determine the level of each node
bool vis[10]; //Mark the node if visited
void bfs(int s) {
queue <int> q;
q.push(s);
level[ s ] = 0 ; //Setting the level of the source node as 0
vis[ s ] = true;
while(!q.empty())
{
int p = q.front();
q.pop();
for(int i = 0;i < v[ p ].size() ; i++)
{
if(vis[ v[ p ][ i ] ] == false)
{
//Setting the level of each node with an increment in the level
of parent node
level[ v[ p ][ i ] ] = level[ p ]+1;
q.push(v[ p ][ i ]);

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

vis[ v[ p ][ i ] ] = true;
}
}
}
}

6.2.2 Depth First Search (DFS)

The DFS algorithm is a recursive algorithm that uses the idea of backtracking. It involves

exhaustive searches of all the nodes by going ahead, if possible, else by backtracking.

Here, the word backtrack means that when you are moving forward and there are no more nodes

along the current path, you move backwards on the same path to find nodes to traverse. All the

nodes will be visited on the current path till all the unvisited nodes have been traversed after

which the next path will be selected.

This recursive nature of DFS can be implemented using stacks. The basic idea is as follows:

Pick a starting node and push all its adjacent nodes into a stack.

Pop a node from stack to select the next node to visit and push all its adjacent nodes into a

stack.

Repeat this process until the stack is empty. However, ensure that the nodes that are visited are

marked. This will prevent you from visiting the same node more than once. If you do not mark the

nodes that are visited and you visit the same node more than once, you may end up in an infinite

loop.

Pseudocode
DFS-iterative (G, s): //Where G is a graph and s is source vertex
let S be stack
S.push( s ) //Inserting s in stack
mark s as visited.
while ( S is not empty):
//Pop a vertex from stack to visit next
v = S.top( )
S.pop( )

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

//Push all the neighbours of v in stack that are not visited


for all neighbours w of v in Graph G:
if w is not visited :
S.push( w )
mark w as visited

DFS-recursive(G, s):
mark s as visited
for all neighbours w of s in Graph G:
if w is not visited:
DFS-recursive(G, w)

6.3 Minimum Spanning Tree


6.3.1 Prim's Algorithm

Prim's algorithm is a minimum spanning tree algorithm that takes a graph as input
and finds the subset of the edges of that graph which

● form a tree that includes every vertex


● has the minimum sum of weights among all the trees that can be formed from
the graph

How Prim's algorithm works

It falls under a class of algorithms called greedy algorithms which find the local
optimum in the hopes of finding a global optimum.

We start from one vertex and keep adding edges with the lowest weight until we
reach our goal.

The steps for implementing Prim's algorithm are as follows:

1. Initialize the minimum spanning tree with a vertex chosen at random.


2. Find all the edges that connect the tree to new vertices, find the minimum and
add it to the tree
Available by :- Crystal Dias-2019 batch | 3A-CSE
Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

3. Keep repeating step 2 until we get a minimum spanning tree

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Prim's Algorithm pseudocode

The pseudocode for prim's algorithm shows how we create two sets of vertices U
and V-U. U contains the list of vertices that have been visited and V-U the list of
vertices that haven't. One by one, we move vertices from set V-U to set U by
connecting the least weight edge.

1. T = ∅;
2. U = { 1 };
3. while (U ≠ V)
4. let (u, v) be the lowest cost edge such that u ∈ U and v ∈ V -
U;
5. T = T ∪ {(u, v)}
6. U = U ∪ {v}

Prim's Algorithm Implementation in C++

The program below implements Prim's algorithm in C++. Although adjacency matrix
representation of graph is used, this algorithm can also be implemented using
Adjacency List to improve its efficiency.

1. #include <iostream>
2. #include <cstring>
3. using namespace std;
4.
5. #define INF 9999999
6.
7. // number of vertices in graph
8. #define V 5
9.
10. // create a 2d array of size 5x5
11. //for adjacency matrix to represent graph
12.
13. int G[V][V] = {
14. {0, 9, 75, 0, 0},
15. {9, 0, 95, 19, 42},
16. {75, 95, 0, 51, 66},
17. {0, 19, 51, 0, 31},
18. {0, 42, 66, 31, 0}
19. };
20.
21. int main () {
22.
23. int no_edge; // number of edge
24.
25. // create a array to track selected vertex

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

26. // selected will become true otherwise false


27. int selected[V];
28.
29. // set selected false initially
30. memset (selected, false, sizeof (selected));
31.
32. // set number of edge to 0
33. no_edge = 0;
34.
35. // the number of edge in minimum spanning tree will be
36. // always less than (V -1), where V is the number of vertices in
37. //graph
38.
39. // choose 0th vertex and make it true
40. selected[0] = true;
41.
42. int x; // row number
43. int y; // col number
44.
45. // print for edge and weight
46. cout << "Edge" << " : " << "Weight";
47. cout << endl;
48. while (no_edge < V - 1) {
49.
50. //For every vertex in the set S, find the all adjacent vertices
51. // , calculate the distance from the vertex selected at step 1.
52. // if the vertex is already in the set S, discard it otherwise
53. //choose another vertex nearest to selected vertex at step 1.
54.
55. int min = INF;
56. x = 0;
57. y = 0;
58.
59. for (int i = 0; i < V; i++) {
60. if (selected[i]) {
61. for (int j = 0; j < V; j++) {
62. if (!selected[j] && G[i][j]) { // not in selected and
there is an edge
63. if (min > G[i][j]) {
64. min = G[i][j];
65. x = i;
66. y = j;
67. }
68.
69. }
70. }
71. }
72. }
73. cout << x << " - " << y << " : " << G[x][y];

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

74. cout << endl;


75. selected[y] = true;
76. no_edge++;
77. }
78.
79. return 0;
80. }

On running the above code, we get the output as:

Edge : Weight
0 - 1 : 9
1 - 3 : 19
3 - 4 : 31
3 - 2 : 51

Prim's vs Kruskal's Algorithm

Kruskal's algorithm is another popular minimum spanning tree algorithm that uses a
different logic to find the MST of a graph. Instead of starting from a vertex, Kruskal's
algorithm sorts all the edges from low weight to high and keeps adding the lowest
edges, ignoring those edges that create a cycle.

6.3.2 Kruskal's Algorithm

Kruskal's algorithm is a minimum spanning tree algorithm that takes a graph as input
and finds the subset of the edges of that graph which

● form a tree that includes every vertex


● has the minimum sum of weights among all the trees that can be formed from
the graph

How Kruskal's algorithm works

It falls under a class of algorithms called greedy algorithms which find the local
optimum in the hopes of finding a global optimum.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

We start from the edges with the lowest weight and keep adding edges until we
reach our goal.

The steps for implementing Kruskal's algorithm are as follows:

1. Sort all the edges from low weight to high


2. Take the edge with the lowest weight and add it to the spanning tree. If adding
the edge created a cycle, then reject this edge.
3. Keep adding edges until we reach all vertices.

Example of Kruskal's algorithm

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Kruskal Algorithm Pseudocode

Any minimum spanning tree algorithm revolves around checking if adding an edge
creates a loop or not.

The most common way to find this out is an algorithm called Union FInd. The
Union-Find algorithm divides the vertices into clusters and allows us to check if two
vertices belong to the same cluster or not and hence decide whether adding an edge
creates a cycle.

1. KRUSKAL(G):
2. A = ∅
3. For each vertex v ∈ G.V:
4. MAKE-SET(v)
5. For each edge (u, v) ∈ G.E ordered by increasing order by weight(u,
v):
6. if FIND-SET(u) ≠ FIND-SET(v):
7. A = A ∪ {(u, v)}
8. UNION(u, v)
9. return A

Kruskal's Algorithm Implementation in C++

Here is the code for C++ implementation in C++. We use standard template libraries
to make our work easier and code cleaner.

1. #include <iostream>
2. #include <vector>
3. #include <algorithm>
4. using namespace std;
5.
6. #define edge pair<int,int>
7.
8. class Graph {
9. private:
10. vector<pair<int, edge>> G; // graph
11. vector<pair<int, edge>> T; // mst
12. int *parent;
13. int V; // number of vertices/nodes in graph
14. public:
15. Graph(int V);
16. void AddWeightedEdge(int u, int v, int w);
17. int find_set(int i);
18. void union_set(int u, int v);
19. void kruskal();

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

20. void print();


21. };
22. Graph::Graph(int V) {
23. parent = new int[V];
24.
25. //i 0 1 2 3 4 5
26. //parent[i] 0 1 2 3 4 5
27. for (int i = 0; i < V; i++)
28. parent[i] = i;
29.
30. G.clear();
31. T.clear();
32. }
33. void Graph::AddWeightedEdge(int u, int v, int w) {
34. G.push_back(make_pair(w, edge(u, v)));
35. }
36. int Graph::find_set(int i) {
37. // If i is the parent of itself
38. if (i == parent[i])
39. return i;
40. else
41. // Else if i is not the parent of itself
42. // Then i is not the representative of his set,
43. // so we recursively call Find on its parent
44. return find_set(parent[i]);
45. }
46.
47. void Graph::union_set(int u, int v) {
48. parent[u] = parent[v];
49. }
50. void Graph::kruskal() {
51. int i, uRep, vRep;
52. sort(G.begin(), G.end()); // increasing weight
53. for (i = 0; i < G.size(); i++) {
54. uRep = find_set(G[i].second.first);
55. vRep = find_set(G[i].second.second);
56. if (uRep != vRep) {
57. T.push_back(G[i]); // add to tree
58. union_set(uRep, vRep);
59. }
60. }
61. }
62. void Graph::print() {
63. cout << "Edge :" << " Weight" << endl;
64. for (int i = 0; i < T.size(); i++) {
65. cout << T[i].second.first << " - " << T[i].second.second << "
: "
66. << T[i].first;
67. cout << endl;
Available by :- Crystal Dias-2019 batch | 3A-CSE
Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

68. }
69. }
70. int main() {
71. Graph g(6);
72. g.AddWeightedEdge(0, 1, 4);
73. g.AddWeightedEdge(0, 2, 4);
74. g.AddWeightedEdge(1, 2, 2);
75. g.AddWeightedEdge(1, 0, 4);
76. g.AddWeightedEdge(2, 0, 4);
77. g.AddWeightedEdge(2, 1, 2);
78. g.AddWeightedEdge(2, 3, 3);
79. g.AddWeightedEdge(2, 5, 2);
80. g.AddWeightedEdge(2, 4, 4);
81. g.AddWeightedEdge(3, 2, 3);
82. g.AddWeightedEdge(3, 4, 3);
83. g.AddWeightedEdge(4, 2, 4);
84. g.AddWeightedEdge(4, 3, 3);
85. g.AddWeightedEdge(5, 2, 2);
86. g.AddWeightedEdge(5, 4, 3);
87. g.kruskal();
88. g.print();
89. return 0;
90. }

When we run the program, we get output as

Edge : Weight
1 - 2 : 2
2 - 5 : 2
2 - 3 : 3
3 - 4 : 3
0 - 1 : 4

Kruskal's vs Prim's Algorithm

Prim's algorithm is another popular minimum spanning tree algorithm that uses a
different logic to find the MST of a graph. Instead of starting from an edge, Prim's
algorithm starts from a vertex and keeps adding lowest-weight edges which aren't in
the tree, until all vertices have been covered.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

7. Sorting and Searching


7.1 Sorting

7.1.1 Quick Sort


Source:- https://www.geeksforgeeks.org/quick-sort/

Like Merge Sort, QuickSort is a Divide and Conquer algorithm. It picks an element as

pivot and partitions the given array around the picked pivot. There are many different

versions of quickSort that pick pivot in different ways.

1. Always pick first element as pivot.


2. Always pick last element as pivot (implemented below)
3. Pick a random element as pivot.
4. Pick median as pivot.

The key process in quickSort is partition(). Target of partitions is, given an array and
an element x of array as pivot, put x at its correct position in sorted array and put all
smaller elements (smaller than x) before x, and put all greater elements (greater than
x) after x. All this should be done in linear time.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Pseudo Code for recursive QuickSort function :

/* low --> Starting index, high --> Ending index */


quickSort(arr[], low, high)
{
if (low < high)
{
/* pi is partitioning index, arr[pi] is now
at right place */
pi = partition(arr, low, high);

quickSort(arr, low, pi - 1); // Before pi


quickSort(arr, pi + 1, high); // After pi
}
}

Partition Algorithm

There can be many ways to do partition, following pseudo code adopts the method

given in CLRS book. The logic is simple, we start from the leftmost element and keep

track of index of smaller (or equal to) elements as i. While traversing, if we find a

smaller element, we swap current element with arr[i]. Otherwise we ignore current

element.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

/* low --> Starting index, high --> Ending index */


quickSort(arr[], low, high)
{
if (low < high)
{
/* pi is partitioning index, arr[pi] is now at right place */
pi = partition(arr, low, high);

quickSort(arr, low, pi - 1); // Before pi


quickSort(arr, pi + 1, high); // After pi
}
}

Pseudo code for partition()

/* This function takes last element as pivot, places the pivot


element at its correct position in sorted array, and places all
smaller (smaller than pivot) to the left of pivot and all greater
elements to right of pivot */

partition (arr[], low, high)


{
// pivot (Element to be placed at right position)
pivot = arr[high];

i = (low - 1) // Index of smaller element

for (j = low; j <= high- 1; j++)


{
// If current element is smaller than the pivot
if (arr[j] < pivot)
{
i++; // increment index of smaller element
swap arr[i] and arr[j]
}
}
swap arr[i + 1] and arr[high])
return (i + 1)
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

Illustration of partition() :

arr[] = {10, 80, 30, 90, 40, 50, 70}


Indexes: 0 1 2 3 4 5 6

low = 0, high = 6, pivot = arr[h] = 70


Initialize index of smaller element, i = -1

Traverse elements from j = low to high-1


j = 0 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])
i = 0
arr[] = {10, 80, 30, 90, 40, 50, 70} // No change as i and j
// are same

j = 1 : Since arr[j] > pivot, do nothing


// No change in i and arr[]

j = 2 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])


i = 1
arr[] = {10, 30, 80, 90, 40, 50, 70} // We swap 80 and 30

j = 3 : Since arr[j] > pivot, do nothing


// No change in i and arr[]

j = 4 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])


i = 2
arr[] = {10, 30, 40, 90, 80, 50, 70} // 80 and 40 Swapped
j = 5 : Since arr[j] <= pivot, do i++ and swap arr[i] with arr[j]
i = 3
arr[] = {10, 30, 40, 50, 80, 90, 70} // 90 and 50 Swapped

We come out of loop because j is now equal to high-1.


Finally we place pivot at correct position by swapping
arr[i+1] and arr[high] (or pivot)
arr[] = {10, 30, 40, 50, 70, 90, 80} // 80 and 70 Swapped

Now 70 is at its correct place. All elements smaller than


70 are before it and all elements greater than 70 are after
It.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

7.1.2 Merge sort

Like QuickSort, Merge Sort is a Divide and Conquer algorithm. It divides input array in

two halves, calls itself for the two halves and then merges the two sorted halves. The

merge() function is used for merging two halves. The merge(arr, l, m, r) is a key

process that assumes that arr[l..m] and arr[m+1..r] are sorted and merges the two

sorted subarrays into one. See following C implementation for details.

MergeSort(arr[], l, r)
If r > l
1. Find the middle point to divide the array into two halves:
middle m = (l+r)/2
2. Call mergeSort for first half:
Call mergeSort(arr, l, m)
3. Call mergeSort for second half:
Call mergeSort(arr, m+1, r)
4. Merge the two halves sorted in step 2 and 3:
Call merge(arr, l, m, r)
The following diagram from wikipedia shows the complete merge sort process for

an example array {38, 27, 43, 3, 9, 82, 10}. If we take a closer look at the diagram, we

can see that the array is recursively divided into two halves till the size becomes 1.

Once the size becomes 1, the merge processes comes into action and starts

merging arrays back till the complete array is merged.

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

void mergeSort(int arr[], int l, int r)


{
if (l < r)
{ // Same as (l+r)/2, but avoids overflow for
// large l and h
int m = l+(r-l)/2;

// Sort first and second halves


mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

void merge(int arr[], int l, int m, int r)


{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;

/* create temp arrays */


int L[n1], R[n2];

/* Copy data to temp arrays L[] and R[] */


for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1+ j];

/* Merge the temp arrays back into arr[l..r]*/


i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray
k = l; // Initial index of merged subarray
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}

/* Copy the remaining elements of L[], if there are any */


while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

/* Copy the remaining elements of R[], if there are any */


while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}

/* l is for left index and r is right index of the


sub-array of arr to be sorted */

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

8. The C++ Standard Template Library


(STL)
Source:- https://www.geeksforgeeks.org/the-c-standard-template-library-stl/

The Standard Template Library (STL) is a set of C++ template classes to provide

common programming data structures and functions such as lists, stacks, arrays,

etc. It is a library of container classes, algorithms, and iterators. It is a generalized

library and so, its components are parameterized. A working knowledge of template

classes is a prerequisite for working with STL.

STL has four components

● Algorithms
● Containers
● Functions
● Iterators

Algorithms

The header algorithm defines a collection of functions especially designed to be


used on ranges of elements.They act on containers and provide means for various
operations for the contents of the containers.
● Algorithm
○ Sorting
○ Searching
○ Important STL Algorithms
○ Useful Array algorithms
○ Partition Operations
● Numeric

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

○ valarray class

Containers

Containers or container classes store objects and data. There are in total seven

standard “first-class” container classes and three container adaptor classes and only

seven header files that provide access to these containers or container adaptors.

● Sequence Containers: implement data structures which can be accessed


in a sequential manner.
○ vector
○ list
○ deque
○ arrays
○ forward_list( Introduced in C++11)
● Container Adaptors : provide a different interface for sequential
containers.
○ queue
○ priority_queue
○ stack
● Associative Containers : implement sorted data structures that can be
quickly searched (O(log n) complexity).
○ set
○ multiset
○ map
○ multimap
● Unordered Associative Containers : implement unordered data structures
that can be quickly searched
○ unordered_set (Introduced in C++11)
○ unordered_multiset (Introduced in C++11)
○ unordered_map (Introduced in C++11)

Available by :- Crystal Dias-2019 batch | 3A-CSE


Data Structures Class Notes by Mahesh Jangid | Faculty of CSE

○ unordered_multimap (Introduced in C++11)

Functions

The STL includes classes that overload the function call operator. Instances of such

classes are called function objects or functors. Functors allow the working of the

associated function to be customized with the help of parameters to be passed.

● Functors

Iterators

As the name suggests, iterators are used for working upon a sequence of values.

They are the major feature that allow generality in STL.

● Iterators

Utility Library

Defined under <utility header>

● pair

Available by :- Crystal Dias-2019 batch | 3A-CSE

You might also like