📖 Scenario: You are working on a program that sorts a list of numbers to help organize data efficiently. Sorting is important in many real-life tasks like arranging books by their numbers or organizing files by date.
🎯 Goal: Build a Rust program that uses the merge sort algorithm to sort a list of numbers. You will create the data, set up a helper function, implement the merge sort logic, and finally print the sorted list.
📋 What You'll Learn
Create a vector called numbers with the exact values [38, 27, 43, 3, 9, 82, 10]
Create a function called merge_sort that takes a vector of i32 and returns a sorted vector
Use the divide and conquer approach inside merge_sort to split the vector and merge sorted halves
Print the sorted vector using println!
💡 Why This Matters
🌍 Real World
Merge sort is used in many software systems to efficiently sort large amounts of data, such as organizing records in databases or sorting files.
💼 Career
Understanding merge sort helps in technical interviews and is a foundation for learning more complex algorithms and data processing techniques.
Progress0 / 4 steps
1
Create the initial data vector
Create a vector called numbers with the exact values [38, 27, 43, 3, 9, 82, 10].
DSA Rust
Hint
Use let numbers = vec![38, 27, 43, 3, 9, 82, 10]; to create the vector.
2
Add the merge function to combine two sorted vectors
Add a function called merge that takes two sorted vectors of i32 named left and right, and returns a single sorted vector by merging them.
DSA Rust
Hint
The merge function compares elements from left and right vectors and pushes the smaller one to result.
3
Implement the merge_sort function using divide and conquer
Add a function called merge_sort that takes a vector of i32 named arr and returns a sorted vector. Use divide and conquer by splitting arr into halves, recursively sorting each half, and merging them with the merge function.
DSA Rust
Hint
Split the vector into two halves, recursively call merge_sort on each half, then merge the results.
4
Print the sorted vector
Call merge_sort with the numbers vector and print the sorted result using println!.
DSA Rust
Hint
Use let sorted_numbers = merge_sort(numbers); and then println!("{:?}", sorted_numbers); to print the sorted vector.
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
Step 1: Understand divide and conquer in Merge Sort
Merge Sort splits the array into two halves recursively until single elements remain.
Step 2: Merge sorted halves
After splitting, it merges the sorted halves back together to form a sorted array.
Final Answer:
Divide the array into halves, sort each half, then merge them -> Option D
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
Step 1: Identify mutable slice parameter
Merge sort modifies the array in place, so it needs a mutable slice: &mut [i32].
Step 2: Check function return type
In-place sorting returns nothing, so return type is omitted (unit type).
Final Answer:
fn merge_sort(arr: &mut [i32]) -> Option B
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
Step 1: Trace recursive splitting
Array splits into [4,1] and [3,2], then further into single elements.
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].
Final Answer:
[1, 2, 3, 4] -> Option A
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:
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
Step 1: Check base case
The condition if arr.len() <= 1 { return; } correctly handles arrays of length 0 or 1.
Step 2: Verify recursive calls
Disjoint mutable slices arr[..mid] and arr[mid..] are sorted independently.
Step 3: Examine merge
Immutable borrows of disjoint slices to merge are temporary; writes to separate merged vec. No overlap or borrow issues.
Final Answer:
The base case condition is correct; no bug here -> Option A
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
Step 1: Understand stable merge importance
Stable merge preserves order of equal elements and can optimize by referencing indices instead of copying repeatedly.
Step 2: Avoid unnecessary copying of duplicates
By using indices and stable merge logic, duplicates are merged efficiently without extra copying.
Final Answer:
Use a stable merge that avoids copying duplicates by referencing indices -> Option C
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 unknownstrongwhile earning +1 Grip toward your certificate.