Bird
Raised Fist0
DSA Rustprogramming~10 mins

Merge Sort as Divide and Conquer in DSA Rust - Execution Trace

Choose your learning style10 modes available
Concept Flow - Merge Sort as Divide and Conquer
Start: Full array
↓
Divide array into two halves
↓
Recursively sort left half
→Recursively sort right half
↓
Merge two sorted halves into one sorted array
↓
Return sorted array
Merge Sort splits the array into halves recursively, sorts each half, then merges them back in order.
Execution Sample
DSA Rust
fn merge_sort(arr: &mut [i32]) {
    if arr.len() > 1 {
        let mid = arr.len() / 2;
        merge_sort(&mut arr[..mid]);
        merge_sort(&mut arr[mid..]);
        merge(arr, mid);
    }
}
This code recursively splits the array and merges sorted halves.
Execution Table
StepOperationArray StateAction DetailVisual State
1Start[38, 27, 43, 3, 9, 82, 10]Full array to sort[38, 27, 43, 3, 9, 82, 10]
2Divide[38, 27, 43, 3, 9, 82, 10]Split into [38,27,43] and [3,9,82,10][38, 27, 43] | [3, 9, 82, 10]
3Divide Left[38, 27, 43]Split into [38] and [27,43][38] | [27, 43]
4Divide Right[3, 9, 82, 10]Split into [3,9] and [82,10][3, 9] | [82, 10]
5Divide Left-Right[27, 43]Split into [27] and [43][27] | [43]
6Divide Right-Left[3, 9]Split into [3] and [9][3] | [9]
7Divide Right-Right[82, 10]Split into [82] and [10][82] | [10]
8Merge Left-Right[27] and [43]Merge sorted [27] and [43][27, 43]
9Merge Right-Left[3] and [9]Merge sorted [3] and [9][3, 9]
10Merge Right-Right[82] and [10]Merge sorted [82] and [10][10, 82]
11Merge Left[38] and [27, 43]Merge sorted [38] and [27, 43][27, 38, 43]
12Merge Right[3, 9] and [10, 82]Merge sorted [3, 9] and [10, 82][3, 9, 10, 82]
13Merge All[27, 38, 43] and [3, 9, 10, 82]Merge sorted halves into final sorted array[3, 9, 10, 27, 38, 43, 82]
14End[3, 9, 10, 27, 38, 43, 82]Array fully sorted[3, 9, 10, 27, 38, 43, 82]
💡 All subarrays reduced to single elements and merged back sorted, completing the sort.
Variable Tracker
VariableStartAfter Step 2After Step 5After Step 8After Step 11After Step 13Final
arr[38, 27, 43, 3, 9, 82, 10][38, 27, 43] | [3, 9, 82, 10][38] | [27, 43][27, 43][27, 38, 43][3, 9, 10, 27, 38, 43, 82][3, 9, 10, 27, 38, 43, 82]
left_halfN/A[38, 27, 43][38][27, 43][27, 38, 43]N/AN/A
right_halfN/A[3, 9, 82, 10]N/AN/AN/A[3, 9, 10, 27, 38, 43, 82]N/A
Key Moments - 3 Insights
Why do we keep dividing the array until subarrays have only one element?
Because single-element arrays are already sorted, which is the base case for merging (see steps 3, 5, 6, 7 in execution_table).
How does merging two sorted halves keep the array sorted?
Merging compares elements from both halves and picks the smaller one step-by-step, ensuring the combined array is sorted (see steps 8, 9, 10, 11, 12, 13).
Why do we need to merge after sorting both halves recursively?
Because sorting halves separately doesn't sort the whole array; merging combines them in order to form a fully sorted array (see step 13).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 6, what are the two subarrays being merged next?
A[27] and [43]
B[3] and [9]
C[82] and [10]
D[38] and [27, 43]
💡 Hint
Check the 'Operation' and 'Array State' columns at step 6 and 9.
At which step does the array first become fully sorted?
AStep 8
BStep 11
CStep 13
DStep 14
💡 Hint
Look at the 'Visual State' column for the fully sorted array.
If the initial array had only 2 elements, how many divide steps would occur before merging?
A1
B2
C0
D3
💡 Hint
Refer to how the array is split until single elements in the execution_table steps 3 and 5.
Concept Snapshot
Merge Sort splits array into halves recursively
Sorts each half separately
Merges sorted halves into one sorted array
Base case: single-element arrays are sorted
Merging compares elements to keep order
Efficient divide and conquer sorting method
Full Transcript
Merge Sort is a sorting method that works by dividing the array into smaller parts until each part has one element. These single elements are considered sorted. Then, it merges these parts back together in order, comparing elements to keep the array sorted. This process repeats recursively, sorting left and right halves, then merging them. The key steps are dividing, sorting halves, and merging. The final result is a fully sorted array.

Practice

(1/5)
1. What is the main idea behind the Merge Sort algorithm in the context of divide and conquer?
easy
A. Select a pivot and partition the array around it
B. Sort the array by swapping adjacent elements repeatedly
C. Build a heap and extract elements in sorted order
D. Divide the array into halves, sort each half, then merge them

Solution

  1. Step 1: Understand divide and conquer in Merge Sort

    Merge Sort splits the array into two halves recursively until single elements remain.
  2. Step 2: Merge sorted halves

    After splitting, it merges the sorted halves back together to form a sorted array.
  3. Final Answer:

    Divide the array into halves, sort each half, then merge them -> Option D
  4. Quick Check:

    Divide and conquer = split, sort, merge [OK]
Hint: Remember: split, sort, then merge halves [OK]
Common Mistakes:
  • Confusing Merge Sort with Bubble Sort
  • Thinking Merge Sort uses a pivot like Quick Sort
  • Ignoring the merge step after dividing
2. Which of the following is the correct Rust function signature for a merge sort function that sorts a mutable slice of integers?
easy
A. fn merge_sort(arr: Vec<i32>) -> Vec<i32>
B. fn merge_sort(arr: &mut [i32])
C. fn merge_sort(arr: &[i32]) -> &[i32]
D. fn merge_sort(arr: &mut Vec<i32>) -> ()

Solution

  1. Step 1: Identify mutable slice parameter

    Merge sort modifies the array in place, so it needs a mutable slice: &mut [i32].
  2. Step 2: Check function return type

    In-place sorting returns nothing, so return type is omitted (unit type).
  3. Final Answer:

    fn merge_sort(arr: &mut [i32]) -> Option B
  4. Quick Check:

    Mutable slice input, no return [OK]
Hint: Use &mut [i32] for in-place sorting in Rust [OK]
Common Mistakes:
  • Using immutable slice &[i32] when mutation is needed
  • Returning a new vector instead of sorting in place
  • Incorrect return type for in-place function
3. What will be the output of the following Rust code snippet using merge sort on the array [4, 1, 3, 2]?
fn main() {
    let mut arr = [4, 1, 3, 2];
    merge_sort(&mut arr);
    println!("{:?}", arr);
}

fn merge_sort(arr: &mut [i32]) {
    let mid = arr.len() / 2;
    if mid == 0 { return; }
    merge_sort(&mut arr[..mid]);
    merge_sort(&mut arr[mid..]);
    let mut merged = arr.to_vec();
    merge(&arr[..mid], &arr[mid..], &mut merged[..]);
    arr.copy_from_slice(&merged);
}

fn merge(left: &[i32], right: &[i32], merged: &mut [i32]) {
    let mut i = 0;
    let mut j = 0;
    let mut k = 0;
    while i < left.len() && j < right.len() {
        if left[i] <= right[j] {
            merged[k] = left[i];
            i += 1;
        } else {
            merged[k] = right[j];
            j += 1;
        }
        k += 1;
    }
    while i < left.len() {
        merged[k] = left[i];
        i += 1;
        k += 1;
    }
    while j < right.len() {
        merged[k] = right[j];
        j += 1;
        k += 1;
    }
}
medium
A. [1, 2, 3, 4]
B. [4, 3, 2, 1]
C. [1, 3, 2, 4]
D. [2, 1, 3, 4]

Solution

  1. Step 1: Trace recursive splitting

    Array splits into [4,1] and [3,2], then further into single elements.
  2. Step 2: Merge sorted halves

    Merge [4] and [1] into [1,4], merge [3] and [2] into [2,3], then merge [1,4] and [2,3] into [1,2,3,4].
  3. Final Answer:

    [1, 2, 3, 4] -> Option A
  4. Quick Check:

    Sorted array = [1, 2, 3, 4] [OK]
Hint: Merge halves step-by-step to get sorted array [OK]
Common Mistakes:
  • Confusing merge order causing wrong output
  • Forgetting to copy merged array back
  • Incorrect base case stopping recursion too early
4. Identify the bug in this Rust merge sort implementation snippet:
fn merge_sort(arr: &mut [i32]) {
    let mid = arr.len() / 2;
    if arr.len() <= 1 { return; }
    merge_sort(&mut arr[..mid]);
    merge_sort(&mut arr[mid..]);
    let mut merged = arr.to_vec();
    merge(&arr[..mid], &arr[mid..], &mut merged[..]);
    arr.copy_from_slice(&merged);
}
medium
A. The base case condition is correct; no bug here
B. The slices passed to merge overlap and cause incorrect merging
C. The merge function is called with immutable slices, but merged is mutable
D. The base case condition should check if mid == 0, not arr.len() <= 1

Solution

  1. Step 1: Check base case

    The condition if arr.len() <= 1 { return; } correctly handles arrays of length 0 or 1.
  2. Step 2: Verify recursive calls

    Disjoint mutable slices arr[..mid] and arr[mid..] are sorted independently.
  3. Step 3: Examine merge

    Immutable borrows of disjoint slices to merge are temporary; writes to separate merged vec. No overlap or borrow issues.
  4. Final Answer:

    The base case condition is correct; no bug here -> Option A
  5. Quick Check:

    Disjoint slices + temporary borrows = safe [OK]
Hint: Verify disjoint slices and borrow lifetimes; this is correct [OK]
Common Mistakes:
  • Ignoring slice borrowing rules in Rust
  • Confusing base case condition with bug
  • Assuming immutable slices cause errors with mutable writes
5. Given a large array of integers with many duplicate values, how can you modify the merge step in merge sort to optimize performance by reducing unnecessary copying?
hard
A. Skip copying elements when both halves have equal values during merge
B. Avoid merging duplicates by sorting only unique elements
C. Use a stable merge that avoids copying duplicates by referencing indices
D. Count duplicates and merge them as a single element to reduce size

Solution

  1. Step 1: Understand stable merge importance

    Stable merge preserves order of equal elements and can optimize by referencing indices instead of copying repeatedly.
  2. Step 2: Avoid unnecessary copying of duplicates

    By using indices and stable merge logic, duplicates are merged efficiently without extra copying.
  3. Final Answer:

    Use a stable merge that avoids copying duplicates by referencing indices -> Option C
  4. Quick Check:

    Stable merge optimizes duplicate handling [OK]
Hint: Use stable merge to handle duplicates efficiently [OK]
Common Mistakes:
  • Trying to merge duplicates as single element (loses data)
  • Skipping copying equal elements breaks stability
  • Sorting only unique elements changes array content
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard