希尔排序(Shell Sort)
希尔排序(Shell Sort)是插入排序的一种优化版本,也称为缩小增量排序。它的基本思想是:先将整个待排序的记录序列分割成为若干子序列(由相隔某个“增量”的记录组成)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
希尔排序的增量序列可以有多种选择,其中Hibbard增量序列Δk=2k−1−1是较常使用的一种,但这不是唯一的。这里我们简单介绍使用Hibbard增量序列的希尔排序。
以下是希尔排序的C++代码示例:
不利于理解的地方:i从gap开始,单纯就是为了前面几次插入排序,少算进来几个元素。
按理来说应该是0, gap, 2 * gap; 1, 1 + gap, 1 + 2*gap。
#include <iostream>
#include <vector>
void shellSort(std::vector<int>& arr) {
int n = arr.size();
int gap = n / 2; // 初始增量
// 增量逐渐减小
while (gap > 0) {
// 对每个子序列进行插入排序
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j = i;
// 插入排序
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
gap /= 2; // 减小增量
}
}
int main() {
std::vector<int> arr = {9, 8, 3, 7, 5, 6, 4, 1};
std::cout << "Original array: ";
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
shellSort(arr);
std::cout << "Sorted array: ";
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
在这个示例中,shellSort 函数接收一个整数向量 arr 作为参数,并使用希尔排序算法对其进行排序。在 main 函数中,我们创建了一个待排序的向量,并调用 shellSort 函数进行排序。然后,我们打印出排序前后的向量以验证排序结果。
希尔排序的时间复杂度与增量序列的选取有关,这里给出的只是其中一种实现方式。在实际应用中,希尔排序的性能通常优于直接插入排序,但是不如快速排序、归并排序等更高效的排序算法。