Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ Please make sure to read our [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CON
```
code-snippets/
├── algorithms/
│ ├── sorting/
│ ├── searching/
│ ├── graphs/
│ └── techniques/
├── data-structures/
│ └── disjoint-sets/
├── web-development/
└── other/
```
Expand All @@ -44,6 +49,35 @@ code-snippets/
- Follow best practices for the programming language you're using
- Test your code before submitting

## 📘 DSA Snippets (Python)

Beginner-friendly algorithm implementations with example usage:

- Sorting: `code-snippets/algorithms/sorting/` with `quick_sort.py`, `merge_sort.py`, `insertion_sort.py`, `selection_sort.py`, `heap_sort.py`, `radix_sort.py`
- Searching: `code-snippets/algorithms/searching/` with `linear_search.py`, `binary_search.py`
- Graphs: `code-snippets/algorithms/graphs/` with `bfs_dfs.py` (BFS/DFS), `dijkstra.py` (shortest paths)
- Disjoint Sets: `code-snippets/data-structures/disjoint-sets/` with `union_find.py`
- Techniques: `code-snippets/algorithms/techniques/` with `sliding_window.py`

### Run the examples (Windows):

```
python code-snippets\algorithms\sorting\quick_sort.py
python code-snippets\algorithms\sorting\merge_sort.py
python code-snippets\algorithms\sorting\insertion_sort.py
python code-snippets\algorithms\sorting\selection_sort.py
python code-snippets\algorithms\sorting\heap_sort.py
python code-snippets\algorithms\sorting\radix_sort.py
python code-snippets\algorithms\searching\linear_search.py
python code-snippets\algorithms\searching\binary_search.py
python code-snippets\algorithms\graphs\bfs_dfs.py
python code-snippets\algorithms\graphs\dijkstra.py
python code-snippets\data-structures\disjoint-sets\union_find.py
python code-snippets\algorithms\techniques\sliding_window.py
```

Each file prints sample outputs to demonstrate how the algorithm works. Feel free to open the files and tweak inputs to deepen understanding.

## 🌈 Happy Hacking!

Thank you for contributing to open source! Every contribution, no matter how small, makes a difference. Let's make Hacktoberfest 2025 amazing together!
Expand Down
13 changes: 13 additions & 0 deletions code-snippets/algorithms/graphs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Graph Algorithms (Python)

This folder contains basic graph algorithms:
- `bfs_dfs.py`: Breadth-First Search (BFS) and Depth-First Search (DFS)
- `dijkstra.py`: Dijkstra's shortest path (non-negative weights)

## Run Examples (Windows)
```
python code-snippets\algorithms\graphs\bfs_dfs.py
python code-snippets\algorithms\graphs\dijkstra.py
```

Each script includes example graphs and prints traversal or shortest path results.
73 changes: 73 additions & 0 deletions code-snippets/algorithms/graphs/bfs_dfs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""
Breadth-First Search (BFS) and Depth-First Search (DFS)
Graph is represented as adjacency list: dict[node] = list[neighbor]
"""
from collections import deque
from typing import Dict, List, Hashable, Set

Graph = Dict[Hashable, List[Hashable]]


def bfs(graph: Graph, start: Hashable) -> List[Hashable]:
"""Return list of nodes in BFS order from start."""
visited: Set[Hashable] = set()
order: List[Hashable] = []
q = deque([start])
visited.add(start)

while q:
node = q.popleft()
order.append(node)
for nei in graph.get(node, []):
if nei not in visited:
visited.add(nei)
q.append(nei)
return order


def dfs_recursive(graph: Graph, start: Hashable) -> List[Hashable]:
visited: Set[Hashable] = set()
order: List[Hashable] = []

def helper(node: Hashable):
visited.add(node)
order.append(node)
for nei in graph.get(node, []):
if nei not in visited:
helper(nei)

helper(start)
return order


def dfs_iterative(graph: Graph, start: Hashable) -> List[Hashable]:
visited: Set[Hashable] = set()
order: List[Hashable] = []
stack: List[Hashable] = [start]

while stack:
node = stack.pop()
if node in visited:
continue
visited.add(node)
order.append(node)
# Add neighbors in reverse to mimic recursive order (optional)
for nei in reversed(graph.get(node, [])):
if nei not in visited:
stack.append(nei)
return order


if __name__ == "__main__":
g = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
}

print("BFS from A:", bfs(g, 'A'))
print("DFS recursive from A:", dfs_recursive(g, 'A'))
print("DFS iterative from A:", dfs_iterative(g, 'A'))
58 changes: 58 additions & 0 deletions code-snippets/algorithms/graphs/dijkstra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""
Dijkstra's Algorithm for shortest paths from a source node
Graph representation: dict[node] = list[(neighbor, weight)]
Assumes non-negative edge weights.
"""
from typing import Dict, List, Tuple, Hashable
import heapq

Graph = Dict[Hashable, List[Tuple[Hashable, float]]]


def dijkstra(graph: Graph, start: Hashable) -> Tuple[Dict[Hashable, float], Dict[Hashable, Hashable | None]]:
"""
Return (dist, prev) where:
- dist[node] is the shortest distance from start to node
- prev[node] is the predecessor of node on the shortest path
"""
dist: Dict[Hashable, float] = {node: float('inf') for node in graph}
prev: Dict[Hashable, Hashable | None] = {node: None for node in graph}
dist[start] = 0.0

pq: List[Tuple[float, Hashable]] = [(0.0, start)]

while pq:
d, node = heapq.heappop(pq)
if d > dist[node]:
continue # Skip outdated entry
for nei, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nei, float('inf')):
dist[nei] = nd
prev[nei] = node
heapq.heappush(pq, (nd, nei))

return dist, prev


def reconstruct_path(prev: Dict[Hashable, Hashable | None], target: Hashable) -> List[Hashable]:
path: List[Hashable] = []
cur: Hashable | None = target
while cur is not None:
path.append(cur)
cur = prev[cur]
return list(reversed(path))


if __name__ == "__main__":
g: Graph = {
'A': [('B', 4), ('C', 2)],
'B': [('C', 5), ('D', 10)],
'C': [('E', 3)],
'D': [('F', 11)],
'E': [('D', 4)],
'F': []
}
dist, prev = dijkstra(g, 'A')
print("Distances:", dist)
print("Path A->F:", reconstruct_path(prev, 'F'))
13 changes: 13 additions & 0 deletions code-snippets/algorithms/searching/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Searching Algorithms (Python)

This folder contains searching algorithms:
- `linear_search.py`: Find index(es) of a target in an array
- `binary_search.py`: Binary search on a sorted array

## Run Examples (Windows)
```
python code-snippets\algorithms\searching\linear_search.py
python code-snippets\algorithms\searching\binary_search.py
```

These scripts include simple examples and can be modified for custom inputs.
25 changes: 25 additions & 0 deletions code-snippets/algorithms/searching/linear_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
Linear Search
Time: O(n)
Space: O(1)
"""
from typing import List, Any


def linear_search(arr: List[Any], target: Any) -> int:
"""Return first index of target in arr, or -1 if not found."""
for i, val in enumerate(arr):
if val == target:
return i
return -1


def linear_search_all(arr: List[Any], target: Any) -> List[int]:
"""Return all indices where target appears in arr."""
return [i for i, val in enumerate(arr) if val == target]


if __name__ == "__main__":
data = [3, 5, 2, 5, 9]
print("First index of 5:", linear_search(data, 5))
print("All indices of 5:", linear_search_all(data, 5))
21 changes: 21 additions & 0 deletions code-snippets/algorithms/sorting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Sorting Algorithms (Python)

This folder contains common sorting algorithms with simple examples:
- `quick_sort.py`: Functional and in-place Quick Sort
- `merge_sort.py`: Merge Sort
- `insertion_sort.py`: Insertion Sort
- `selection_sort.py`: Selection Sort
- `heap_sort.py`: Heap Sort (using `heapq`)
- `radix_sort.py`: Radix Sort (LSD, non-negative integers)

## Run Examples (Windows)
```
python code-snippets\algorithms\sorting\quick_sort.py
python code-snippets\algorithms\sorting\merge_sort.py
python code-snippets\algorithms\sorting\insertion_sort.py
python code-snippets\algorithms\sorting\selection_sort.py
python code-snippets\algorithms\sorting\heap_sort.py
python code-snippets\algorithms\sorting\radix_sort.py
```

Each script prints sample outputs and can be edited to test custom inputs.
18 changes: 18 additions & 0 deletions code-snippets/algorithms/sorting/heap_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
Heap Sort using Python's heapq (min-heap)
Time: O(n log n)
Space: O(n) due to heap container
"""
from typing import List, Any
import heapq


def heap_sort(arr: List[Any]) -> List[Any]:
heap = arr[:]
heapq.heapify(heap)
return [heapq.heappop(heap) for _ in range(len(heap))]


if __name__ == "__main__":
data = [4, 10, 3, 5, 1]
print("Heap Sort:", heap_sort(data))
23 changes: 23 additions & 0 deletions code-snippets/algorithms/sorting/insertion_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
Insertion Sort implementation (returns a new sorted list)
Time: O(n^2)
Space: O(1)
"""
from typing import List, Any


def insertion_sort(arr: List[Any]) -> List[Any]:
a = arr[:]
for i in range(1, len(a)):
key = a[i]
j = i - 1
while j >= 0 and a[j] > key:
a[j + 1] = a[j]
j -= 1
a[j + 1] = key
return a


if __name__ == "__main__":
data = [9, 1, 5, 3, 7]
print("Insertion Sort:", insertion_sort(data))
36 changes: 36 additions & 0 deletions code-snippets/algorithms/sorting/merge_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""
Merge Sort implementation (returns a new sorted list)
Time: O(n log n)
Space: O(n)
"""
from typing import List, Any


def merge_sort(arr: List[Any]) -> List[Any]:
if len(arr) <= 1:
return arr[:]

mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return _merge(left, right)


def _merge(left: List[Any], right: List[Any]) -> List[Any]:
i = j = 0
merged: List[Any] = []
while i < len(left) and j < len(right):
if left[i] <= right[j]:
merged.append(left[i])
i += 1
else:
merged.append(right[j])
j += 1
merged.extend(left[i:])
merged.extend(right[j:])
return merged


if __name__ == "__main__":
data = [5, 2, 4, 6, 1, 3]
print("Merge Sort:", merge_sort(data))
Loading