希尔排序

算法核心:

把 序 列 分 成 若 干 组 , 每 组 进 行 直 接 插 入 排 序 , 再 逐 步 合 并 已 经 有 序 的 若 干 个 组 \color{red}{把序列分成若干组,每组进行直接插入排序,再逐步合并已经有序的若干个组}

( 这 里 的 分 组 不 是 简 单 的 分 成 若 干 段 , 而 是 每 隔 n 个 为 一 组 , 如 下 图 ) \color{red}{(这里的分组不是简单的分成若干段,而是每隔n个为一组,如下图)} n

( 所 谓 “ 逐 步 ” 是 把 “ 每 隔 n 个 ” 的 n 逐 渐 缩 小 成 1 ) \color{red}{(所谓“ 逐步 ”是把“每隔n个”的n逐渐缩小成1)} nn1

( 因 为 当 序 列 很 长 时 , n 得 设 置 得 大 一 些 ) \color{red}{(因为当序列很长时,n得设置得大一些)} n

( 直 接 插 入 排 序 的 话 , 我 有 写 过 博 客 ) : \color{green}{(直接插入排序的话,我有写过博客):} 直接插入排序
在这里插入图片描述

解析:(完整代码在最后)

一:参数

a数组保存了要排序的序列

n 为 n 个要排序数字

d数组保存了逐渐合并的 m 个跨度

二:具体代码解析
for(int j=0;j<n/span;j++){   //n组,一个循环分好一组
    for(int x=j+span;x<n;x+=span){
        y=x-span;
        z=x;
        while(y>=0&&a[y]>a[z]){  //插入排序
            int temp=a[y];
            a[y]=a[z];
            a[z]=temp;
            z=y;
            y-=span;
        }
    }
}

第一重 for循环:

循 环 操 作 若 干 个 组 \color{green}{循环操作若干个组}

第二重 for循环 和 while循环:

具 体 到 一 个 组 内 进 行 直 接 插 入 排 序 \color{green}{具体到一个组内进行直接插入排序}

void X(int *a,int n,int *d,int m){
    int span;
    int y;
    int z;
    for(int i=0;i<m;i++){
        span=d[i];
        if(span==1){  //为1的时候特殊处理,不然很麻烦
            for(int x=1;x<n;x+=span){
                y=x-span;
                z=x;
                while(y>=0&&a[y]>a[z]){
                    int temp=a[y];
                    a[y]=a[z];
                    a[z]=temp;
                    z=y;
                    y-=span;
                }
            }
        }
        else {                             //每一组不是连续的
            for(int j=0;j<n/span;j++){   //n组,一个循环分好一组
              for(int x=j+span;x<n;x+=span){
                  y=x-span;
                  z=x;
                  while(y>=0&&a[y]>a[z]){  //插入排序
                      int temp=a[y];
                      a[y]=a[z];
                      a[z]=temp;
                      z=y;
                      y-=span;
                  }
            }
        }
      }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值