Full DSA Course Notes in Python
Comprehensive Beginner to Advanced Guide
Includes Explanations, Code Examples, and Practice Problems
1. Introduction to DSA
Data Structures and Algorithms (DSA) form the foundation of computer science. They help write
efficient, optimized, and clean code. Time Complexity measures how fast an algorithm runs.
Common complexities: O(1), O(log n), O(n), O(n log n), O(n²).
Practice Questions:
1 Explain the difference between a data structure and an algorithm.
2 Write a Python function to calculate factorial using recursion.
2. Arrays and Lists
Arrays are contiguous memory locations holding elements of the same type. Lists in Python are
dynamic arrays.
Python Example:
numbers = [10, 20, 30, 40] print("Array Elements:", numbers) numbers.append(50)
print("After append:", numbers)
Output: Array Elements: [10, 20, 30, 40] After append: [10, 20, 30, 40, 50]
Practice Questions:
1 Reverse an array in Python.
2 Find the maximum and minimum elements in a list.
3. Stacks
Stacks follow LIFO (Last In First Out) principle. Used in recursion, undo mechanisms, etc.
Python Example:
stack = [] stack.append(10) stack.append(20) print("Stack after pushes:", stack)
stack.pop() print("After pop:", stack)
Practice Questions:
1 Implement a stack using Python list.
2 Check if a string has balanced parentheses using a stack.
4. Queues
Queues follow FIFO (First In First Out) principle. Used in scheduling and buffering.
Python Example:
from collections import deque queue = deque() queue.append(10) queue.append(20)
print("Queue after enqueue:", queue) queue.popleft() print("After dequeue:",
queue)
Practice Questions:
1 Implement a queue using two stacks.
2 Simulate a ticketing system queue in Python.
5. Linked Lists
A linked list is a linear data structure where elements are nodes pointing to the next node.
Python Example:
class Node: def __init__(self, data): self.data = data self.next = None class
LinkedList: def __init__(self): self.head = None def append(self, data): new_node
= Node(data) if not self.head: self.head = new_node return 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.append(10) ll.append(20) ll.append(30) ll.display()
Practice Questions:
1 Reverse a linked list.
2 Find the middle node of a linked list.
6. Recursion
Recursion is a function calling itself to solve smaller subproblems.
Python Example:
def factorial(n): if n == 0: return 1 return n * factorial(n-1)
print(factorial(5))
Output: 120
Practice Questions:
1 Write a recursive function to compute Fibonacci numbers.
2 Solve Tower of Hanoi problem using recursion.
7. Searching Algorithms
Linear Search and Binary Search are basic searching algorithms.
Python Example:
def binary_search(arr, target): low, high = 0, len(arr)-1 while low <= high: mid
= (low+high)//2 if arr[mid] == target: return mid elif arr[mid] < target: low =
mid+1 else: high = mid-1 return -1 print(binary_search([10,20,30,40,50], 30))
Output: 2
Practice Questions:
1 Implement linear search.
2 Search in a rotated sorted array.
8. Sorting Algorithms
Common sorting algorithms: Bubble Sort, Selection Sort, Insertion Sort, Merge Sort, Quick Sort.
Python Example:
def bubble_sort(arr): n = len(arr) for i in range(n): for j in range(0,n-i-1): if
arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] return arr
print(bubble_sort([64, 34, 25, 12, 22, 11, 90]))
Output: [11, 12, 22, 25, 34, 64, 90]
Practice Questions:
1 Implement insertion sort.
2 Implement merge sort.
9. Trees
Trees are hierarchical data structures. A binary tree has at most two children per node.
Python Example:
class Node: def __init__(self, data): self.data = data self.left = None
self.right = None root = Node(1) root.left = Node(2) root.right = Node(3)
print(root.data, root.left.data, root.right.data)
Output: 1 2 3
Practice Questions:
1 Implement inorder, preorder, postorder traversal.
2 Find height of a binary tree.
10. Graphs
Graphs consist of vertices and edges. Can be represented using adjacency list or matrix.
Python Example:
graph = { 'A': ['B','C'], 'B': ['A','D','E'], 'C': ['A','F'], 'D': ['B'], 'E':
['B','F'], 'F': ['C','E'] } print(graph)
Practice Questions:
1 Implement BFS and DFS.
2 Detect cycle in an undirected graph.
11. Hashing
Hashing is mapping data to fixed-size values using hash functions.
Python Example:
hash_map = {} hash_map['apple'] = 10 hash_map['banana'] = 20 print(hash_map)
Output: {'apple': 10, 'banana': 20}
Practice Questions:
1 Implement your own hash table.
2 Count frequency of elements in a list using hashing.
12. Dynamic Programming
Dynamic Programming is solving problems by combining solutions of subproblems and storing
results.
Python Example:
def fib_dp(n): dp = [0]*(n+1) dp[1] = 1 for i in range(2,n+1): dp[i] =
dp[i-1]+dp[i-2] return dp[n] print(fib_dp(10))
Output: 55
Practice Questions:
1 Solve 0/1 Knapsack problem.
2 Solve Minimum Coin Change problem.