Dsa
Mon 30 June 2025
# Stack using List
stack = []
# Pushing elements
stack.append(10)
stack.append(20)
stack.append(30)
print("Stack after pushes:", stack)
Stack after pushes: [10, 20, 30]
# Popping elements
stack.pop()
print("Stack after pop:", stack)
Stack after pop: [10, 20]
# Peek
if stack:
print("Top element:", stack[-1])
Top element: 20
# IsEmpty
print("Is stack empty?", len(stack) == 0)
Is stack empty? False
# Stack Length
print("Stack size:", len(stack))
Stack size: 2
# Stack function
def print_stack(s):
for i in reversed(s):
print(i)
print_stack(stack)
20
10
# Push more elements
stack.append(40)
stack.append(50)
print_stack(stack)
50
40
20
10
# Pop all elements
while stack:
stack.pop()
print("Stack cleared:", stack)
Stack cleared: []
# Queue using List
queue = []
# Enqueue
queue.append(1)
queue.append(2)
queue.append(3)
print("Queue:", queue)
Queue: [1, 2, 3]
# Dequeue
queue.pop(0)
print("After Dequeue:", queue)
After Dequeue: [2, 3]
# Is queue empty?
print("Empty?", len(queue) == 0)
Empty? False
# Peek front
if queue:
print("Front:", queue[0])
Front: 2
# Queue Length
print("Queue size:", len(queue))
Queue size: 2
# Using deque for efficient queue
from collections import deque
dq = deque()
dq.append(10)
dq.append(20)
dq.append(30)
print("Deque:", dq)
Deque: deque([10, 20, 30])
dq.popleft()
print("After popleft:", dq)
After popleft: deque([20, 30])
dq.appendleft(5)
print("After appendleft:", dq)
After appendleft: deque([5, 20, 30])
# Node class
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Linked List class
class LinkedList:
def __init__(self):
self.head = None
def insert(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
else:
temp = self.head
while temp.next:
temp = temp.next
temp.next = new_node
def display(self):
temp = self.head
while temp:
print(temp.data, end=" -> ")
temp = temp.next
print("None")
ll = LinkedList()
ll.insert(1)
ll.insert(2)
ll.insert(3)
ll.display()
1 -> 2 -> 3 -> None
# Insert at beginning
def insert_at_beginning(self, data):
new_node = Node(data)
new_node.next = self.head
self.head = new_node
LinkedList.insert_at_beginning = insert_at_beginning
ll.insert_at_beginning(0)
ll.display()
0 -> 1 -> 2 -> 3 -> None
# Delete by value
def delete(self, key):
temp = self.head
if temp and temp.data == key:
self.head = temp.next
return
while temp.next:
if temp.next.data == key:
temp.next = temp.next.next
return
temp = temp.next
LinkedList.delete = delete
ll.delete(2)
ll.display()
0 -> 1 -> 3 -> None
ll.delete(0)
ll.display()
1 -> 3 -> None
ll.delete(10) # non-existent
ll.display()
1 -> 3 -> None
# Linear Search
def linear_search(arr, x):
for i in range(len(arr)):
if arr[i] == x:
return i
return -1
arr = [5, 2, 9, 4, 7]
print("Index of 9:", linear_search(arr, 9))
Index of 9: 2
print("Index of 3 (not found):", linear_search(arr, 3))
Index of 3 (not found): -1
# Binary Search
def binary_search(arr, x):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == x:
return mid
elif arr[mid] < x:
low = mid + 1
else:
high = mid - 1
return -1
sorted_arr = sorted(arr)
print("Sorted:", sorted_arr)
Sorted: [2, 4, 5, 7, 9]
print("Binary search 4:", binary_search(sorted_arr, 4))
Binary search 4: 1
print("Binary search 8 (not found):", binary_search(sorted_arr, 8))
Binary search 8 (not found): -1
# Edge case: empty array
print("Empty array:", binary_search([], 1))
Empty array: -1
# Edge case: one element
print("One element:", binary_search([5], 5))
One element: 0
# Binary search for negative numbers
neg_arr = [-9, -3, 0, 2, 4]
print("Find -3:", binary_search(neg_arr, -3))
Find -3: 1
# Bubble Sort
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
data = [64, 34, 25, 12, 22, 11, 90]
bubble_sort(data)
print("Bubble Sorted:", data)
Bubble Sorted: [11, 12, 22, 25, 34, 64, 90]
# Insertion Sort
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and key < arr[j]:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
data2 = [9, 1, 6, 3, 2]
insertion_sort(data2)
print("Insertion Sorted:", data2)
Insertion Sorted: [1, 2, 3, 6, 9]
# Selection Sort
def selection_sort(arr):
for i in range(len(arr)):
min_idx = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
data3 = [29, 10, 14, 37, 13]
selection_sort(data3)
print("Selection Sorted:", data3)
Selection Sorted: [10, 13, 14, 29, 37]
# Merge Sort
def merge_sort(arr):
if len(arr) > 1:
mid = len(arr) // 2
L = arr[:mid]
R = arr[mid:]
merge_sort(L)
merge_sort(R)
i = j = k = 0
while i < len(L) and j < len(R):
if L[i] < R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
while i < len(L):
arr[k] = L[i]
i += 1
k += 1
while j < len(R):
arr[k] = R[j]
j += 1
k += 1
data4 = [12, 11, 13, 5, 6, 7]
merge_sort(data4)
print("Merge Sorted:", data4)
Merge Sorted: [5, 6, 7, 11, 12, 13]
# Recursive Factorial
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
print("Factorial 5:", factorial(5))
Factorial 5: 120
# Fibonacci
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print("Fibonacci of 6:", fibonacci(6))
Fibonacci of 6: 8
# Print fibonacci series
for i in range(8):
print(fibonacci(i), end=" ")
0 1 1 2 3 5 8 13
# Recursion with sum of array
def sum_array(arr):
if not arr:
return 0
return arr[0] + sum_array(arr[1:])
print("Sum:", sum_array([1, 2, 3, 4]))
Sum: 10
# Tower of Hanoi
def hanoi(n, src, temp, dest):
if n == 1:
print(f"Move disk 1 from {src} to {dest}")
return
hanoi(n - 1, src, dest, temp)
print(f"Move disk {n} from {src} to {dest}")
hanoi(n - 1, temp, src, dest)
hanoi(3, 'A', 'B', 'C')
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
# Base case edge test
print("Hanoi 1 disk:")
hanoi(1, 'X', 'Y', 'Z')
Hanoi 1 disk:
Move disk 1 from X to Z
# Tree Node
class TreeNode:
def __init__(self, val):
self.left = None
self.right = None
self.val = val
# Pre-order Traversal
def preorder(root):
if root:
print(root.val, end=' ')
preorder(root.left)
preorder(root.right)
# Build a simple tree
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
print("Preorder traversal:")
preorder(root)
Preorder traversal:
1 2 4 5 3
# In-order
def inorder(root):
if root:
inorder(root.left)
print(root.val, end=' ')
inorder(root.right)
print("\nInorder traversal:")
inorder(root)
Inorder traversal:
4 2 5 1 3
# Post-order
def postorder(root):
if root:
postorder(root.left)
postorder(root.right)
print(root.val, end=' ')
print("\nPostorder traversal:")
postorder(root)
Postorder traversal:
4 5 2 3 1
# Tree Depth
def depth(root):
if not root:
return 0
return 1 + max(depth(root.left), depth(root.right))
print("\nTree Depth:", depth(root))
Tree Depth: 3
Score: 70
Category: basics