希尔排序:
思想:
希尔排序是为了防止直接插入排序出现最坏情况所做的一种改进,将原本的排序过程分为预排序和直接插入排序两个阶段。
预排序阶段:将整个预排序的序列分为若干个待排序的子序列,分别进行插入排序,然后依次缩减分量;
直接插入排序阶段:待增量不断缩减后,序列基本达到有序状态,此时在进行一次直接插入排序。
图解示例(红色为有序序列黑色为无序序列)
代码实现:
#include<iostream> #include<assert.h> using namespace std; template<class T> void Print(const T* a, size_t n) { for (size_t i = 0; i < n; ++i) { cout << a[i] << " "; } cout << endl; } template<class T> struct Less //升序 { bool operator()(const T& l, const T& r) { return l < r; } }; template <class T> struct Great //降序 { bool operator()(const T& l, const T& r) { return l > r; } }; template<class T,class Compare> void ShellSort(T* a,size_t n) { assert(a); int gap = n; while (gap > 1) { gap = gap / 3 + 1; //+1是为了最后一次对全体数据进行插入排序 for (size_t i = gap; i < n; i++) { int end = i - gap; T tmp = a[i]; while (end >= 0) { if (Compare()(tmp, a[end])) { a[end + gap] = a[end]; end = end - gap; } else break; } a[end + gap] = tmp; } } } void TestShellSort() { int a[] = { 3, 5, 7, 2, 4, 1, 9, 8, 6 }; ShellSort<int, Less<int>>(a, sizeof(a) / sizeof(a[0])); Print(a, sizeof(a) / sizeof(a[0])); ShellSort<int, Great<int>>(a, sizeof(a) / sizeof(a[0])); Print(a, sizeof(a) / sizeof(a[0])); }
执行结果:
复杂度和稳定性:
时间复杂度:O(N)~O(N^2)
空间复杂度:O(1)
稳定性:不稳定
