这里我只写了第一趟的排序手算结果,后面都跟第一趟差不多的。
/*
基本思想
{
插入排序:每次将一个待排序的记录按其关键字大小插入前面已经排好序的子序列,直到全部记录插入完成。(直接插入排序,折半插入排序,希尔排序)
希尔插入排序步骤:
{
基本思想:将待排序的顺序表分割成若干个子表,对各个子表分别进行插入排序,当整个表中的元素“基本有序”时,在对全体记录进行一次直接插入排序
1.先取一个小于n的步长d1,把表中的全部记录分成d1组,所有距离为d1的倍数的记录放在一组,在各个组内进行插入排序
2.然后取第二个步长d2<d1,重复上述操作,直到d=1.
}
希尔插入排序算法分析:
{
空间效率:O(1),仅使用了常数个辅助单元
最坏情况下时间复杂度为:O(n^2)
稳定性:不稳定
适用性:适用于线性表为顺序存储的情况
}
}
*/
#include<stdio.h>
#include<stdlib.h>
#define size 15
typedef struct
{
int data[size];
int length;
}sqlist;
//随机建表
bool creatlist(sqlist &s)
{
int i;
i=1;
s.data[0]; //作为暂存单元
s.length=0;
while(i<=size-1)
{
s.data[i]=rand()%50+12;
i++;
s.length++;
}
printf("顺序表建立成功!长度为%d\n",s.length);
return true;
}
//输出顺序表
void pirintlist(sqlist s)
{
int i;
for(i=1;i<=s.length;i++)
{
printf("%d ",s.data[i]);
}
}
//希尔插入排序
void ShellSort(sqlist &s,int len) //len=s.length
{
int i,j,step;
int f=1;
for(step=len/2;step>=1;step/=2)//步长间隔每次减半
{
for(i=step+1;i<=len;i++)//这里step+1,是因为我是从数字位序1开始存的数据
{
if(s.data[i]<s.data[i-step])
{
s.data[0]=s.data[i];
for(j=i-step;s.data[j]>s.data[0]&&j>0;j=j-step)
{
s.data[j+step]=s.data[j];
}
s.data[j+step]=s.data[0];
}
}
printf("\n长度为%d\n第%d趟排序结果为:\n",step,f++);
pirintlist(s);
}
}
int main()
{
sqlist s;
creatlist(s);
pirintlist(s);
ShellSort(s,s.length);
printf("\n排序后顺序表内容为:\n");
pirintlist(s);
return 0;
}
实验结果图
代码如有错误或者需要改正的地方,欢迎大佬进行改正!