Skip to content

Commit 95360e0

Browse files
authored
Create DSA.py
1 parent 633c703 commit 95360e0

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

DSA.py

+235
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# ------------------------------ Data Structures ------------------------------
2+
3+
# 1. Arrays (Lists in Python)
4+
# An array in Python is implemented as a list, which is dynamic and can hold different types of elements.
5+
6+
arr = [1, 2, 3, 4, 5]
7+
arr.append(6) # Add 6 at the end
8+
arr.insert(2, 9) # Insert 9 at index 2
9+
arr.remove(4) # Remove first occurrence of 4
10+
print("Array:", arr)
11+
12+
# 2. Linked List
13+
# A linked list consists of nodes, where each node has a data value and a reference (or pointer) to the next node.
14+
15+
class Node:
16+
def __init__(self, data):
17+
self.data = data # Node data
18+
self.next = None # Next node in the list
19+
20+
class LinkedList:
21+
def __init__(self):
22+
self.head = None # Initially, the list is empty
23+
24+
def append(self, data):
25+
new_node = Node(data) # Create a new node
26+
if not self.head:
27+
self.head = new_node # If list is empty, set the head to the new node
28+
return
29+
last = self.head
30+
while last.next:
31+
last = last.next # Traverse to the last node
32+
last.next = new_node # Add the new node at the end
33+
34+
def display(self):
35+
current = self.head
36+
while current:
37+
print(current.data, end=" -> ") # Print current node data
38+
current = current.next
39+
print("None") # End of list
40+
41+
ll = LinkedList()
42+
ll.append(10)
43+
ll.append(20)
44+
ll.append(30)
45+
ll.display()
46+
47+
# 3. Stack
48+
# A stack follows the Last In, First Out (LIFO) principle.
49+
50+
stack = []
51+
stack.append(1) # Push 1 onto the stack
52+
stack.append(2) # Push 2 onto the stack
53+
stack.pop() # Pop the top element (2)
54+
print("Stack after pop:", stack)
55+
56+
# 4. Queue
57+
# A queue follows the First In, First Out (FIFO) principle.
58+
59+
from collections import deque
60+
queue = deque()
61+
queue.append(1) # Enqueue (add 1 to the queue)
62+
queue.append(2) # Enqueue (add 2 to the queue)
63+
queue.popleft() # Dequeue (remove the first element, which is 1)
64+
print("Queue after dequeue:", queue)
65+
66+
# 5. Hash Table (Dictionaries in Python)
67+
# A hash table stores data in key-value pairs.
68+
69+
hash_map = {}
70+
hash_map['key1'] = 'value1' # Insert key-value pair
71+
hash_map['key2'] = 'value2'
72+
print("Hash Map:", hash_map)
73+
74+
# 6. Trees (Binary Tree)
75+
# A binary tree is a tree where each node has at most two children.
76+
77+
class TreeNode:
78+
def __init__(self, data):
79+
self.data = data # Node value
80+
self.left = None # Left child
81+
self.right = None # Right child
82+
83+
class BinaryTree:
84+
def __init__(self, root):
85+
self.root = TreeNode(root) # Initialize tree with root node
86+
87+
def inorder_traversal(self, node):
88+
if node:
89+
self.inorder_traversal(node.left) # Traverse left subtree
90+
print(node.data, end=" ") # Visit node
91+
self.inorder_traversal(node.right) # Traverse right subtree
92+
93+
bt = BinaryTree(1)
94+
bt.root.left = TreeNode(2)
95+
bt.root.right = TreeNode(3)
96+
bt.inorder_traversal(bt.root)
97+
98+
# 7. Graph (Adjacency List Representation)
99+
# A graph is made of vertices (nodes) connected by edges.
100+
101+
graph = {
102+
'A': ['B', 'C'], # A is connected to B and C
103+
'B': ['A', 'D'], # B is connected to A and D
104+
'C': ['A'], # C is connected to A
105+
'D': ['B'] # D is connected to B
106+
}
107+
print("Graph:", graph)
108+
109+
# ------------------------------ Algorithms ------------------------------
110+
111+
# 1. Sorting Algorithms
112+
113+
# Bubble Sort
114+
# Bubble Sort repeatedly compares adjacent elements and swaps them if they are in the wrong order.
115+
116+
def bubble_sort(arr):
117+
n = len(arr)
118+
for i in range(n):
119+
for j in range(0, n-i-1):
120+
if arr[j] > arr[j+1]: # If current element is greater than the next
121+
arr[j], arr[j+1] = arr[j+1], arr[j] # Swap
122+
123+
arr = [64, 34, 25, 12, 22, 11, 90]
124+
bubble_sort(arr) # Sort the array using bubble sort
125+
print("Bubble Sort Result:", arr)
126+
127+
# Merge Sort
128+
# Merge Sort is a divide-and-conquer algorithm. It splits the array into two halves, recursively sorts them, and merges them.
129+
130+
def merge_sort(arr):
131+
if len(arr) > 1:
132+
mid = len(arr) // 2
133+
left_half = arr[:mid]
134+
right_half = arr[mid:]
135+
136+
merge_sort(left_half) # Recursively sort the left half
137+
merge_sort(right_half) # Recursively sort the right half
138+
139+
i = j = k = 0
140+
141+
# Merge the sorted halves
142+
while i < len(left_half) and j < len(right_half):
143+
if left_half[i] < right_half[j]:
144+
arr[k] = left_half[i]
145+
i += 1
146+
else:
147+
arr[k] = right_half[j]
148+
j += 1
149+
k += 1
150+
151+
# Copy the remaining elements of left_half and right_half, if any
152+
while i < len(left_half):
153+
arr[k] = left_half[i]
154+
i += 1
155+
k += 1
156+
157+
while j < len(right_half):
158+
arr[k] = right_half[j]
159+
j += 1
160+
k += 1
161+
162+
arr = [38, 27, 43, 3, 9, 82, 10]
163+
merge_sort(arr) # Sort the array using merge sort
164+
print("Merge Sort Result:", arr)
165+
166+
# 2. Searching Algorithms
167+
168+
# Binary Search
169+
# Binary Search works on sorted arrays by repeatedly dividing the search interval in half.
170+
171+
def binary_search(arr, x):
172+
low = 0
173+
high = len(arr) - 1
174+
while low <= high:
175+
mid = (low + high) // 2
176+
if arr[mid] == x: # Element found
177+
return mid
178+
elif arr[mid] < x: # Search right half
179+
low = mid + 1
180+
else: # Search left half
181+
high = mid - 1
182+
return -1 # Element not found
183+
184+
arr = [2, 3, 4, 10, 40]
185+
result = binary_search(arr, 10) # Search for 10
186+
print("Binary Search Result:", result)
187+
188+
# 3. Graph Algorithms
189+
190+
# Depth-First Search (DFS)
191+
# DFS explores as far as possible along each branch before backtracking.
192+
193+
def dfs(graph, node, visited=None):
194+
if visited is None:
195+
visited = set()
196+
visited.add(node) # Mark the node as visited
197+
for neighbor in graph[node]:
198+
if neighbor not in visited:
199+
dfs(graph, neighbor, visited) # Recursively visit unvisited neighbors
200+
return visited
201+
202+
graph = {
203+
'A': ['B', 'C'],
204+
'B': ['A', 'D'],
205+
'C': ['A'],
206+
'D': ['B']
207+
}
208+
print("DFS Traversal:", dfs(graph, 'A'))
209+
210+
# Breadth-First Search (BFS)
211+
# BFS explores all neighbors at the present depth level before moving on to nodes at the next depth level.
212+
213+
from collections import deque
214+
215+
def bfs(graph, start):
216+
visited = set()
217+
queue = deque([start]) # Initialize queue with the start node
218+
visited.add(start)
219+
220+
while queue:
221+
vertex = queue.popleft() # Dequeue (remove from front)
222+
print(vertex, end=" ") # Visit node
223+
for neighbor in graph[vertex]:
224+
if neighbor not in visited:
225+
visited.add(neighbor) # Mark as visited
226+
queue.append(neighbor) # Enqueue unvisited neighbors
227+
228+
graph = {
229+
'A': ['B', 'C'],
230+
'B': ['A', 'D'],
231+
'C': ['A'],
232+
'D': ['B']
233+
}
234+
print("BFS Traversal:", end=" ")
235+
bfs(graph, 'A')

0 commit comments

Comments
 (0)