1.算法思想:希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力加强版。
假设有这样一组数{5,4,8,9,7,10,12,3,2,6,1},如果我们以步长为4开始进行排序:
5,4,8,97,10,12,32,6,1
然后对每列进行排序:
2,4,1,35,6,8,97,10,12,
再以3为步长:
2,4,13,5,68,9,710,12,
排序后:
2,4,13,5,68,9,710,12,
最后以1为步长进行排序(此时就是简单的插入排序了)。
所以,步长的选择是希尔排序的重要部分,算法最开始以一定的步长进行排序,然后继续以更小的步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变成了直接插入排序,这就保证了数据一定会被全部排序。
2.时间复杂度:
步长序列的不同会导致最坏的时间复杂度情况的不同。
先用较长步长,后用小的,可以保证大的步长有序,小的步长也有序。用这样的步长序列的希尔排序比插入排序要快,甚至在小数组中比快速排序和堆排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。
3.算法稳定性:希尔排序中相等数据可能会交换位置,所以希尔排序是不稳定的算法。
4.直接插入排序和希尔排序的比较:
a.直接插入排序是稳定的;而希尔排序是不稳定的。
b.直接插入排序更适合于原始记录基本有序的集合。
c.希尔排序的比较次数和移动次数都要比直接插入排序少,当N越大时,效果越明显。
d.直接插入排序适用于链式存储结构;希尔排序不适用于链式结构。
5.算法步骤:a.确定步长gap为N/2,然后最后一次为1。b.对每列进行直接插入。
#includeusing namespace std;void ShellSort(int* arr, int length){ if (arr == NULL || length <= 0) { return; } for (int gap = length >> 1; gap > 0; gap >>= 1) { for (int i = gap; i < length; i++) { int temp = arr[i]; int j = i - gap; while (arr[j] > temp && j >= 0) { arr[j+gap] = arr[j]; j -= gap; } arr[j+gap] = temp; } }}int main(){ int arr[] = {2,5,1,3,8,7}; ShellSort((int*)arr, 6); for (int i = 0; i < 6; i++) { cout << arr[i] << " "; } return 0;}