希尔排序

希尔排序

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的板本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。

排序方法

  1. 取间距step,对所有数按照下标对step的剩余类进行分组,也就是间隔为step倍数的为一组。

  2. 在组内进行直接插入排序。

  3. 缩小step。

  4. step为1结束。否则跳转2。

时间复杂度

与参数step相关。

时间复杂度的下界为O(nlog22n)。

基本上为O(n1.22)

合理性分析

实际上希尔排序在实际运用中已经很少会见到了。

我认为他的主要价值在于认识和证明希尔排序的合理性。

直观上来说,每次插入排序都能让数列看上去更有顺序一些,然后前面大间距的插入排序帮助后面小间距的插入排序降低复杂度。

但这个要证明的话很不简单。

其实是要证明间隔k排序之后再进行间隔h排序,h排序不会影响k排序。

意思就是隔k个数有序,再将隔h个数排序,新序列仍然隔k个数有序。

h-排序 不影响 k-排序

引理 两个序列{x1,,xn+r}和{y1,,ym+r}中满足

x1<=ym,,xr<=ym+r

如果对x和y排序,则仍满足如上规则。

证明思路 先考虑两个r个数序列,然后不断加数。

以下证明:

对a进行k排序

a1,,a1+tk

a2,,a2+tk

这些都是有序的

再进行h排序

a1,,a1+ph

a2,,a2+ph

其中取一种情况

a1,a1+h,

a1+k,a1+h+k,

类比于引理中的x,y。易得结果。

实现代码

#include <bits/stdc++.h>
using namespace std;
int a[100010];
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    int step = n / 3;
    while (step)
    {
        for (int i = step + 1; i <= n; ++i)
            for (int j = i; j >= step && a[j] < a[j - step]; j -= step)
                swap(a[j], a[j - step]);
        step /= 3;
    }
    for (int i = 1; i <= n; ++i)
        cout << a[i] << ' ';
    return 0;
}
posted @   cacu  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示