Skip to content

Commit ce0fc12

Browse files
Update sorting-algorithms.md
1 parent 368955a commit ce0fc12

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed

contrib/ds-algorithms/sorting-algorithms.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,3 +327,162 @@ print("Sorted array:", arr) # Output: [3, 9, 10, 27, 38, 43, 82]
327327
</br>
328328
<hr>
329329
</br>
330+
331+
# 5. Insertion Sort
332+
333+
Insertion sort is a straightforward and efficient sorting algorithm for small datasets. It builds the final sorted array one element at a time. It is much like sorting playing cards in your hands: you take one card at a time and insert it into its correct position among the already sorted cards.
334+
335+
**Algorithm Overview:**
336+
- **Start from the Second Element:** Begin with the second element, assuming the first element is already sorted.
337+
- **Compare with Sorted Subarray:** Take the current element and compare it with elements in the sorted subarray (the part of the array before the current element).
338+
- **Insert in Correct Position:** Shift all elements in the sorted subarray that are greater than the current element to one position ahead. Insert the current element into its correct position.
339+
- **Repeat Until End:** Repeat this process for all elements in the array.
340+
341+
## Example with Visualization
342+
Let's sort the list `[5, 3, 8, 1, 2]` using insertion sort.
343+
344+
**Step-by-Step Visualization:**
345+
**Initial List:** `[5, 3, 8, 1, 2]`
346+
347+
1. **Pass 1:**
348+
- Current element: 3
349+
- Compare 3 with 5, move 5 to the right: `[5, 5, 8, 1, 2]`
350+
- Insert 3 in its correct position: `[3, 5, 8, 1, 2]`
351+
352+
2. **Pass 2:**
353+
- Current element: 8
354+
- 8 is already in the correct position: `[3, 5, 8, 1, 2]`
355+
356+
3. **Pass 3:**
357+
- Current element: 1
358+
- Compare 1 with 8, move 8 to the right: `[3, 5, 8, 8, 2]`
359+
- Compare 1 with 5, move 5 to the right: `[3, 5, 5, 8, 2]`
360+
- Compare 1 with 3, move 3 to the right: `[3, 3, 5, 8, 2]`
361+
- Insert 1 in its correct position: `[1, 3, 5, 8, 2]`
362+
363+
4. **Pass 4:**
364+
- Current element: 2
365+
- Compare 2 with 8, move 8 to the right: `[1, 3, 5, 8, 8]`
366+
- Compare 2 with 5, move 5 to the right: `[1, 3, 5, 5, 8]`
367+
- Compare 2 with 3, move 3 to the right: `[1, 3, 3, 5, 8]`
368+
- Insert 2 in its correct position: `[1, 2, 3, 5, 8]`
369+
370+
## Insertion Sort Code in Python
371+
372+
373+
```python
374+
375+
def insertion_sort(arr):
376+
# Traverse from 1 to len(arr)
377+
for i in range(1, len(arr)):
378+
key = arr[i]
379+
# Move elements of arr[0..i-1], that are greater than key,
380+
# to one position ahead of their current position
381+
j = i - 1
382+
while j >= 0 and key < arr[j]:
383+
arr[j + 1] = arr[j]
384+
j -= 1
385+
arr[j + 1] = key
386+
387+
# Example usage
388+
arr = [5, 3, 8, 1, 2]
389+
insertion_sort(arr)
390+
print("Sorted array:", arr) # Output: [1, 2, 3, 5, 8]
391+
```
392+
## Complexity Analysis
393+
- **Worst Case:** `𝑂(𝑛^2)` comparisons and swaps. This occurs when the array is in reverse order.
394+
- **Best Case:** `𝑂(𝑛)` comparisons and `𝑂(1)` swaps. This happens when the array is already sorted.
395+
- **Average Case:** `𝑂(𝑛^2)` comparisons and swaps. This is the expected number of comparisons and swaps over all possible input sequences.
396+
397+
398+
</br>
399+
<hr>
400+
</br>
401+
402+
# 6. Heap Sort
403+
404+
Heap Sort is an efficient comparison-based sorting algorithm that uses a binary heap data structure. It divides its input into a sorted and an unsorted region and iteratively shrinks the unsorted region by extracting the largest (or smallest) element and moving it to the sorted region.
405+
406+
**Algorithm Overview:**
407+
- **Build a Max Heap:** Convert the array into a max heap, a complete binary tree where the value of each node is greater than or equal to the values of its children.
408+
- **Heapify:** Ensure that the subtree rooted at each node satisfies the max heap property. This process is called heapify.
409+
- **Extract Maximum:** Swap the root (the maximum element) with the last element of the heap and reduce the heap size by one. Restore the max heap property by heapifying the root.
410+
- **Repeat:** Continue extracting the maximum element and heapifying until the entire array is sorted.
411+
412+
## Example with Visualization
413+
414+
Let's sort the list `[5, 3, 8, 1, 2]` using heap sort.
415+
416+
1. **Build Max Heap:**
417+
- Initial array: `[5, 3, 8, 1, 2]`
418+
- Start heapifying from the last non-leaf node.
419+
- Heapify at index 1: `[5, 3, 8, 1, 2]` (no change, children are already less than the parent)
420+
- Heapify at index 0: `[8, 3, 5, 1, 2]` (swap 5 and 8 to make 8 the root)
421+
422+
2. **Heapify Process:**
423+
- Heapify at index 0: `[8, 3, 5, 1, 2]` (no change needed, already a max heap)
424+
425+
3. **Extract Maximum:**
426+
- Swap root with the last element: `[2, 3, 5, 1, 8]`
427+
- Heapify at index 0: `[5, 3, 2, 1, 8]` (swap 2 and 5)
428+
429+
4. **Repeat Extraction:**
430+
- Swap root with the second last element: `[1, 3, 2, 5, 8]`
431+
- Heapify at index 0: `[3, 1, 2, 5, 8]` (swap 1 and 3)
432+
- Swap root with the third last element: `[2, 1, 3, 5, 8]`
433+
- Heapify at index 0: `[2, 1, 3, 5, 8]` (no change needed)
434+
- Swap root with the fourth last element: `[1, 2, 3, 5, 8]`
435+
436+
After all extractions, the array is sorted: `[1, 2, 3, 5, 8]`.
437+
438+
## Heap Sort Code in Python
439+
440+
```python
441+
def heapify(arr, n, i):
442+
largest = i # Initialize largest as root
443+
left = 2 * i + 1 # left child index
444+
right = 2 * i + 2 # right child index
445+
446+
# See if left child of root exists and is greater than root
447+
if left < n and arr[largest] < arr[left]:
448+
largest = left
449+
450+
# See if right child of root exists and is greater than root
451+
if right < n and arr[largest] < arr[right]:
452+
largest = right
453+
454+
# Change root, if needed
455+
if largest != i:
456+
arr[i], arr[largest] = arr[largest], arr[i] # swap
457+
458+
# Heapify the root.
459+
heapify(arr, n, largest)
460+
461+
def heap_sort(arr):
462+
n = len(arr)
463+
464+
# Build a maxheap.
465+
for i in range(n // 2 - 1, -1, -1):
466+
heapify(arr, n, i)
467+
468+
# One by one extract elements
469+
for i in range(n - 1, 0, -1):
470+
arr[i], arr[0] = arr[0], arr[i] # swap
471+
heapify(arr, i, 0)
472+
473+
# Example usage
474+
arr = [5, 3, 8, 1, 2]
475+
heap_sort(arr)
476+
print("Sorted array:", arr) # Output: [1, 2, 3, 5, 8]
477+
```
478+
479+
## Complexity Analysis
480+
- **Worst Case:** `𝑂(𝑛log𝑛)`. Building the heap takes `𝑂(𝑛)` time, and each of the 𝑛 element extractions takes `𝑂(log𝑛)` time.
481+
- **Best Case:** `𝑂(𝑛log𝑛)`. Even if the array is already sorted, heap sort will still build the heap and perform the extractions.
482+
- **Average Case:** `𝑂(𝑛log𝑛)`. Similar to the worst-case, the overall complexity remains `𝑂(𝑛log𝑛)` because each insertion and deletion in a heap takes `𝑂(log𝑛)` time, and these operations are performed 𝑛 times.
483+
484+
</br>
485+
<hr>
486+
</br>
487+
488+

0 commit comments

Comments
 (0)