算法核心:
把 序 列 分 成 若 干 组 , 每 组 进 行 直 接 插 入 排 序 , 再 逐 步 合 并 已 经 有 序 的 若 干 个 组 \color{red}{把序列分成若干组,每组进行直接插入排序,再逐步合并已经有序的若干个组} 把序列分成若干组,每组进行直接插入排序,再逐步合并已经有序的若干个组
( 这 里 的 分 组 不 是 简 单 的 分 成 若 干 段 , 而 是 每 隔 n 个 为 一 组 , 如 下 图 ) \color{red}{(这里的分组不是简单的分成若干段,而是每隔n个为一组,如下图)} (这里的分组不是简单的分成若干段,而是每隔n个为一组,如下图)
( 所 谓 “ 逐 步 ” 是 把 “ 每 隔 n 个 ” 的 n 逐 渐 缩 小 成 1 ) \color{red}{(所谓“ 逐步 ”是把“每隔n个”的n逐渐缩小成1)} (所谓“逐步”是把“每隔n个”的n逐渐缩小成1)
( 因 为 当 序 列 很 长 时 , 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;
}
}
}
}
}
}