1-Data Stucture Using Python Lab
1-Data Stucture Using Python Lab
Class stack:
def__init__(self):
self.values=[]
def push(self,x):
self.values = [x]+self.values
def pop(self):
retrun self.values.pop(0)
s=stack()
s.push(10)
s.push(20)
s.push(30)
s.push(40)
s.push(50)
print(s.values)
print(s.pop())
print(s.values)
OUTPUT:
[50,40,30,20,10]
50
[40,30,20,10]
b) program:
class queue:
def__init__(self):
self.values=[]
def enqueue(self,x):
self.values.append(x)
def dequeue(self):
front=self.values[0]
self.values=self.values[1:]
return front
q1=queue()
q1.enqueue(10)
q1.enqueue(20)
q1.enqueue(30)
q1.enqueue(40)
print(q1.values)
q1.enqueue(50)
print(q1.values)
print(q1.dequeue())
print(q1.values)
OUTPUT:
[10,20,30,40]
[10,20,30,40,50]
10
[20,30,40,50]
Python Program:
def evaluate_postfix(expression):
stack = []
if char.isdigit():
stack.append(int(char))
else:
operand2 = stack.pop()
operand1 = stack.pop()
if char == '+':
stack.append(operand1 + operand2)
stack.append(operand1 - operand2)
stack.append(operand1 * operand2)
stack.append(operand1 / operand2)
return stack[0]
# Example usage
postfix_expr = "23*5+"
result = evaluate_postfix(postfix_expr)
Explanation:
If the character is an operator (+, -, *, /), we pop the top two elements from the stack, apply the
operator, and push the result back onto the stack.
Finally, the result of the postfix expression is the last remaining element in the stack.
Step 2: * operator pops 2 and 3, multiplies them to get 6, then pushes 6 back onto the stack.
Step 4: + operator pops 6 and 5, adds them to get 11, then pushes 11 back onto the stack.
Final result: 11
Output:
Let me know if you'd like to try more examples or need further clarification!
class LinkedList:
def __init__(self):
self.head = None
temp = self.head
# Traverse to the position-1 node (i.e., the node before the specified
position)
for i in range(position - 1):
if temp is None:
print("Position out of range")
return
temp = temp.next
class LinkedList:
def __init__(self):
self.head = None # Initializes an empty linked list
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
class LinkedList:
def __init__(self):
self.head = None # Initializes an empty linked list
while current:
if current.data == key:
return position # Return the position if element is found
current = current.next
position += 1
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
output:
List after inserting elements:
10 -> 20 -> 30 -> 40 -> None
Element 30 found at position 2.
Element 50 not found in the list.
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
output:
List before sorting:
40 -> 10 -> 30 -> 20 -> None
List after sorting:
10 -> 20 -> 30 -> 40 -> None
Or
class Node:
def __init__(self, data):
self.data = data
self.next = None
class SinglyLinkedList:
def __init__(self):
self.head = None
if current is None:
print(f"Position {position} is out of bounds")
return
if current.next is None:
print(f"Element {data} not found")
return
current = self.head
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
# Delete an element
sll.delete_element(15)
print("Linked List after deleting 15:")
sll.display()
class Node:
def __init__(self, data):
self.data = data # The data of the node
self.next = None # Pointer to the next node
self.prev = None # Pointer to the previous node
class DoublyLinkedList:
def __init__(self):
self.head = None # Initially, the list is empty
def print_list(self):
# Function to print the elements of the list
temp = self.head
while temp:
print(temp.data, end=" <=> ")
temp = temp.next
print("None")
# Example usage:
dll = DoublyLinkedList()
# Insert elements
dll.insert_at_position(10, 0) # Insert 10 at position 0
dll.insert_at_position(20, 1) # Insert 20 at position 1
dll.insert_at_position(15, 1) # Insert 15 at position 1
dll.insert_at_position(5, 0) # Insert 5 at position 0
dll.insert_at_position(25, 3) # Insert 25 at position 3
output:
List after insertion:
5 <=> 10 <=> 15 <=> 20 <=> 25 <=> None
class DoublyLinkedList:
def __init__(self):
self.head = None # Initially, the list is empty
def print_list(self):
# Function to print the elements of the list
temp = self.head
while temp:
print(temp.data, end=" <=> ")
temp = temp.next
print("None")
last = self.head
while last.next:
last = last.next
last.next = new_node
new_node.prev = last
# Example usage:
dll = DoublyLinkedList()
# Insert elements
dll.insert_at_end(10)
dll.insert_at_end(20)
dll.insert_at_end(30)
dll.insert_at_end(40)
dll.insert_at_end(50)
# Delete an element
dll.delete_element(30)
print("\nList after deleting 30:")
dll.print_list() # Output the list after deletion
output:
List before deletion:
10 <=> 20 <=> 30 <=> 40 <=> 50 <=> None
class DoublyLinkedList:
def __init__(self):
self.head = None # Initially, the list is empty
def print_list(self):
# Function to print the elements of the list
temp = self.head
while temp:
print(temp.data, end=" <=> ")
temp = temp.next
print("None")
last = self.head
while last.next:
last = last.next
last.next = new_node
new_node.prev = last
# Example usage:
dll = DoublyLinkedList()
# Insert elements
dll.insert_at_end(10)
dll.insert_at_end(20)
dll.insert_at_end(30)
dll.insert_at_end(40)
dll.insert_at_end(50)
class Node:
def __init__(self, data):
self.data = data # The data of the node
self.next = None # Pointer to the next node
self.prev = None # Pointer to the previous node
class DoublyLinkedList:
def __init__(self):
self.head = None # Initially, the list is empty
def print_list(self):
# Function to print the elements of the list
temp = self.head
while temp:
print(temp.data, end=" <=> ")
temp = temp.next
print("None")
last = self.head
while last.next:
last = last.next
last.next = new_node
new_node.prev = last
def sort_list(self):
if not self.head or not self.head.next:
return # List is empty or has one element, no need to sort
# Example usage:
dll = DoublyLinkedList()
# Insert elements
dll.insert_at_end(40)
dll.insert_at_end(10)
dll.insert_at_end(30)
dll.insert_at_end(20)
dll.insert_at_end(50)
output:
class CircularLinkedList:
def __init__(self):
self.head = None
if count != position - 1:
print("Position out of bounds.")
return
new_node.next = current.next
current.next = new_node
print(f"Inserted {data} at position {position}.")
def display(self):
if not self.head:
print("List is empty.")
return
current = self.head
print("Circular Linked List:", end=" ")
while True:
print(current.data, end=" -> ")
current = current.next
if current == self.head:
break
print("(back to head)")
# Example usage
cll = CircularLinkedList()
cll.insert_at_position(10, 0)
cll.insert_at_position(20, 1)
cll.insert_at_position(15, 1)
cll.display()
output:
Inserted 10 as the first node.
Inserted 20 at position 1.
Inserted 15 at position 1.
Circular Linked List: 10 -> 15 -> 20 -> (back to head)
class CircularLinkedList:
def __init__(self):
self.head = None
if not self.head:
new_node.next = new_node
self.head = new_node
print(f"Inserted {data} as the first node.")
return
if position == 0:
tail = self.head
while tail.next != self.head:
tail = tail.next
new_node.next = self.head
tail.next = new_node
self.head = new_node
print(f"Inserted {data} at position {position}.")
return
current = self.head
count = 0
while count < position - 1 and current.next != self.head:
current = current.next
count += 1
if count != position - 1:
print("Position out of bounds.")
return
new_node.next = current.next
current.next = new_node
print(f"Inserted {data} at position {position}.")
current = self.head
prev = None
def display(self):
if not self.head:
print("List is empty.")
return
current = self.head
print("Circular Linked List:", end=" ")
while True:
print(current.data, end=" -> ")
current = current.next
if current == self.head:
break
print("(back to head)")
# Example usage
cll = CircularLinkedList()
cll.insert_at_position(10, 0)
cll.insert_at_position(20, 1)
cll.insert_at_position(15, 1)
cll.display()
# Deleting elements
cll.delete_element(15)
cll.display()
cll.delete_element(10)
cll.display()
cll.delete_element(100) # Element not in the list
Output:
Inserted 10 as the first node.
Inserted 20 at position 1.
Inserted 15 at position 1.
Circular Linked List: 10 -> 15 -> 20 -> (back to head)
Deleted 15 from the list.
Circular Linked List: 10 -> 20 -> (back to head)
Deleted 10 from the list.
Circular Linked List: 20 -> (back to head)
Element 100 not found in the list.
class CircularLinkedList:
def __init__(self):
self.head = None
if position == 0:
tail = self.head
while tail.next != self.head:
tail = tail.next
new_node.next = self.head
tail.next = new_node
self.head = new_node
print(f"Inserted {data} at position {position}.")
return
current = self.head
count = 0
while count < position - 1 and current.next != self.head:
current = current.next
count += 1
if count != position - 1:
print("Position out of bounds.")
return
new_node.next = current.next
current.next = new_node
print(f"Inserted {data} at position {position}.")
current = self.head
position = 0
while True:
if current.data == data:
print(f"Element {data} found at position {position}.")
return position
current = current.next
position += 1
if current == self.head:
break
def display(self):
if not self.head:
print("List is empty.")
return
current = self.head
print("Circular Linked List:", end=" ")
while True:
print(current.data, end=" -> ")
current = current.next
if current == self.head:
break
print("(back to head)")
# Example usage
cll = CircularLinkedList()
cll.insert_at_position(10, 0)
cll.insert_at_position(20, 1)
cll.insert_at_position(15, 1)
cll.display()
output:
Inserted 10 as the first node.
Inserted 20 at position 1.
Inserted 15 at position 1.
Circular Linked List: 10 -> 15 -> 20 -> (back to head)
Element 15 found at position 1.
Element 10 found at position 0.
Element 100 not found in the list.
# Node class
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Stack class
class Stack:
def __init__(self):
self.top = None
def push(self, data):
new_node = Node(data)
new_node.next = self.top
self.top = new_node
print(f"Pushed: {data}")
def pop(self):
if self.top is None:
print("Stack Underflow")
return
popped = self.top.data
self.top = self.top.next
print(f"Popped: {popped}")
def display(self):
current = self.top
print("Stack from top to bottom:")
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
# Example usage
stack = Stack()
stack.push(10)
stack.push(20)
stack.push(30)
stack.display()
stack.pop()
stack.display()
Output:
Pushed: 10
Pushed: 20
Pushed: 30
Stack from top to bottom:
30 -> 20 -> 10 -> None
Popped: 30
Stack from top to bottom:
20 -> 10 -> None
# Node class
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Queue class
class Queue:
def __init__(self):
self.front = None
self.rear = None
def dequeue(self):
if self.front is None:
print("Queue Underflow")
return
dequeued = self.front.data
self.front = self.front.next
if self.front is None:
self.rear = None
print(f"Dequeued: {dequeued}")
def display(self):
current = self.front
print("Queue from front to rear:")
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
# Example usage
queue = Queue()
queue.enqueue(100)
queue.enqueue(200)
queue.enqueue(300)
queue.display()
queue.dequeue()
queue.display()
Output:
Enqueued: 100
Enqueued: 200
Enqueued: 300
Queue from front to rear:
100 -> 200 -> 300 -> None
Dequeued: 100
Queue from front to rear:
200 -> 300 -> None
Code:
# Binary Search - Iterative Method
def binary_search_iterative(arr, target):
low = 0
high = len(arr) - 1
if arr[mid] == target:
return mid # Element found
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
if arr[mid] == target:
return mid
elif arr[mid] < target:
return binary_search_recursive(arr, mid + 1, high, target)
else:
return binary_search_recursive(arr, low, mid - 1, target)
# Example usage
arr = [10, 20, 30, 40, 50, 60, 70]
target = 40
# Iterative
print("Using Iterative Method:")
index_iter = binary_search_iterative(arr, target)
if index_iter != -1:
print(f"Element {target} found at index {index_iter}")
else:
print(f"Element {target} not found")
# Recursive
print("\nUsing Recursive Method:")
index_rec = binary_search_recursive(arr, 0, len(arr) - 1, target)
if index_rec != -1:
print(f"Element {target} found at index {index_rec}")
else:
print(f"Element {target} not found")
Output:
Using Iterative Method:
Element 40 found at index 3
10 b). Write a program for sorting the given list numbers in ascending order
using the following technique: Bubble sort and Selection sort
Program:
Sorting in Python:
1️⃣ Bubble Sort
2️⃣ Selection Sort
Code:
# Bubble Sort Function
def bubble_sort(arr):
n = len(arr)
for i in range(n - 1): # Number of passes
for j in range(n - 1 - i): # Pairwise comparison
if arr[j] > arr[j + 1]: # Swap if out of order
arr[j], arr[j + 1] = arr[j + 1], arr[j]
# Example list
numbers1 = [64, 25, 12, 22, 11]
numbers2 = numbers1.copy() # For second sort
# Bubble Sort
print("Original List:", numbers1)
bubble_sort(numbers1)
print("Sorted using Bubble Sort:", numbers1)
# Selection Sort
print("\nOriginal List:", numbers2)
selection_sort(numbers2)
print("Sorted using Selection Sort:", numbers2)
Output:
Original List: [64, 25, 12, 22, 11]
Sorted using Bubble Sort: [11, 12, 22, 25, 64]
11.Write a program for sorting the given list numbers in ascending order
using the following technique: Insertion sort and Quicksort
Programs:
1) Insertion Sort
2) Quick Sort
Code:
# Insertion Sort Function
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j=i-1
arr[j + 1] = key
# Example list
numbers1 = [29, 10, 14, 37, 13]
numbers2 = numbers1.copy()
# Insertion Sort
print("Original List:", numbers1)
insertion_sort(numbers1)
print("Sorted using Insertion Sort:", numbers1)
# Quick Sort
print("\nOriginal List:", numbers2)
sorted_quick = quick_sort(numbers2)
print("Sorted using Quick Sort:", sorted_quick)
Output:
Original List: [29, 10, 14, 37, 13]
Sorted using Insertion Sort: [10, 13, 14, 29, 37]
12.Write a program for sorting the given list numbers in ascending order
using the following technique: Merge sort and Heapsort
Program:
1) Merge Sort
2) Heap Sort
Code:
# Merge Sort Function
def merge_sort(arr):
if len(arr) > 1:
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
merge_sort(left_half)
merge_sort(right_half)
def heap_sort(arr):
n = len(arr)
# Example list
numbers1 = [45, 23, 11, 89, 77, 98, 4]
numbers2 = numbers1.copy()
# Merge Sort
print("Original List:", numbers1)
merge_sort(numbers1)
print("Sorted using Merge Sort:", numbers1)
# Heap Sort
print("\nOriginal List:", numbers2)
heap_sort(numbers2)
print("Sorted using Heap Sort:", numbers2)
Output:
Original List: [45, 23, 11, 89, 77, 98, 4]
Sorted using Merge Sort: [4, 11, 23, 45, 77, 89, 98]
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
# Pre-order Traversal
print("Pre-order Traversal:")
preorder(root) # Output: 1 2 4 5 3 6 7
# In-order Traversal
print("\nIn-order Traversal:")
inorder(root) # Output: 4 2 5 1 6 3 7
# Post-order Traversal
print("\nPost-order Traversal:")
postorder(root) # Output: 4 5 2 6 7 3 1
Output:
Pre-order Traversal:
1245367
In-order Traversal:
4251637
Post-order Traversal:
4526731
14.Write a program to find the minimum spanning tree for a weighted graph
using a) Prim’s Algorithm b) Kruskal’s Algorithm.
Program:
a) Prim’s Algorithm
b) Kruskal’s Algorithm
for _ in range(num_vertices):
# Find the minimum key vertex not yet included
min_key = sys.maxsize
for v in range(num_vertices):
if not selected[v] and keys[v] < min_key:
min_key = keys[v]
u=v
selected[u] = True
# Print MST
print("Prim's MST:")
total_weight = 0
for i in range(1, num_vertices):
print(f"{parent[i]} - {i} : {graph[i][parent[i]]}")
total_weight += graph[i][parent[i]]
print("Total Weight:", total_weight)
prims_algorithm(graph)
Output (Prim’s):
Prim's MST:
0-1:2
1-2:3
0-3:6
1-4:5
Total Weight: 16
# Print MST
print("\nKruskal's MST:")
for u, v, weight in mst:
print(f"{u} - {v} : {weight}")
print("Total Weight:", total_weight)
kruskal_algorithm(vertices, edges)
(Kruskal’s):
Kruskal's MST:
A-B:2
B-C:3
B-E:5
A-D:6
Total Weight: 16
while queue:
node = queue.popleft()
if node not in visited:
print(node, end=" ")
visited.add(node)
for neighbor in self.graph[node]:
if neighbor not in visited:
queue.append(neighbor)
# Example graph:
# A
# /\
# B C
# /\ \
#D E F
# Perform traversals
g.bfs('A') # Expected BFS: A B C D E F
print()
g.dfs('A') # Expected DFS: A B D E C F
Output:
BFS Traversal: A B C D E F
DFS Traversal: A B D E C F