Day 6: Advanced Sorting Algorithms - Insertion Sort and Merge Sort

Advanced Sorting Algorithms - Insertion Sort and Merge Sort #

Welcome to Day 6 of our 60 Days of Coding Algorithm Challenge! Today, we’ll delve into two more advanced sorting algorithms: Insertion Sort and Merge Sort. These sorting techniques offer different trade-offs in terms of efficiency and complexity.

Insertion Sort #

Insertion Sort is a simple and intuitive sorting algorithm that builds the final sorted array one item at a time. It is much less efficient on large lists than more advanced algorithms like Merge Sort.

How It Works: #

  • It iterates through the array and, for each element, inserts it into its correct position relative to the already sorted elements on its left.

Example: #

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
    return arr

Time Complexity: #

  • Best Case: O(n) when the array is already sorted.
  • Average and Worst Case: O(n^2) when the array is in reverse order.

Merge Sort #

Merge Sort is a more complex, yet efficient, divide-and-conquer sorting algorithm. It splits the array into halves, sorts each half, and then merges them back together.

How It Works: #

  • Divide the array into two halves.
  • Conquer by recursively sorting each half.
  • Combine the two halves by merging them into a single sorted array.

Example: #

def merge_sort(arr):
    if len(arr) > 1:
        mid = len(arr) // 2
        left_half = arr[:mid]
        right_half = arr[mid:]

        merge_sort(left_half)
        merge_sort(right_half)

        i = j = k = 0

        while i < len(left_half) and j < len(right_half):
            if left_half[i] < right_half[j]:
                arr[k] = left_half[i]
                i += 1
            else:
                arr[k] = right_half[j]
                j += 1
            k += 1

        while i < len(left_half):
            arr[k] = left_half[i]
            i += 1
            k += 1

        while j < len(right_half):
            arr[k] = right_half[j]
            j += 1
            k += 1

    return arr

Time Complexity: #

  • All Cases: O(n log n), making it more efficient than Bubble, Selection, or Insertion Sort for large datasets.

Comparison of Insertion Sort and Merge Sort #

  • Insertion Sort is simple and works well for small or nearly sorted arrays but is inefficient for large datasets.
  • Merge Sort is more complex but handles large datasets efficiently due to its O(n log n) time complexity.

Exercise #

  1. Implement the Merge Sort algorithm and test it on arrays of various sizes.
  2. Compare the performance of Insertion Sort and Merge Sort on the same dataset.
  3. Modify the Insertion Sort algorithm to handle a list of strings instead of numbers.

Summary #

Understanding these advanced sorting algorithms is essential for writing efficient code. While Insertion Sort is simple and intuitive, Merge Sort introduces the power of the divide-and-conquer approach. Tomorrow, we’ll explore another powerful algorithm: Quick Sort.

Stay tuned!