Shell Sort Algorithm in DSA Rust - Time & Space Complexity
We want to understand how the time taken by Shell Sort changes as the list size grows.
How does the number of steps increase when sorting bigger lists?
Analyze the time complexity of the following Shell Sort code.
fn shell_sort(arr: &mut [i32]) {
let n = arr.len();
let mut gap = n / 2;
while gap > 0 {
for i in gap..n {
let temp = arr[i];
let mut j = i;
while j >= gap && arr[j - gap] > temp {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
gap /= 2;
}
}
This code sorts an array by comparing elements far apart and gradually reducing the gap.
Look at the loops and repeated steps:
- Primary operation: The inner while loop that shifts elements to insert the current element in the right place.
- How many times: This inner loop runs multiple times for each element, depending on the gap and how unsorted the array is.
As the list size grows, the number of comparisons and shifts grows too, but not as fast as simple sorts.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20-30 operations |
| 100 | Few thousands of operations |
| 1000 | Hundreds of thousands of operations |
Pattern observation: The growth is faster than linear but slower than quadratic, improving over simple insertion sort.
Time Complexity: O(n^{1.5})
This means the time grows a bit faster than n times n square root, which is better than simple quadratic sorts.
[X] Wrong: "Shell Sort always runs in quadratic time like bubble sort or insertion sort."
[OK] Correct: Shell Sort uses gaps to reduce the number of shifts early on, so it usually runs faster than simple quadratic sorts.
Understanding Shell Sort's time complexity shows you how clever improvements can speed up simple ideas, a skill useful in many coding challenges.
"What if we changed the gap sequence to use a different pattern, like the Knuth sequence? How would the time complexity change?"
Practice
Shell Sort Algorithm?Solution
Step 1: Understand Shell Sort's approach
Shell sort starts by comparing elements far apart and reduces the gap over iterations.Step 2: Compare with other sorting methods
Unlike bubble or insertion sort, it uses gaps to improve efficiency before final insertion sort pass.Final Answer:
It sorts elements by comparing distant elements and gradually reducing the gap. -> Option AQuick Check:
Shell Sort = gap-based comparison [OK]
- Confusing Shell sort with bubble sort
- Thinking it only swaps adjacent elements
- Assuming it uses divide and conquer
arr?Solution
Step 1: Identify how gap is initialized in Shell Sort
The gap usually starts at half the array length to compare distant elements first.Step 2: Check Rust syntax correctness
Usinglet mut gap = arr.len() / 2;correctly initializes a mutable gap variable with half the length.Final Answer:
let mut gap = arr.len() / 2; -> Option CQuick Check:
Gap starts at half length [OK]
- Using multiplication instead of division for gap
- Not declaring gap as mutable
- Starting gap at array length or length minus one
arr = [9, 8, 3, 7, 5, 6, 4, 1]?
let mut arr = vec![9, 8, 3, 7, 5, 6, 4, 1];
let gap = 3;
for i in gap..arr.len() {
let temp = arr[i];
let mut j = i;
while j >= gap && arr[j - gap] > temp {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
println!("{:?}", arr);Solution
Step 1: Perform insertion with gap 3 on elements from index 3 to end
Start at i=3 (value 7), compare with arr[0]=9, since 9 > 7, shift 9 to index 3 and place 7 at index 0.Step 2: Repeat for i=4 to 7
i=4 (5) compares with arr[1]=8, shift 8 to 4, place 5 at 1; i=5 (6) compares with arr[2]=3 no shift; i=6 (4) compares with arr[3]=9 shifted to 6, then arr[0]=7 shifted to 3, place 4 at 0; i=7 (1) compares with arr[4]=8 shifted to 7, arr[1]=5 shifted to 4, place 1 at 1.Final Answer:
[4, 1, 3, 7, 5, 6, 9, 8] -> Option AQuick Check:
After gap 3 pass = [4,1,3,7,5,6,9,8] [OK]
- Not shifting elements correctly with gap
- Confusing indices during insertion
- Assuming no change after first pass
let mut gap = arr.len() / 2;
while gap > 0 {
for i in gap..arr.len() {
let temp = arr[i];
let mut j = i;
while j >= gap && arr[j - gap] < temp {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
gap /= 2;
}Solution
Step 1: Analyze the inner while condition
The conditionarr[j - gap] < tempcauses sorting in descending order, but Shell Sort usually sorts ascending.Step 2: Correct the comparison for ascending order
Changing it toarr[j - gap] > tempensures elements larger than temp shift right, sorting ascending.Final Answer:
Changearr[j - gap] < temptoarr[j - gap] > tempin inner while condition. -> Option BQuick Check:
Comparison sign fixes sorting order [OK]
- Using wrong comparison sign for sorting order
- Changing gap update incorrectly
- Removing essential loops
Solution
Step 1: Understand gap sequences impact
Using advanced gap sequences like Tokuda's improves efficiency by reducing comparisons and swaps.Step 2: Modify insertion to maintain stability
Avoid swapping equal elements during insertion to keep their original order, preserving stability.Final Answer:
Use a gap sequence like Tokuda's and modify insertion to avoid swapping equal elements. -> Option DQuick Check:
Advanced gaps + stable insertion = better Shell Sort [OK]
- Increasing gap size instead of decreasing
- Ignoring stability in sorting equal elements
- Using only gap=1 which is slow
- Replacing Shell Sort with bubble sort
Ready to prove it?
Pass the test and this pattern moves unknown
