Shell Sort เป็นการปรับปรุงจาก Insertion Sort โดยเปรียบเทียบและสลับองค์ประกอบที่ห่างกันด้วย Gap (ช่องว่าง) ลดการเลื่อนข้อมูลจำนวนมากเมื่อค่าน้อยอยู่ไกลตำแหน่งที่ควรเป็น
ความซับซ้อน (Complexity)
| กรณี | Time Complexity |
|---|---|
| Best Case | O(n log n) |
| Average Case | ขึ้นอยู่กับ Gap Sequence (ประมาณ O(n^1.25) ถึง O(n^1.5)) |
| Worst Case | O(n²) (Gap sequence แบบเดิม) |
Space Complexity: O(1) (In-place)
Gap Sequences ที่นิยม
| Sequence | Formula | Worst Case |
|---|---|---|
| Shell (Original) | n/2, n/4, ..., 1 | O(n²) |
| Hibbard | 2^k - 1: 1, 3, 7, 15, ... | O(n^1.5) |
| Sedgewick | 4^k + 3·2^(k-1) + 1: 1, 5, 19, 41, ... | O(n^1.33) |
| Pratt | 2^p·3^q: 1, 2, 3, 4, 6, 8, 9, 12, ... | O(n log² n) |
| Tokuda | ceil((9·(9/4)^k - 4)/5) | O(n^1.25) - ค่อนข้างดีในทางปฏิบัติ |
แนวคิดการทำงาน (Original Shell Sequence)
gap = n/2- ทำ Insertion Sort บนแต่ละ "Sub-array" ที่ห่างกัน gap
gap = gap / 2- ทำซ้ำจน gap = 1 (Insertion Sort ปกติรอบสุดท้าย)
ตัวอย่างข้อมูล
Input: 23 56 97 21 35 689 854 12 47 66 Output: 12 21 23 35 47 56 66 97 689 854
อัลกอริทึม (Pseudocode)
shellSort(array, size)
for gap = size/2; gap > 0; gap /= 2:
for j = gap to size-1:
for k = j-gap; k >= 0; k -= gap:
if array[k+gap] >= array[k]: break
swap(array[k+gap], array[k])
ตัวอย่างโค้ด C++
#include <iostream>
using namespace std;
void shellSort(int *arr, int n) {
for (int gap = n/2; gap > 0; gap /= 2) {
for (int j = gap; j < n; j++) {
for (int k = j - gap; k >= 0; k -= gap) {
if (arr[k+gap] >= arr[k]) break;
swap(arr[k+gap], arr[k]);
}
}
}
}
void display(int *array, int size) {
for (int i = 0; i < size; i++) cout << array[i] << " ";
cout << endl;
}
int main() {
int n; cin >> n;
int arr[n];
for (int i = 0; i < n; i++) cin >> arr[i];
cout << "Before: "; display(arr, n);
shellSort(arr, n);
cout << "After: "; display(arr, n);
}
คุณสมบัติ
- In-place: O(1) space
- Not Stable: การสลับแบบ Gap อาจเปลี่ยนลำดับค่าเท่ากัน
- Adaptive: เร็วขึ้นถ้าข้อมูลเรียงแล้วบางส่วน
เมื่อไหร่ควรใช้?
- ข้อมูลขนาดกลาง (ไม่ใหญ่จนต้อง Merge/Quick/Heap)
- Embedded Systems: โค้ดสั้น ไม่ต้อง Recursion/Stack
- เมื่อต้องการ In-place และง่ายกว่า Quick Sort