0% found this document useful (0 votes)
20 views94 pages

Technical Skills II Manual

The syllabus covers various data structures and algorithms, including arrays, linear and non-linear data structures, searching and sorting techniques, and hashing functions. It includes practical laboratory exercises for implementing these concepts using Python. The course aims to equip students with the skills to understand and apply these data structures and algorithms effectively.

Uploaded by

anitha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views94 pages

Technical Skills II Manual

The syllabus covers various data structures and algorithms, including arrays, linear and non-linear data structures, searching and sorting techniques, and hashing functions. It includes practical laboratory exercises for implementing these concepts using Python. The course aims to equip students with the skills to understand and apply these data structures and algorithms effectively.

Uploaded by

anitha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 94

SYLLABUS

MODULE 1
ARRAYS
Basic operations on arrays: Traversal-insertion-deletion-search-update, Array types:
One dimensional Array-Two dimensional array.

MODULE 2
LINEAR DATA STRUCTURES
List ADT: Creating a list, Types of List-Singly linked list & operations, Doubly linked
list & operations, Circularly linked list & operations, Queue ADT-Queue using list &
operations-Queue using linked list, Stack ADT- Stack using list &operations- -Stack
using linked list-Applications of Stack-Postfix and Infix operations.

MODULE 3
NON-LINEAR DATA STRUCTURES
Trees: Binary tree traversal – In Order-Pre Order-Post Order, B-Tree, Binary heaps,
Graphs-Graph Traversal Algorithms-Breadth First Search-Depth First Search-
Topological Sorting, Shortest path algorithms-Dijikstra Algorithm-Bellman Ford
algorithm, Minimum Spanning Tree-Kruskal Algorithm-Prim’s Algorithm, All pair
shortest path – Floyd’s Algorithm.

MODULE 4
SEARCHING TECHNIQUES
Linear Search, Binary Search: Recursive Binary Search-Iterative Binary Search.

MODULE 5
SORTING TECHNIQUES AND HASHING FUCTIONS
Sorting algorithms: Bubble sort -Insertion Sort-Selection Sort-Quick Sort-Merge Sort-
Radix Sort-Bucket Sort-Heap Sort-Shell Sort- Hashing-Hash Table using Open
Addressing.
TECHNICAL SKILLS II LABORATORY

COURSE OBJECTIVES:
The course should enable the students to:
I. To understand the concepts of Arrays, ListADT.
II. To learn linear data structures–stacks and queues ADTs.
III. To understand and apply Tree data structures.
IV. To analyze sorting and searching algorithms.
V. To understand and apply Graph structures and hashing techniques.

LIST OF EXPERIMENTS

WEEK-1 ARRAY IMPLEMENTATION


1. Write Python programs for implementing the following operations in arrays.
i. Creation ii. insertion iii. deletion iv. traversal
2. Write Python programs for implementing
a) One dimensional arrays
b) Two dimensional arrays
WEEK-2 LIST ADT
3. Write Python programs for implementing the following operations in list.
i. Creation ii. insertion iii. deletion iv. traversal
4. Write Python programs for implementing
a) Singly linked list.
b) Circularly singly linked list.
c) Doubly linked list
WEEK-3 STACK ADT AND QUEUE ADT
5. Write Python programs for implementing stack and its operations in a list.
6. Write Python programs for implementing queue and its operations in a list.

WEEK-4 APPLICATION OF STACK


Write Python programs to perform following stack operations.
a. Infix expression into postfix expression using stack.
b. Evaluate the postfix expression using stack.
WEEK-5 TREES
Write Python programs for the following:
a. Create a binary search tree.
b. Traverse the above binary search tree recursively in pre-order, post-order and in-order.
c. Count the number of nodes in the binary search tree.
d. Implementation of Binary heaps.
WEEK-6 GRAPH TRAVERSAL TECHNIQUES
Write Python programs to implement the following
a. Depth first search.
b. Breadth first search.
c. Topological sorting.
WEEK-7 SHORTEST PATH ALGORITHM
Write Python programs to implement the following
a. Dijikstra’s algorithm
b. Bellman ford algorithm
WEEK-8 MINIMUM SPANNING TREE
Write Python programs to implement the following
a. Prim’s algorithm
b. Kruskal’s algorithm

WEEK-9 SEARCHING TECHNIQUES


Write Python programs to implement the following
a. Linear Search
b. Binary Search
WEEK-10 SORTING TECHNIQUES - I

Write a Python program to implement following sorting operations.


a. Bubble sort
b. Insertion sort
c. Selection sort
d. Radix sort
e. Bucket sort

WEEK-11 SORTING TECHNIQUES - II

Write Python programs for implementing the following sorting operations.


a. Quick sort
b. Merge sort
c. Heap sort
d. Shell sort
WEEK-12 HASHING
Write a Python program to perform the following:
a. Hashing with chaining in python

LIST OF REFERENCE BOOKS:

1. Y Daniel Liang, “Introduction to Programming using Python”, Pearson.


2. Benjamin Baka, David Julian, “Python Data Structures and Algorithms”, Packt Publishers,2017.
3. Rance D. Necaise, “Data Structures and Algorithms using Python”, Wiley Student Edition.
4. Martin Jones, “Python for Complete Beginners”, 2015.
5. Zed A. Shaw, “Learn Python the Hard Way: a very simple introduction to the terrifyingly beautiful
world of computers and code”, 3e, Addison-Wesley, 2014.
6. Hemant Jain, “Problem Solving in Data Structures and Algorithms using Python: programming
interview guide”, 2016.

3
WEB REFERENCES:
1. https://docs.python.org/3/tutorial/datastructures.html
2. http://interactivepython.org/runestone/static/pythonds/index.html
3. http://www.tutorialspoint.com/data_structures_algorithms
4. http://www.geeksforgeeks.org/data-structures/
5. http://www.studytonight.com/data-structures/
6. http://www.coursera.org/specializations/data-structures-algorithms

3
WEEK-1

ARRAYS IN DATA STRUCTURES -

AIM:
To implement the following Array operations.

a. Append()
b. Insert()
c. Pop()
d. Remove()
e. Reverse()

EXERCISE-1
Write a Python program to append an element in an array.
import array
arr = array.array('i', [1, 2, 3])
print ("The new created array is : ",end=" ")
for i in range (0, 3):
print (arr[i], end=" ")
print("\r")
arr.append(4);
print("The appended array is : ", end="")
for i in range (len(arr)):
print (arr[i], end=" ")

Test case-1
The new created array is : 1 2 3
Expected output
The appended array is : 1 2 3 4

EXERCISE-2
Write a Python program to insert an element in an array.
Test case-1
The new created array is : 1 2 3
Expected output-1
The array after insertion is : 1 2 5 3

Test case-2
The new created array is : 1 2 3 4
Expected output-2
The array after insertion is : 1 2 3 4 6
EXERCISE-3
Write a Python program to pop an element in an array.
Test case
The new created array is : 1 2 3 1 5
The popped element is : 3
Expected output
The array after popping is : 1 2 1 5

EXERCISE-4
Write a Python program to remove an element in an array.
Test case
The new created array is : 1 2 3 1 5
Expected output
The array after removing is : 2 3 1 5

EXERCISE-5
Write a Python program to reverse an element in an array.
Test case
The new created array is : 1 2 3 1 2 5
Expected output
The array after reversing is : 5 2 1 3 2 1

RESULT
Thus, the programs were implemented to append, insert, pop, remove and reverse the elements
in the given array.
WEEK-1

ARRAY TYPES-

AIM:

To implement the array types of One dimensional and Two dimensional array in data structures.

EXERCISE-1
Write a program using one dimensional array to update an array after changing an element in
an array and also to find the sum of the elements in the array.
myArray = [10, 20, 30, 40, 50]
print("Elements of the array:")
for i in range(5):
print(myArray[i], end=" ")
print()
myArray[2] = 35
print("Updated array after changing the third element:")
for i in range(5):
print(myArray[i], end=" ")
print()
sum_value = sum(myArray)
print("Sum of the elements:", sum_value)

Test case
Elements of the array:
10 20 30 40 50
Expected output
Updated array after changing the third element:
10 20 35 40 50
Sum of the elements: 155

EXERCISE-2
Write a program to the create and manipulate a 3x4 matrix to print the original matrix, modify
an element, calculate the sum of elements in each row, and transposes the matrix.

def print_array(array):
for row in array:
for element in row:
print(element, end="\t")
print()
rows = 3
columns = 4
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
print("Original Matrix:")
print_array(matrix)
print("\nElement at matrix[1][2]:", matrix[1][2])
matrix[1][2] = 20
print("Modified Matrix:")
print_array(matrix)
for i in range(rows):
row_sum = sum(matrix[i])
print(f"\nSum of elements in Row {i + 1}: {row_sum}")
print("\nTransposed Matrix:")
for i in range(columns):
for j in range(rows):
print(matrix[j][i], end="\t")
print()

Test case-1
Original Matrix:
1 2 3 4
5 6 7 8
9 10 11 12
Expected output-1

Element at matrix[1][2]: 7
Modified Matrix:
1 2 3 4
5 6 20 8
9 10 11 12

Sum of elements in Row 1: 10

Sum of elements in Row 2: 39

Sum of elements in Row 3: 42

Transposed Matrix:
1 5 9
2 6 10
3 20 11
4 8 12

RESULT
Thus, the programs were implemented for the one dimensional and two dimensional arrays with its
operations .
WEEK-2
IMPLEMENTATION OF SINGLE LINKED LIST

AIM

To write Python program to perform the following operations on single linked list.
(i) Creation (ii) insertion (iii) deletion (iv) traversal

Procedure for Single linked list

1. A singly linked list's node is divided into two parts. The first part holds or points to information
about the node, and second part holds the address of next node. A singly linked list travels one
way.
2. The beginning of the linked list is stored in a "start" pointer which points to the first node. The
first node contains a pointer to the second node. The second node contains a pointer to the third
node, ... and so on.
3. The last node in the list has its next field set to NULL to mark the end of the list.
4. The basic operations in a single linked list are: Creation, Insertion, Deletion, Traversing.

SOURCE CODE:

class Node:
def init (self,data):
print("Node created",data)
self.data=data
self.next=None
class S_L_List:
def init (self):
self.head=None
self.ctr=0
def insert_beginning(self,data):
node=Node(data)
if self.head==None:
self.head=node
else:
node.next=self.head
self.head=node
self.ctr+=1
print("Node inserted",data)
return
def insert_middle(self,pos,data):
if pos==0:
self.insert_beginning(data)
elif pos==self.ctr+1:
self.insert_end(data)
else:
node=Node(data)
temp=self.head
i=0
while (i<pos-1):
temp=temp.next
i+=1
node.next=temp.next
temp.next=node
self.ctr+=1
print("Node inserted",data)
return
def insert_end(self,data):
node=Node(data)
node.next=None
if self.head==None:
self.head=node
return
temp=self.head
while (temp.next is not None):
temp=temp.next
temp.next=node
self.ctr+=1
print("Node inserted",data)
return
def delete_beginning(self):
if self.head==None:
print("No nodes exist")
elif self.ctr==1:
print("Node deleted",self.head.data)
self.head=None
self.ctr-=1
else:
print("Node deleted",self.head.data)
self.head=self.head.next
self.ctr-=1
return
def delete_middle(self,pos):
if self.head==None:
print("No nodes exist")
elif pos==0:
self.delete_beginning()
elif pos==self.ctr:
self.delete_end()
else:
temp=self.head
prev=temp
i=0
while (i<pos):
prev=temp
temp=temp.next
i+=1
prev.next=temp.next
print("Node deleted",temp.data)
temp.next=None
self.ctr-=1
return
def delete_end(self):
if self.ctr==0:
print("No Nodes present")
elif self.ctr==1:
self.ctr=0
print("Node deleted",self.head.data)
self.head=None
else:
temp=self.head
prev=self.head
while (temp.next is not None):
prev=temp
temp=temp.next
print("Node deleted",temp.data)
prev.data=None
self.ctr-=1
return
def traverse_forward(self):
if self.head==None:
print("No nodes exist")
print("traversal forward")
temp=self.head
while (temp is not None):
print(temp.data)
temp=temp.next

def menu():
print("1. Insert at beginning")
print("2. Insert at middle")
print("3. Insert at end")
print("4. Delete at beginning")
print("5. Delete at middle")
print("6. Delete at end")
print("7. Traversal forward")
print("8. Count number of nodes")
print("9. Exit")
ch=eval(input("Enter choice:"))
return ch

print("*******SINGLE LINKED LIST***********")


l=S_L_List()
while True:
ch=menu()
if ch==1:
data=eval(input("Enter data:"))
l.insert_beginning(data)
elif ch==2:
data=eval(input("Enter data:"))
pos=eval(input("Enter the position:"))
l.insert_middle(pos,data)
elif ch==3:
data=eval(input("Enter data:"))
l.insert_end(data)
elif ch==4:
l.delete_beginning()
elif ch==5:
pos=eval(input("Enter position:"))
l.delete_middle(pos)
elif ch==6:
l.delete_end()
elif ch==7:
l.traverse_forward()
elif ch==8:
print("Number of nodes",l.ctr)
else:
print("Exit")
break
6.2 INPUT / OUTPUT:
RESULT :
Thus the above programs are implemented and verified.
IMPLEMENTATION OF CIRCULAR SINGLE LINKED LIST

AIM:

To write a python program to implement circular linked


listi)Creation (ii)insertion (iii)deletion (iv)traversal

PROGRAM LOGIC:

1. In Circular single linked list the link field of the last node points back to the address of the first
node.
2. A circular linked list has no beginning and no end. It is necessary to establish a special pointer
called start pointer always pointing to the first node of the list.
3. The basic operations in a circular single linked list is: creation, insertion, deletion and
traversing.

SOURCE CODE:

class Node:
def init (self,data):
self.next=None
self.data=data
print("Node created",data)

class CLList:
def init (self):
self.head=None
self.ctr=0
def insert_beg(self,data):
node=Node(data)
if self.head==None:
self.head=node
node.next=self.head
else:
temp=self.head
while temp.next is not self.head:
temp=temp.next
temp.next=node
node.next=self.head
self.head=node
print("Node inserted",data)
self.ctr+=1
return
def insert_end(self,data):
node=Node(data)
if self.head==None:
self.head=node
node.next=self.head
else:
temp=self.head
while temp.next is not self.head:
temp=temp.next
temp.next=node
node.next=self.head
self.ctr+=1
print("Node inserted",data)
return
def insert_inter(self,pos,data):
node=Node(data)
if pos<1 or pos>self.ctr:
print("invalid position")
else:
temp=self.head
i=1
while i<pos:
temp=temp.next
i+=1
node.next=temp.next
temp.next=node
self.ctr+=1
print("Node Insered",data)
return
def delete_beg(self):
if self.head==None:
print("No Nodes exist")
elif self.ctr==1:
print("Node deleted",self.head.data)
self.head=None
self.ctr-=1
else:
print("Node deleted",self.head.data)
temp=self.head
while temp.next is not self.head:
temp=temp.next
self.head=self.head.next
temp.next=self.head
self.ctr-=1
return
def delete_end(self):
if self.head==None:
print("No Nodes exist")
elif self.ctr==1:
print("Node deleted",self.head.data)
self.head=None
self.ctr-=1
else:
temp=self.head
prev=temp
while temp.next is not self.head:
prev=temp
temp=temp.next
print("Node deleted",temp.data)
prev.next=temp.next
self.ctr-=1
return
def delete_inter(self,pos):
if self.head==None:
print("No nodes exist")
elif pos<1 or pos>self.ctr:
print("Invalid position")
elif self.ctr==1:
print("Node deleted",self.head.data)
self.head=None
self.ctr-=1
else:
temp=self.head
prev=temp
i=0
while i<pos:
prev=temp
temp=temp.next
i+=1
prev.next=temp.next
print("Node deleted",temp.data)
self.ctr-=1
return
def traverse(self):
temp=self.head
i=0
while i<self.ctr:
print(temp.data)
temp=temp.next
i+=1
return

def Menu():
print("1.Insert at beginning")
print("2.Insert at middle")
print("3.Insert at end")
print("4.Delete at beginning")
print("5.Delete at middle")
print("6.Delete at end")
print("7.Traverse Forward")
print("8.Number of nodes")
print("9.Exit")
ch=int(input("Enter choice:"))
return ch

c=CLList()
print("****************Circular Linked List**************")
while True:
ch=Menu()
if ch==1:
data=input("Enter data:")
c.insert_beg(data)
elif ch==2:
data=input("Enter data:")
pos=int(input("Enter position:"))
c.insert_inter(pos,data)
elif ch==3:
data=input("Enter data:")
c.insert_end(data)
elif ch==4:
c.delete_beg()
elif ch==5:
pos=int(input("Enter position:"))
c.delete_inter(pos)
elif ch==6:
c.delete_end()
elif ch==7:
c.traverse()
elif ch==8:
print("Number of Nodes",c.ctr)
else:
print("Exit")
break
Output:
RESULT:

Thus the above programs are implemented and verified.


IMPLEMENTATION OF DOUBLE LINKED LIST

AIM:

a. To create a doubly linked list of integers.


b. To delete a given integer from the above doubly linked list.
c. To display the contents of the above list after deletion

PROGRAM LOGIC:
1. In a doubly-linked list each node of the list contain two references (or links) – one to the previous
node and other to the next node. The previous link of the first node and the next linkof the last
node points to NULL.
2. A double linked list is a two-way list in which all nodes will have two links. This helps in
accessing both successor node and predecessor node from the given node position. It provides
bi-directional traversing.
3. Each node contains three fields: Left link, Data and Right link.
4. The left link points to the predecessor node and the right link points to the successor node. The
data field stores the required data.

5. The basic operations in a double linked list are: creation, insertion, deletion and traversing.
6. The beginning of the double linked list is stored in a "start" pointer which points to the first node.
The first node’s left link and last node’s right link is set to NULL.

SOURCE CODE:

class Node:
def init (self,data):
self.data=data
self.next=self.prev=None
class DLinkedList:
def init (self):
self.head=None
self.ctr=0
def insert_beg(self,data):
node=Node(data)
if self.head==None:
self.head=node
else:
node.next=self.head
self.head.prev=node
self.head=node
self.ctr +=1
print("Nodes inserted",data)
return
def insert_end(self,data):
node=Node(data)
if self.head==None:
self.head=node
else:
temp=self.head
while(temp.next is not None):
temp=temp.next
temp.next=node
node.prev=temp
self.ctr +=1
print("Node inserted",data)
return
def delete_beg(self):
if self.head==None:
print("No node exist")
else:
print("Node deleted",self.head.data)
self.head=self.head.next
self.head.prev=None
self.ctr -=1
return
def delete_end(self):
if self.head==None:
print("No nodes exist")
elif self.ctr==1:
self.ctr=0
print ("Node deleted",self.head.data)
self.head=None
else:
temp=self.head
while temp.next is not None:
temp=temp.next
print("Node deleted",temp.data)
temp=temp.prev
temp.next=None
self.ctr -=1
return
def insert_pos(self,pos,data):
if pos==0:
self.insert_beg(data)
elif pos==self.ctr:
self.insert_end(data)
else:
node=Node(data)
temp=self.head
i=1
while i<pos-1:
temp=temp.next
i +=1
node.next=temp.next
temp.next.prev=node
temp.next=node
node.prev=temp
self.ctr +=1
print("Node inserted",data)
return
def delete_pos(self,pos):
if self.head==None:
print("Node is empty")
else:
if pos==0:
self.delete_beg()
elif pos==self.ctr:
self.delete_end()
else:
temp=self.head
i=0
while i<pos:
temp=temp.next
i+=1
print("node deleted",temp.data)
temp.prev.next=temp.next
temp.next.prev=temp.prev
temp.next=None
temp.preve=None
self.ctr -=1
return
def traverse_f(self):
if self.head==None:
print("No nodes exist")
temp=self.head
i=0
while i<self.ctr:
print(temp.data)
temp=temp.next
i+=1
return
def traverse_r(self):
if self.head==None:
print("No nodes exist")
temp=self.head
while temp.next is not None:
temp=temp.next
while temp is not None:
print(temp.data)
temp=temp.prev
def menu():
print("1.Insert at beginning")
print("2.Insert at position")
print("3.Insert at end")
print("4.Delete at beginning")
print("5.Delete at position")
print("6.Delete at end")
print("7.Count no of nodes")
print("8.Traverse forward")
print("9.Traverse reverse")
print("10.Quit")
ch=eval(input("Enter choice:"))
return ch

print("******************Double linked list**************")


d=DLinkedList()
while True :
ch=menu()
if ch==1:
data=eval(input("Enter data:"))
d.insert_beg(data)
elif ch==2:
data=eval(input("Enter data:"))
pos=int(input("Enter position:"))
d.insert_pos(pos,data)
elif ch==3:
data=eval(input("Enter data:"))
d.insert_end(data)
elif ch==4:
d.delete_beg()
elif ch==5:
pos=int(input("Enter position:"))
d.delete_pos(pos)
elif ch==6:
d.delete_end()
elif ch==7:
print("Number of nodes",d.ctr)
elif ch==8:
d.traverse_f()
elif ch==9:
d.traverse_r()
else:
print("Exit")
break
Output:
RESULT:

Thus the above programs are implemented and verified.


WEEK- 3

IMPLEMENTATION OF STACK AND QUEUE


AIM:

a. To write a Python program to implement Stack and its operations using list.
b. To write a Python program to implement Queue and its operations using list.
Procedure for Stack using List

1. STACK: Stack is a linear data structure which works under the principle of last in first out.
Basic operations: push, pop, display.
2. PUSH: if (top==MAX), display Stack overflow. Otherwise reading the data and making stack
[top] =data and incrementing the top value by doing top++.
3. Pop: if (top==0), display Stack underflow. Otherwise printing the element at the top of the
stack and decrementing the top value by doing the top.
4. DISPLAY: If (top==0), display Stack is empty. Otherwise printing the elements in the stack
from stack [0] to stack [top].

Procedure for Queue using List

1. QUEUE: Queue is a linear data structure which works under the principle of first in first out.
Basic operations: Insertion, deletion, display.
2. Inserion: if (rear==MAX), display Queue is full. Else reading data and inserting at queue [rear],
and doing rear++.
3. Deletion: if (front==rear), display Queue is empty .Else printing element at queue [front] and
doing front++.
4. Display: if (front==rear) ,display No elements in the queue .Else printing the elements from
queue[front] to queue[rear].

Example: Consider a stack with 5 elements capacity. When an element is added to a stack, the
operation is performed by Push().

When an element is taken off from the stack, the operation is performed by Pop().
Program for implementing Stack using list

top=0
mymax=eval(input("Enter Maximum size of stack:"))
def createStack():
stack=[]
return stack
def isEmpty(stack):
return len(stack)==0
def Push(stack,item):
stack.append(item)
print("Pushed to stack",item)
def Pop(stack):
if isEmpty(stack):
return "stack underflow"
return stack.pop()
stack=createStack()
while True:
print("1.Push")
print("2.Pop")
print("3.Display")
print("4.Quit")
ch=int(input("Enter your choice:"))
if ch==1:
if top<mymax:
item=input("Enter any elements:")
Push(stack,item)
top+=1
else:
print("Stack overflow")
elif ch==2:
print(Pop(stack))
elif ch==3:
print(stack)
else:
print("Exit")
break

Output:
Program for implementing Linear Queue using list

front=0
rear=0
mymax=eval(input("Enter maximum size of queue:"))
def createQueue():
queue=[]
return queue
def isEmpty(queue):
return len(queue)==0
def enqueue(queue,item):
queue.append(item)
print("Enqueued to queue",item)
def dequeue(queue):
if isEmpty(queue):
return "Queue is empty"
item=queue[0]
del queue[0]
return item
queue=createQueue()
while True:
print("1.Enqueue")
print("2.Dequeue")
print("3.Display")
print("4.Quit")
ch=int(input("Enter your choice:"))
if ch==1:
if rear<mymax:
item=input("Enter any elements:")
enqueue(queue,item)
rear+=1
else:
print("Queue is full")
elif ch==2:
print(dequeue(queue))
elif ch==3:
print(queue)
else:
print("Exit")
break

Output:
RESULT:
Thus the above program to implement stack and queue are executed and verified.
WEEK-3
IMPLEMENTATION OF STACK USING LINKED LIST

OBJECTIVE:
To write a Python script to implement stack using linked list.

PROGRAM LOGIC:

1. STACK: Stack is a linear data structure which works under the principle of last in first out.
Basic operations: push, pop, display.
2. PUSH: if (newnode==NULL), display Stack overflow. if(start == NULL) then start = newnode.
Otherwise use loop and copy address of new node in to old node by creating link.
3. Pop: if (top == NULL), display Stack underflow. Otherwise printing the element at the top of
the stack and decrementing the top value by doing the top.
4. DISPLAY: if (top == NULL), display Stack is empty. Otherwise printing the elements in the
stack from top.

SOURCE CODE:class

Node:
def init (self,data):
self.data=data
self.next=None

class Stack:
def init (self):
self.head=None
self.ctr=0
self.top=None
def Push(self,data):
node=Node(data)
if self.head==None:
self.head=node
self.top=node
else:
self.top.next=node
self.top=node
print("Node pushed to stack",data)
self.ctr+=1
return
def Pop(self):
if self.head==None:
print("Stack Underflow")
elif self.head==self.top:
print("Deleted from Stack",self.head.data)
self.head=self.top=None
self.ctr-=1
else:
print("Deleted from Stack",self.top.data)
temp=self.head
while temp.next is not self.top:
temp=temp.next
temp.next=None
self.top=temp
self.ctr-=1
return
def Traverse(self):
if self.head==None:
print("No Nodes exist")
return
temp=self.head
while temp is not None:
print(temp.data)
temp=temp.next

def Menu():
print("1.Push\n2.Pop\n3.Traverse\n4.Number of nodes\n5.Exit")
ch=int(input("Enter choice:"))
return ch

s=Stack()
print("**************Stack*****************")
while True:
ch=Menu()
if ch==1:
data=input("Enter data:")
s.Push(data)
elif ch==2:
s.Pop()
elif ch==3:
s.Traverse()
elif ch==4:
print("Number of nodes",s.ctr)
else:
print('Quit')
break

Output:
RESULT:
Thus the above programs are implemented and verified.
WEEK 3
IMPLEMENTATION OF QUEUE USING LINKED LIST

OBJECTIVE:

To write a Python program to implement queue using linked list

PROGRAM LOGIC:

1. QUEUE: Queue is a linear data structure which works under the principle of first in first out.
Basic operations: Insertion, deletion, display.
2. Inserion: if newnode ==NULL, display Queue is full. Else reading data and inserting at queue
rear.
3. Deletion: if (front==NULL), display Queue is empty .Else printing element at queue front
4. Display: if (front==NULL) ,display No elements in the queue .Else printing the elements from
front to rear.

SOURCE CODE:
class Node:
def init (self,data):
self.data=data
self.next=None

class Queue:
def init (self):
self.front=None
self.ctr=0
self.rear=None
def Enqueue(self,data):
node=Node(data)
if self.front==None:
self.front=node
self.rear=node
else:
self.rear.next=node
self.rear=node
print("Node enqueued to queue",data)
self.ctr+=1
return
def Dequeue(self):
if self.front==None:
print("No Nodes exist")
else:
print("Dequeued from queue",self.front.data)
self.front=self.front.next
self.ctr-=1
return
def Traverse(self):
if self.front==None:
print("No Nodes exist")
return
temp=self.front
while temp is not None:
print(temp.data)
temp=temp.next

def Menu():
print("1.Enqueue\n2.Dequeue\n3.Traverse\n4.Number of nodes\n5.Exit")
ch=int(input("Enter choice:"))
return ch

print("*******************Queue*************")
s=Queue()
while True:
ch=Menu()
if ch==1:
data=input("Enter data:")
s.Enqueue(data)
elif ch==2:
s.Dequeue()
elif ch==3:
s.Traverse()
elif ch==4:
print("Number of nodes",s.ctr)
else:
print('Quit')
break
10.1 INPUT/OUTPUT:-
RESULT:

Thus the above programs are implemented and verified.


WEEK-4
APPLICATIONS OF STACK
AIM

a. To write a Python program to convert infix expression into postfix expression using stack.
b. To write a Python program to evaluate the postfix expression using stack.

PROGRAM LOGIC:

Procedure to convert Infix Expression into Postfix Expression

1. Read an infix expression and scan the symbols from left to right.
2. If the symbol is an operand, then write down in the postfix string.
3. If the symbol is a left parenthesis, then push it onto stack.
4. If the symbol is a right parenthesis, then pop the operators from until it find a left parenthesis or
the stack is empty.
5. If the symbol is an operator, then check it's priority with the top most operator in the stack.
6. If the incoming operator is having high priority then the top most operator in the stack, then push
the new operator onto stack, otherwise pop the existing operator and push the new operator.
7. Display the content of the postfix string.

Example: Convert the following expression A + B * C - D / E * H into its equivalent postfix


expression.

Symbol Postfix String Stack Remarks


A A Place A in the postfix string
+ A + Push + onto stack
B A B + Place B in the postfix string
* A B +* Push * onto stack
C A B C +* Place C in the postfix string
- A B C *+ - Pop * and + from stack and push -.
D A B C *+ D - Place D in the postfix string
/ A B C *+ D - / Push / onto stack
E A B C *+ D E - / Place E in the postfix string
* A B C *+ D E / - * Push * onto stack
H A B C *+ D E / H - * Place H in the postfix string
End of A B C *+ D E / H * - The input is now empty, pop the output symbols from
string the stack until it is empty.

Procedure to evaluate a Postfix Expression

1. Read a postfix expression and scan the symbols from left to right.
2. If the symbol is an operand, then push it onto the stack.
3. If the symbol is an operator, the pop the top most two symbols and apply the operator.
4. Then push the result again in to stack.
5. Display the final result which is in stack.
Program to convert Infix Expression Into Postfix Expression
class Stack:
def init (self):
self.items = []

def isEmpty(self):
return self.items == []

def push(self, item):


self.items.append(item)

def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items)-1]

def size(self):
return len(self.items)

def infix_postfix(infixexp):
prec={}
prec["^"]=4
prec["*"]=3
prec["/"]=3
prec["+"]=2
prec["-"]=2
prec["("]=1
opStack=Stack()
postfixList=[]
tokenList=infixexp.split()
for token in tokenList:
if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or \
token in "abcdefghijklmnopqrstuvwxyz" or token in "0123456789":
postfixList.append(token)
elif token == '(':
opStack.push(token)
elif token == ')':
topToken = opStack.pop()
while topToken != '(':
postfixList.append(topToken)
topToken=opStack.pop()
else:
while (not opStack.isEmpty()) and \
(prec[opStack.peek()]>=prec[token]):
postfixList.append(opStack.pop())
opStack.push(token)
while not opStack.isEmpty():
postfixList.append(opStack.pop())
return " ".join(postfixList)

a=infix_postfix('A + B * C - D / E * H')
print("The postfix expression of infix expression A + B * C - D / E * H is \n",a)
Output:

Program for evaluating the postfix expression

class Stack:
def init (self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)

def postfix_eval(s):
s=s.split()
n=len(s)
stack =[]
for i in range(n):
if s[i].isdigit():
#append function is equivalent to push
stack.append(int(s[i]))
elif s[i]=="+":
a=stack.pop()
b=stack.pop()
stack.append(int(a)+int(b))
elif s[i]=="*":
a=stack.pop()
b=stack.pop()
stack.append(int(a)*int(b))
elif s[i]=="/":
a=stack.pop()
b=stack.pop()
stack.append(int(b)/int(a))
elif s[i]=="-":
a=stack.pop()
b=stack.pop()
stack.append(int(b)-int(a))
return stack.pop()

def doMath(op,op1,op2):
if op == "^":
return op1 ^ op2
elif op == "*":
return op1 * op2
elif op == "/":
return op1 / op2
elif op == "//":
return op1 // op2
elif op == "+":
return op1 + op2
else:
return op1 - op2

s=input("enter string:")
val=postfix_eval(s)
print("The value of postfix expression",s,"is",val)
Output:

RESULT:

Thus the above program to implement stack and queue are executed and verified.
WEEK-5

IMPLEMENTATION OF BINARY SEARCH TREE

AIM:

To write a Python program to implement binary search tree creation, traversal and count node.

PROGRAM LOGIC:

1. The left sub tree of a node contains smaller nodes than a root node.
2. The right sub tree of a node contains greater nodes than a root node.
3. Both the left and right sub trees must also be binary search trees.
4. There are three types of tree traversals: Preorder, Postorder, and Inorder.

Pre-order traversal

Algorithm:
1. Visit the root (we will print it when we visit to show the order of visiting)
2. Traverse the left subtree in pre-order
3. Traverse the right subtree in pre-order

In-order traversal
Visit the root node in between the left and right node (in)

Algorithm:
1. Traverse the left subtree in in-order
2. Visit the root (we will print it when we visit to show the order of visiting)
3. Traverse the right subtree in in-order

Post-order traversal
Visit the root node after (post) visiting the left and right subtree.

Algorithm:
1. Traverse the left subtree in in-order
2. Traverse the right subtree in in-order
3. Visit the root (we will print it when we visit to show the order of visiting)

Maximum depth or Height of a tree

Algorithm:
maxDepth()
1. If tree is empty then return 0
2. Else
a. Get the max depth of left subtree recursively i.e., call
maxDepth( tree->left-subtree)
b. Get the max depth of right subtree recursively i.e., call
maxDepth( tree->right-subtree)
c. Get the max of max depths of left and rightsubtrees and add 1
to it for the current node. max_depth = max(max dept of left
subtree,
max depth of right subtree)
+1
(c) Return max_depth

Count number of leaf nodes in a binary tree


A node is a leaf node if both left and right child nodes of it are NULL.

Algorithm
getLeafCount(node)
1) If node is NULL then return 0.
2) Else If left and right child nodes are NULL return 1.
3) Else recursively calculate leaf count of the tree using below formula.
Leaf count of a tree=Leaf count of left sub tree + leaf count of right sub tree

SOURCE CODE:

class Node:

def init (self,info): #constructor of class


self.info = info #information for node
self.left = None #left leef
self.right = None #right leef
self.level = None #level none defined
def str (self):
return str(self.info) #return as string

class searchtree:
def init (self): #constructor of class
self.root = None
def create(self,val): #create binary search tree nodes
if self.root == None:
self.root = Node(val)
else:
current = self.root
while 1:
if val < current.info:
if current.left:
current = current.left
else:
current.left = Node(val)
break;
elif val > current.info:
if current.right:
current = current.right
else:
current.right = Node(val)
break;
else:
break

def bft(self): #Breadth-First Traversal


self.root.level = 0
queue = [self.root]
out = []
current_level = self.root.level
while len(queue) > 0:
current_node = queue.pop(0)
if current_node.level > current_level:
current_level += 1
out.append("\n")
out.append(str(current_node.info) + " ")
if current_node.left:
current_node.left.level = current_level + 1
queue.append(current_node.left)
if current_node.right:
current_node.right.level = current_level + 1
queue.append(current_node.right)
result= "".join(out)
print (result)
def inorder(self,node):
if node is not None:
self.inorder(node.left)
print (node.info)
self.inorder(node.right)
def preorder(self,node):
if node is not None:
print (node.info)
self.preorder(node.left)
self.preorder(node.right)
def postorder(self,node):
if node is not None:
self.postorder(node.left)
self.postorder(node.right)
print (node.info)

tree = searchtree()
arr = [8,3,1,6,4,7,10,14,13]
for i in arr:
tree.create(i)
print ('Breadth-First Traversal')
tree.bft()
print ('Inorder Traversal')
tree.inorder(tree.root)
print ('Preorder Traversal')
tree.preorder(tree.root)
print ('Postorder Traversal')
tree.postorder(tree.root)
Output:

Breadth-First Traversal
8
3 10
1 6 14
4 7 13
Inorder Traversal
1
3
4
6
7
8
10
13
14
Preorder Traversal
8
3
1
6
4
7
10
14
13
Postorder Traversal
1
4
7
6
3
13
14
10
8

Count the number of nodes in the binary search tree.

class BinaryTree:
def init (self, data):
self.data = data
self.left = None
self.right = None
def insert_left(self, new_data):
if self.left == None:
self.left = BinaryTree(new_data)
else:
t = BinaryTree(new_data)
t.left = self.left
self.left = t
def insert_right(self, new_data):
if self.right == None:
self.right = BinaryTree(new_data)
else:
t = BinaryTree(new_data)
t.right = self.right
self.right = t
def get_left(self):
return self.left
def get_right(self):
return self.right
def set_data(self, data):
self.data = data
def get_data(self):
return self.data
def size(my_tree):
if not my_tree:
return 0
return 1 + size(my_tree.get_left()) + size(my_tree.get_right())

a = BinaryTree(1)
a.insert_left(2)
a.insert_right(3)
print(size(a))

Output:
No of nodes: 3

RESULT:
Thus the above programs are implemented and verified.
IMPLEMENTATION OF BINARY HEAPS

AIM:

To write a Python program to implement binary search tree creation, traversal and count node.

PROGRAM LOGIC:

Binary heaps can be of two types:


a. Min heap
b. Max heap
In a Min heap, the value of the root node will be less than that of its child nodes. Hence, the root node
will have the least value in the whole tree.

In a Max heap, the value of the root node will be greater than the values of its child nodes. Hence, the
root node will have the highest value in the whole tree.

The properties must be satisfied by all the sub-trees in the tree.


Identifying if a binary tree is a heap:
The tree has to be a complete binary tree:
All the levels till the second last level have to be filled.
All the child nodes of the second last level must be filled from left to right.
The heap property must be satisfied-min heap or max heap.

1. Heapify:

Given a binary tree, converting it into a heap is called "Heapify". We use the array implementation of the
tree, and we'll convert it into an array representing a heap:

#Min Heap
def heapify(BT, nodes, node):
smallest = node
leftchild = 2 * node + 1
rightchild = 2 * node + 2

if leftchild < nodes and BT[node] > BT[leftchild]:


smallest = leftchild
if rightchild < nodes and BT[smallest] > BT[rightchild]:
smallest = rightchild

if smallest != node:
BT[node], BT[smallest] = BT[smallest], BT[node]
heapify(BT, nodes, smallest)

BinaryTree = [7, 2, 5, 6, 3, 4, 1]
for i in range((len(BinaryTree)//2)-1, -1, -1):
heapify(BinaryTree, len(BinaryTree), i)
print(BinaryTree)
Output:
[1, 2, 4, 6, 3, 7, 5]
As you can observe, the minimum node 1 is kept at the root(index-0) position, satisfying the minheap
property.

2. Inserting a node

Given a node, we need to append the node to the array at the end such that the last node from left to right is
getting filled, and the most important step is to heapify the array after insertion:

def insertion(BT, newnode):


n = len(BT)
n += 1
BT.append(newnode)
for i in range((n//2)-1, -1, -1):
heapify(BT, n, i)

BinaryTree = [2, 4, 6, 3, 7, 5]
for i in range((len(BinaryTree)//2)-1, -1, -1):
heapify(BinaryTree, len(BinaryTree), i)
print(BinaryTree)
insertion(BinaryTree, 1)
print(BinaryTree)
Output:

[2, 3, 4, 6, 7, 5]
[1, 3, 2, 6, 7, 5, 4]
We inserted 1 into the heap. Among all the elements in a heap, 1 is the smallest; according to the minheap's
property, it must be placed at the root(index-0).

3. Deleting elements from a heap

If the node we want to delete from the heap is a leaf node, we can delete it. If it is an internal node, we need
to swap the node with any leaf node and then delete it.

Never forget to heapify the array.


def deletion(BT, ele):
n = len(BT)
for i in range(0, n):
if ele == BT[i]:
break
BT[i], BT[n-1] = BT[n-1], BT[i]
BT.remove(ele)
for i in range((len(BT)//2)-1, -1, -1):
heapify(BT, len(BT), i)

BinaryTree = [7, 2, 5, 6, 3, 4]
for i in range((len(BinaryTree)//2)-1, -1, -1):
heapify(BinaryTree, len(BinaryTree), i)
print(BinaryTree)
insertion(BinaryTree, 1)
print(BinaryTree)
deletion(BinaryTree, 1)
print(BinaryTree)
Output:
[2, 3, 4, 6, 7, 5]
[1, 3, 2, 6, 7, 5, 4]
[2, 3, 4, 6, 7, 5]

4. Get Minimum node/ Maximum node:

In a minheap, the root node will have the minimum value. Hence, we can write a function to find the min
node and return the root(index-0).

In the same way, in a maxheap, the root node will have the maximum value:

def minnode(BT):
return BT[0]
print(minnode([3, 7, 8, 9]))

Output:

RESULT:
Thus the above programs are implemented and verified.
WEEK-6
GRAPH TRAVERSAL TECHNIQUES

AIM:

a. To write a Python program to implement depth first search.


b. To write a Python program to implement breadth first search.

PROGRAM LOGIC:

1. Take the graph as input and find the adjacency list


2. Start at a random vertex and visit all nodes using depth first search (DFS) and then breadth first
search (BFS).
3. Use stack for DFS and queue for BFS.

SOURCE CODE:

Depth First Search Program


import defaultdict

class Graph:

# Constructor
def init (self):

self.graph = defaultdict(list)

def addEdge(self,u,v):
self.graph[u].append(v)

def DFSUtil(self,v,visited):

visited[v]= True
print (v),

for i in self.graph[v]:
if visited[i] == False:
self.DFSUtil(i, visited)

def DFS(self,v):

visited = [False]*(len(self.graph))
self.DFSUtil(v,visited)
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)

print ("Following is DFS from (starting from vertex 2)")


g.DFS(2)

Breadth First Search Program


import defaultdict

class Graph:
def init (self):

self.graph = defaultdict(list)

def addEdge(self,u,v):
self.graph[u].append(v)

def BFS(self, s):

visited = [False]*(len(self.graph))

queue = []

queue.append(s)
visited[s] = True

while queue:

s = queue.pop(0)
print (s)

for i in self.graph[s]:
if visited[i] == False:
queue.append(i)
visited[i] = True

g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
print ("Following is Breadth First Traversal (starting from vertex 2)")
g.BFS(2)

Program to implement Topological sorting

from collections import defaultdict

#Class to represent a graph


class Graph:
def __init__(self,vertices):
self.graph = defaultdict(list) #dictionary containing adjacency List
self.V = vertices #No. of vertices

# function to add an edge to graph


def addEdge(self,u,v):
self.graph[u].append(v)

# A recursive function used by topologicalSort


def topologicalSortUtil(self,v,visited,stack):

# Mark the current node as visited.


visited[v] = True

# Recur for all the vertices adjacent to this vertex


for i in self.graph[v]:
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)

# Push current vertex to stack which stores result


stack.insert(0,v)

# The function to do Topological Sort. It uses recursive


# topologicalSortUtil()
def topologicalSort(self):
# Mark all the vertices as not visited
visited = [False]*self.V
stack =[]

# Call the recursive helper function to store Topological


# Sort starting from all vertices one by one
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)

# Print contents of stack


print (stack)

g= Graph(6)
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);

print ("Following is a Topological Sort of the given graph")


g.topologicalSort()

Output:

Following is a Topological Sort of the given graph


[5, 4, 2, 3, 1, 0]

RESULT:

Thus the above programs are implemented and verified.


WEEK-7

IMPLEMENTATION OF SHORTEST PATH ALGORITHM

AIM:

a. To write a Python program to implement Dijkstra’s Shortest Path Algorithm.


b. To write a Python program to implement Bellman ford Algorithm.

Program To Implement Dijkstra’s Shortest Path Algorithm

class Graph():

def __init__(self, vertices):

self.V = vertices

self.graph = [[0 for column in range(vertices)]

for row in range(vertices)]

def printSolution(self, dist):

print("Vertex \t Distance from Source")

for node in range(self.V):

print(node, "\t\t", dist[node])

def minDistance(self, dist, sptSet):

min = 1e7

for v in range(self.V):

if dist[v] < min and sptSet[v] == False:

min = dist[v]

min_index = v

return min_index

def dijkstra(self, src):

dist = [1e7] * self.V

dist[src] = 0

sptSet = [False] * self.V

for cout in range(self.V):

u = self.minDistance(dist, sptSet)
sptSet[u] = True

for v in range(self.V):

if (self.graph[u][v] > 0 and

sptSet[v] == False and

dist[v] > dist[u] + self.graph[u][v]):

dist[v] = dist[u] + self.graph[u][v]

self.printSolution(dist)

g = Graph(9)

g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],

[4, 0, 8, 0, 0, 0, 0, 11, 0],

[0, 8, 0, 7, 0, 4, 0, 0, 2],

[0, 0, 7, 0, 9, 14, 0, 0, 0],

[0, 0, 0, 9, 0, 10, 0, 0, 0],

[0, 0, 4, 14, 10, 0, 2, 0, 0],

[0, 0, 0, 0, 0, 2, 0, 1, 6],

[8, 11, 0, 0, 0, 0, 1, 0, 7],

[0, 0, 2, 0, 0, 0, 6, 7, 0]

g.dijkstra(0)

Output:

Vertex Distance from Source

0 0

1 4

2 12

3 19

4 21

5 11

6 9

7 8

8 14
Program To Implement Bellman ford Algorithm

def bellman_ford(graph, source):

distances = {vertex: float('inf') for vertex in graph}

distances[source] = 0

for _ in range(len(graph) - 1):

for u in graph:

for v, weight in graph[u].items():

if distances[u] != float('inf') and distances[u] + weight <


distances[v]:

distances[v] = distances[u] + weight

for u in graph:

for v, weight in graph[u].items():

if distances[u] != float('inf') and distances[u] + weight <


distances[v]:

raise ValueError("Graph contains negative weight cycle")

return distances

graph = {

'A': {'B': -1, 'C': 4},

'B': {'C': 3, 'D': 2, 'E': 2},

'C': {},

'D': {'B': 1, 'C': 5},

'E': {'D': -3}

source = 'A'

shortest_distances = bellman_ford(graph, source)

print(shortest_distances)
Output:

{'A': 0, 'B': -1, 'C': 2, 'D': -2, 'E': 1}

RESULT:

Thus the above programs are implemented and verified.


WEEK-8

IMPLEMENTATION OF MINIMUM SPANNING TREE

AIM:

a. To write a Python program to implement Prim’s Algorithm.


b. To write a Python program to implement

PROGRAM TO IMPLEMENT PRIM’S ALGORITHM


class Graph:
def __init__(self, size):
self.adj_matrix = [[0] * size for _ in range(size)]
self.size = size
self.vertex_data = [''] * size

def add_edge(self, u, v, weight):


if 0 <= u < self.size and 0 <= v < self.size:
self.adj_matrix[u][v] = weight
self.adj_matrix[v][u] = weight # For undirected graph

def add_vertex_data(self, vertex, data):


if 0 <= vertex < self.size:
self.vertex_data[vertex] = data

def prims_algorithm(self):
in_mst = [False] * self.size
key_values = [float('inf')] * self.size
parents = [-1] * self.size

key_values[0] = 0 # Starting vertex

print("Edge \tWeight")
for _ in range(self.size):
u = min((v for v in range(self.size) if not in_mst[v]), key=lambda v: key_values[v])

in_mst[u] = True

if parents[u] != -1: # Skip printing for the first vertex since it has no parent
print(f"{self.vertex_data[parents[u]]}-{self.vertex_data[u]} \t{self.adj_matrix[u][parents[u]]}")

for v in range(self.size):
if 0 < self.adj_matrix[u][v] < key_values[v] and not in_mst[v]:
key_values[v] = self.adj_matrix[u][v]
parents[v] = u

g = Graph(8)

g.add_vertex_data(0, 'A')
g.add_vertex_data(1, 'B')
g.add_vertex_data(2, 'C')
g.add_vertex_data(3, 'D')
g.add_vertex_data(4, 'E')
g.add_vertex_data(5, 'F')
g.add_vertex_data(6, 'G')
g.add_vertex_data(7, 'H')

g.add_edge(0, 1, 4) #A-B
g.add_edge(0, 3, 3) #A-D
g.add_edge(1, 2, 3) #B-C
g.add_edge(1, 3, 5) #B-D
g.add_edge(1, 4, 6) #B-E
g.add_edge(2, 4, 4) #C-E
g.add_edge(2, 7, 2) #C-H
g.add_edge(3, 4, 7) #D-E
g.add_edge(3, 5, 4) #D-F
g.add_edge(4, 5, 5) #E-F
g.add_edge(4, 6, 3) #E-G
g.add_edge(5, 6, 7) #F-G
g.add_edge(6, 7, 5) #G-H

print("Prim's Algorithm MST:")


g.prims_algorithm()

output:

RESULT:
Thus the above programs are implemented and verified.
PROGRAM TO IMPLEMENT PRIM’S ALGORITHM

class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.edges = []
self.adjacency_list = {v: [] for v in vertices}

def add_edge(self, u, v, weight):


self.edges.append((u, v, weight))
self.adjacency_list[u].append((v, weight))
self.adjacency_list[v].append((u, weight))

def find_parent(self, parent, i):


if parent[i] == i:
return i
return self.find_parent(parent, parent[i])

def union(self, parent, rank, x, y):


root_x = self.find_parent(parent, x)
root_y = self.find_parent(parent, y)
if rank[root_x] < rank[root_y]:
parent[root_x] = root_y
elif rank[root_x] > rank[root_y]:
parent[root_y] = root_x
else:
parent[root_y] = root_x
rank[root_x] += 1

def kruskal(self):
minimum_spanning_tree = set()
parent = {}
rank = {}
for v in self.vertices:
parent[v] = v
rank[v] = 0
sorted_edges = sorted(self.edges, key=lambda x: x[2])
for edge in sorted_edges:
u, v, weight = edge
root_u = self.find_parent(parent, u)
root_v = self.find_parent(parent, v)
if root_u != root_v:
minimum_spanning_tree.add(edge)
self.union(parent, rank, root_u, root_v)
return minimum_spanning_tree
vertices = [0, 1, 2, 3]
g = Graph(vertices)
g.add_edge(0, 1, 5)
g.add_edge(0, 2, 10)
g.add_edge(0, 3, 3)
g.add_edge(1, 3, 1)
g.add_edge(2, 3, 4)
minimum_spanning_tree = g.kruskal()
print(minimum_spanning_tree)

OUTPUT:

{(1, 3, 1), (2, 3, 4), (0, 3, 3)}

RESULT:
Thus the above programs are implemented and verified.
WEEK- 9

SEARCHING TECHNIQUES

AIM:

To write a Python script to for implementing linear search technique.


To write a Python script to for implementing binary search technique.

Linear Search Algorithm

Algorithm linsrch (a[], x)


{ // a[1:n] is an array of n elements
index := 0; flag := 0;
while (index < n) do
{
if (x = a[index]) then
{ flag := 1; break;
}
index ++;
}
if(flag =1)
write(“Data found “);
else
write(“data not found”);
}

Example: Given a list of n elements and search a given element x in the list using linear search.
a. Start from the leftmost element of list a[] and one by one compare x with each element of
list a[].
b. If x matches with an element, return the index.
c. If x doesn’t match with any of elements, return -1.

Consider a list with 10 elements and search for 9.

a = [56, 3, 249, 518, 7, 26, 94, 651, 23, 9]


Index → 0 1 2 3 4 5 6 7 8 9
Iteration 1 56 3 249 518 7 26 94 651 23 9
Iteration 2 56 3 249 518 7 26 94 651 23 9
Iteration 3 56 3 249 518 7 26 94 651 23 9
Iteration 4 56 3 249 518 7 26 94 651 23 9
Iteration 5 56 3 249 518 7 26 94 651 23 9
Iteration 6 56 3 249 518 7 26 94 651 23 9
Iteration 7 56 3 249 518 7 26 94 651 23 9
Iteration 8 56 3 249 518 7 26 94 651 23 9
Iteration 9 56 3 249 518 7 26 94 651 23 9
Iteration 10 56 3 249 518 7 26 94 651 23 9

Binary Search Algorithm


Algorithm binsrch (a[], n, x)
{ // a[1:n] is an array of n elements
low = 1;
high = n;
while (low < high) do
{
mid = (low + high)/2 ;
if (x < a[mid]) then
high = mid – 1;
else if (x > a[mid]) then
low = mid + 1;
else
return mid;
}
return 0;
}

Example: Given a sorted list of a[] of n elements, search a given element x in list.
a. Search a sorted list by repeatedly dividing the search interval in half. Begin with an interval
covering the whole list.
b. If the search key is less than the item in the middle item, then narrow the interval to the
lower half. Otherwise narrow it to the upper half.
c. Repeat the procedure until the value is found or the interval is empty.

Consider a sorted list a[] with 9 elements and the search key is 31.

0 1 2 3 4 5 6 7 8
11 23 31 33 65 68 71 89 100

Let the search key = 31.


First low = 0, high = 8, mid = (low + high) = 4
a[mid] = 65 is the centre element, but 65 > 31.
So now high = mid - 1= 4 - 1 = 3, low = 0, mid = (0 + 3) / 2 = 1
a[mid] = a[1] = 23, but 23 < 31.
Again low = mid +1 = 1 +1 =2, high = 3, mid = (2 + 3) /2 = 2
a[mid] = a[2] = 31 which is the search key, so the search is successful.

SOURCE CODE:

Implementation of Linear Search

def l_search(a,x,l,n):
if l<n:
if a[l]==x:
print("The element found at",l+1,"position")
else:
l_search(a,x,l+1,n)
else:
print("Element not found")

print("Enter list:")
a=[int(b) for b in input().split()]
x=eval(input("Enter the search element:"))
n=len(a)
l_search(a,x,0,n)

Output:

Implementation of Binary Search

def b_search(a,x,l,n):
if l<=n:
mid=(l+n)//2
if a[mid]==x:
print("The element found at",mid+1,"position")
else:

if a[mid]>x:
b_search(a,x,l,mid-1)
else:

b_search(a,x,mid+1,n)
else:
print("Element not found")print("Enter list:")
a=[int(b) for b in

input().split()]list.sort(a)

print("the sorted list is",a)


x=eval(input("Enter the search element:"))
n=len(a)
b_search(a,x,0,n)

Output:

RESULT:
Thus the above program to implement searching algorithms like linear search and binary search are
executed and verified.
WEEK –10

SORTING TECHNIQUES
AIM:
a. To write Python script for implementing Bubble sort techniques to arrange a list of integers
inascending order.
b. To write Python script for implementing insertion sort techniques to arrange a list of integers in
ascending order.
c. To write Python script for implementing selection sort techniques to arrange a list of integers
inascending order.
d. To write Python script for implementing Radix sort techniques to arrange a list of integers in
ascending order.
e. To write Python script for implementing Bucket sort techniques to arrange a list of integers
inascending order

PROGRAM LOGIC:

Bubble Sort Algorithm

Algorithm bubblesort ( x[], n)


{ // x[1:n] is an array of n elements
for i := 0 to n do
{ for j := 0 to n–i-1 d0
{ if (x[j] > x[j+1])
{
temp = x[j];
x[j] = x[j+1];
x[j+1] = temp;
}
} }
}

Example: Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the
adjacent elements if they are not in order.

First Pass
5 1 4 2 8 Compare the first two elements, and swaps since 5 > 1
1 5 4 2 8 Compare 5 and 4 and swap since 5 > 4
1 4 5 2 8 Compare 5 and 2 and swap since 5 > 2
1 4 2 5 8 Compare 5 and 8 and since 5 < 8, no swap.
Second Pass
1 4 2 5 8 Compare the first two elements, and as 1 < 4, no
swap.
1 4 2 5 8 Compare 4 and 2, swap since 4 > 2
1 2 4 5 8 Compare 4 and 5, no swap.
1 2 4 5 8 Compare 5 and 8 and no swap.
Third Pass
1 2 4 5 8 Compare the first two elements and no swap.
1 2 4 5 8 Compare 2 and 4, no swap.
1 2 4 5 8 Compare 4 and 5, no swap.
1 2 4 5 8 Compare 5 and 8, no swap.
Fourth Pass
1 2 4 5 8 Compare the first two elements and no swap.
1 2 4 5 8 Compare 2 and 4, no swap.
1 2 4 5 8 Compare 4 and 5, no swap.
1 2 4 5 8 Compare 5 and 8, no swap.

Insertion Sort Algorithm

Algorithm insertionsort (a, n)


{//sort the array a[1:n] in ascending order
for j:=2 to n do
{
item:=a[j];
i=j-1;
while((i>1) and (item< a[i])) do
{
a[i+1]:=a[i];
i:=i-1;
}
a[i+1]:=item;
}
}

Example: This is an in-place comparison-based sorting algorithm. Here, a sub-list is maintained which is
always sorted. An element which is to be inserted in this sorted sub-list, has to find its appropriate place and
then it has to be inserted. Consider an unsorted list with 8 elements.

14 33 27 10 35 19 42 44 Compares the first two elements 14 and 33 and


these element are already in ascending order. Now
14 is in sorted sub-list.
14 33 27 10 35 19 42 44 Compare 33 with 27 and 33 is not in correct
position. So swap 33 with 27.
14 27 33 10 35 19 42 44 Now we have 14 and 27 in the sorted sub-list.
14 27 33 10 35 19 42 44 Next compare 33 with 10.
10 14 27 33 35 19 42 44 Compare 27 with 10 and 14 with 10. Insert 10 in
the proper place.
10 14 27 33 35 19 42 44 Compare 33 and 35, no swap.
10 14 27 33 35 19 42 44 Compare 35 with 19
10 14 27 33 35 19 42 44 Compare 33 with 19, 27 with 19,
10 14 19 27 33 35 42 44 Compare 35 with 42, no swap.
10 14 19 27 33 35 42 44 Compare 42 with 44, no swap.

Selection Sort Algorithm


Algorithm selectionSort ( low, high )
{ //a[low : high] is an array of size n
i=0, j=0, temp=0, ;
for i: =low to high do
{
minindex = i;
for j: =i+1 to high do
{
if( a[j] < a[minindex] ) then
minindex := j; }temp := a[i];
a[i] := a[minindex];
a[minindex] := temp;
}
}
Example: The selection sort algorithm sorts an array by repeatedly finding the minimum element
(considering ascending order) from unsorted part and putting it at the beginning. In every iteration of selection
sort, the minimum element from the unsorted sub-array is picked and moved to the sorted sub- array.

Consider a list a = [64, 25, 12, 22, 11]

Index 0 1 2 3 4 Remarks
List 64 25 12 22 11 Find the minimum element in a[0 .. 4] and place it
at beginning.
Iteration 1 11 25 12 22 64 Find the minimum element in a[1 .. 4] and place it
at beginning of a[1 .. 4]
Iteration 2 11 12 25 22 64 Find the minimum element in a[2 .. 4] and place it
at beginning of a[2 .. 4]
Iteration 3 11 12 22 25 64 Find the minimum element in a[3 .. 4] and place it
at beginning of a[3 .. 4]
Iteration 4 11 12 22 25 64 Finally the list is sorted.

Program for implementing Bubble Sort

def b_sort(a):
n = len(a)
for i in range(n):
for j in range(0, n-i-1):
if a[j] > a[j+1] :
a[j], a[j+1] = a[j+1], a[j]

print("Enter elements into list:")


a=[int(x) for x in input().split()]
b_sort(a)
print("The sorted list is ",a)
Output:

Program for implementing Insertion Sort

def i_sort(a):
for i in range(1,len(a)):
temp=a[i]
pos=i
while pos>0 and a[pos-1]>temp:
a[pos]=a[pos-1]
pos-=1
a[pos]=temp

print("Enter elements into list:")


a=[int(x) for x in input().split()]
i_sort(a)
print("The sorted list is",a)
Output:

Program for implementing Selection Sort

def s_sort(a):
for i in range(len(a)):
least=i
for k in range(i+1,len(a)):
if a[k]<a[least]:
least=k
swap(a,least,i)
def swap(a,least,i):
temp=a[least]
a[least]=a[i]
a[i]=temp

print("Enter elements into list:")


a=[int(x) for x in input().split()]
s_sort(a)
print("The sorted list is",a)
Output:

Program for implementing Radix Sort

def countingSort(arr, exp1):

n = len(arr)

output = [0] * (n)

count = [0] * (10)

for i in range(0, n):


index = (arr[i]/exp1)
count[int((index)%10)] += 1

for i in range(1,10):
count[i] += count[i-1]

i = n-1
while i>=0:
index = (arr[i]/exp1)
output[ count[ int((index)%10) ] - 1] = arr[i]
count[int((index)%10)] -= 1
i -= 1
i=0
for i in range(0,len(arr)):
arr[i] = output[i]
def radixSort(arr):
max1 = max(arr)
exp = 1
while max1 // exp > 0:
countingSort(arr,exp)
exp *= 10
arr = [ 170, 45, 75, 90, 802, 24, 2, 66]
radixSort(arr)

for i in range(len(arr)):
print(arr[i],end=" ")

Output
2 24 45 66 75 90 170 802

Bucket Sort Algorithm


bucketSort()
create N buckets each of which can hold a range of values
for all the buckets
initialize each bucket with 0 values
for all the buckets
put elements into buckets matching the range
for all the buckets
sort elements in each bucket
gather elements from each bucket
end bucketSort

Program for implementing Bucket Sort

def bucketSort(array):
bucket = []
for i in range(len(array)):
bucket.append([])
for j in array:
index_b = int(10 * j)
bucket[index_b].append(j)
for i in range(len(array)):
bucket[i] = sorted(bucket[i])
k=0
for i in range(len(array)):
for j in range(len(bucket[i])):
array[k] = bucket[i][j]
k += 1
return array
array = [.42, .32, .33, .52, .37, .47, .51]
print("Sorted Array in descending order is")
print(bucketSort(array))
Output:
Sorted Array in descending order is
[0.32, 0.33, 0.37, 0.42, 0.47, 0.51, 0.52]

RESULT:
Thus the above program to implement sorting algorithms are executed and verified.
WEEK- 11

SORTING TECHNIQUES
AIM:
1. To write Python programs for implementing Quick sort technique to arrange a list of integers
inascending order.
2. To write Python programs for implementing merge sort technique to arrange a list of integers
inascending order.
3. To write Python programs for implementing heap sort technique to arrange a list of integers in
ascending order.
4. To write Python programs for implementing shell sort technique to arrange a list of integers in
ascending order.

Algorithm for Quick Sort

Algorithm QuickSort (p, q)


// sorts the elements a[p],…….,a[q] which resides in the global array a[1 : n] into ascending order.
// a[n+1] is considered to be defined and must be >= all the elements in a[1 : n].
{
if (p<q) then // if there are more than one element
{
//divide p into two sub-problems
j := partition(a, p, q+1);
// j is the position of the partitioning element.
//solve the sub-problems.
QuickSort (p, j-1);
QuickSort (j+1, q);
}
}

Algorithm Partition(a, m, p)
// within a[m], a[m+1], ………, a[p-1] the elements are rearranged in such a manner that if initially
// t = a[m], then after completion a[q] = t for some q between m and p-1, a[k] <= t for m<=k<=q,
// and a[k]>=t for q<k<p. q is returned, set a[p] = ∞
{
v := a[m]; i:=m; j:=p;
repeat
{
repeat
i:= i+1;
until (a[i] >=v);
repeat
j:=j-1
until (a[j]<=v);
if( i<j) then interchange(a, i, j);
}until(i>=j);
a[m]:= a[j]; a[j]=v; return j;
}
Algorithm Interchange(a, i, j)
//exchange a[i] and a[j]
{
p:=a[i];
a[i]:=a[j];
a[j]:=p;
}

Example: Quick sort is a divide and conquer algorithm. Quick sort first divides a large list into two smaller
sub-lists: the low elements and the high elements. Quick sort can then recursively sort the sub-lists.

The steps are:


1. Pick an element, called a pivot, from the list.
2. Reorder the list so that all elements with values less than the pivot come before the pivot, while all
elements with values greater than the pivot come after it. After this partitioning, the pivot is in its final
position. This is called the partition operation.
3. Recursively apply the above steps to the sub-list of elements with smaller values and separately the sub
list of elements with greater values.

Step-by-step example:
0 1 2 3 4 5 6 7 8 9 10 11 12 Remarks
38 08 16 06 79 57 24 56 02 58 04 70 45
Pivot Up Down Swap up
and down
38 08 16 06 04 57 24 56 02 58 79 70 45
Pivot Up Down Swap up
and down
38 08 16 06 04 02 24 56 57 58 79 70 45
Pivot Down Up Swap Pivot
and down
24 08 16 06 04 02 38 56 57 58 79 70 45
Pivot Down Up Swap Pivot
and down
02 08 16 06 04 24 38
Pivot Up Swap Pivot
Down and down
02 08 16 06 04 24 38
Pivot Up Down Swap up
and down
02 08 04 06 16 24 38
Pivot Down Up Swap Pivot
and down
02 06 04 08 16 24 38
Pivot Down Up Swap Pivot
and down
02 04 06 08 16 24 38 Left sub-list
is sorted
Repeat the similar procedure for right sub-list also

Algorithm for Merge sort


Algorithm MergeSort (low, high)
//a[low : high] is a global array to be sorted.
//Small(P) id true if there is only one element to sort.
{
If(low < high) then // if there are more than one element
{
//Divide P into sub-problems
//Find where to split the set.
Mid := (low + high) / 2;
//Solve the sub-problems.
MergeSort (low, mid);
MergeSort (mid+1, high);
//Combine the solutions
Merge(low, mid, high);
}
}

Algorithm Merge(low, mid, high)


// a[low: high] is a global array containing two sorted subsets in a[low: mid] and in a[mid+1: high].
//The goal is to merge these two sets into a single set residing in a[low: high]. b[] is an auxiliary
//global array.
{
h:=low; i:=low; j:=mid+1;
while ((h<=mid) and (j<=high)) do
{
if(a[h] <= a[j]) then
{
b[i]:=a[h];
h:=h+1;
}
else
{
b[i]:=a[j];
j:=j+1;
}
i:=i+1;
}

if (h>mid) then
for k:=j to high do
{
b[i]:= a[k]; i:= i+1;
}
else
for k:=h to mid do
{
b[i]:= a[k]; i:= i+1;
}
for k:= low to high do a[k] = b[k]

}
Example: This is a divide and conquer algorithm. Merge sort works as follows :
1. Divide the input which we have to sort into two parts in the middle. Call it the left part and right
part.
2. Sort each of them separately by using the same function recursively.
3. Then merge the two sorted parts.

Program for implementation of Quick Sort

def q_sort(a,low,high):
if low<high:
pivotpos=partition(a,low,high)
q_sort(a,low,pivotpos-1)
q_sort(a,pivotpos+1,high)

def partition(a,low,high):
pivotvalue=a[low]
up=low+1
down=high
done=False
while not done:
while up<=down and a[up]<=pivotvalue:
up+=1
while down>=up and a[down]>=pivotvalue:
down-=1
if down<up:
done=True
else:
temp=a[up]
a[up]=a[down]
a[down]=temp
temp=a[low]
a[low]=a[down]
a[down]=temp
return down

print("Enter elements into list:")


a=[int(x) for x in input().split()]
high=len(a)
q_sort(a,0,high-1)
print("The sorted list is",a)

Output:
Program for implementing Merge Sort

def m_sort(a):
for i in range(len(a)):
if i>1:
mid=len(a)//2
l_half=a[:mid]
r_half=a[mid:]
m_sort(l_half)
m_sort(r_half)
i=j=k=0
while i<len(l_half) and j<len(r_half):
if l_half[i]<r_half[j]:
a[k]=l_half[i]
i+=1
else:
a[k]=r_half[j]
j+=1
k+=1
while i<len(l_half):
a[k]=l_half[i]
i+=1
k+=1
while j<len(r_half):
a[k]=r_half[j]
j+=1
k+=1
print("Enter elements into list:")
a=[int(x) for x in input().split()]
m_sort(a)
print("The sorted list is",a)
Output:

Program for implementing heap Sort


def heapify(array, a, b):
largest = b
l=2*b+1
root = 2 * b + 2

if l < a and array[b] < array[l]:


largest = l

if root < a and array[largest] < array[root]:


largest = root

# Change root
if largest != b:
array[b], array[largest] = array[largest], array[b]
heapify(array, a, largest)

# sort an array of given size


def Heap_Sort(array):
a = len(array)

# maxheap..
for b in range(a // 2 - 1, -1, -1):
heapify(array, a, b)
# extract elements
for b in range(a-1, 0, -1):
array[b], array[0] = array[0], array[b] # swap
heapify(array, b, 0)

# Driver code
array = [ 7, 2, 5, 6, 3, 1, 8, 4]
print("The original array is: ", array)
Heap_Sort(array)
a = len(array)
print ("Array after sorting is: ", array)

output:
The original array is: [7, 2, 5, 6, 3, 1, 8, 4]
Array after sorting is: [1, 2, 3, 4, 5, 6, 7, 8]

Program for implementing shell Sort


def shellSort(array, n):
# Rearrange elements at each n/2, n/4, n/8, ... intervals
interval = n // 2
while interval > 0:
for i in range(interval, n):
temp = array[i]
j=i
while j >= interval and array[j - interval] > temp:
array[j] = array[j - interval]
j -= interval

array[j] = temp
interval //= 2
data = [9, 8, 3, 7, 5, 6, 4, 1]
size = len(data)
shellSort(data, size)
print('Sorted Array in Ascending Order:')
print(data)
print ("Array after sorting is: ", array)
output:
Sorted Array in Ascending Order:
[1, 3, 4, 5, 6, 7, 8, 9]

RESULT:
Thus the above program to implement sorting algorithms are executed and verified.
WEEK-12

IMPLEMENTATION OF HASHING WITH CHAINING IN


PYTHON
AIM:
To write a Python program to implement hashing with chaining in python

PROGRAM:
class HashTable:
def __init__(self, size):
self.size = size
self.table = [[] for _ in range(size)]

def hash_function(self, key):


# Simple hash function using modulus operator
return hash(key) % self.size

def insert(self, key, value):


index = self.hash_function(key)
# Check if the key already exists in the chain, if so update the value
for i, (k, v) in enumerate(self.table[index]):
if k == key:
self.table[index][i] = (key, value)
return
# Otherwise, insert the new key-value pair
self.table[index].append((key, value))

def search(self, key):


index = self.hash_function(key)
# Search for the key in the chain
for k, v in self.table[index]:
if k == key:
return v
return None # Return None if the key is not found

def delete(self, key):


index = self.hash_function(key)
# Search for the key in the chain and remove it
for i, (k, v) in enumerate(self.table[index]):
if k == key:
del self.table[index][i]
return True
return False # Return False if the key is not found

def display(self):
for i, chain in enumerate(self.table):
print(f"Index {i}: {chain}")

# Example usage
if __name__ == "__main__":
ht = HashTable(10) # Create a hash table of size 10
# Insert some key-value pairs
ht.insert("apple", 10)
ht.insert("banana", 20)
ht.insert("grape", 30)
ht.insert("cherry", 40)
ht.insert("melon", 50)
# Display the hash table
ht.display()
# Search for some keys
print("Search for 'apple':", ht.search("apple"))
print("Search for 'banana':", ht.search("banana"))
print("Search for 'mango':", ht.search("mango")) # This should return None
# Delete some keys
ht.delete("banana")
ht.delete("grape")
# Display the hash table after deletion
ht.display()

OUTPUT:

Index 0: []
Index 1: []
Index 2: []
Index 3: []
Index 4: [('apple', 10), ('grape', 30)]
Index 5: []
Index 6: [('melon', 50)]
Index 7: []
Index 8: []
Index 9: [('banana', 20), ('cherry', 40)]

Search for 'apple': 10


Search for 'banana': 20
Search for 'mango': None

Index 0: []
Index 1: []
Index 2: []
Index 3: []
Index 4: [('apple', 10)]
Index 5: []
Index 6: [('melon', 50)]
Index 7: []
Index 8: []
Index 9: [('cherry', 40)]

RESULT:
Thus the above programs are implemented and verified.

You might also like