shell排序就是采取跳跃分割的策略,将相距某个”增量“的记录成一个子序列,这样能保证在子序列内分别进行直接插入排序后得到的结果时基本有序而不是局部有序,再通过循环执行,最后实现shell排序。
shell排序算法如下
26行这里的 intcrement 就是开头说的增距, 大家可根据喜好设计或者计算一下如何才能优化算法;
33、34行,36行实现两个值的交换
剩下的简单,大家可以假设一个随机数组,跟着这个程序一步步看,还有那个增量必须大于1,否者为0自己与自己比较没有意义。
下面看整体代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define num 20
int main()
{
srand(time(NULL));
int arr[num];
arr[0] = 0; //将arr[0]置0,作为交换数值的中间变量(相当于头节点)
for(int i = 1; i < num; i++) //随机生成一些数据
arr[i] = rand()%100;
printf("排序前\n");
for(int i = 1; i < num; i++) //将数据挨个输出,便于排序后对比
{
printf("%d ",arr[i]);
}
int i, j;
int increment = num;
do //shell排序主体
{
increment = increment/3+1;
for(i = increment+1; i < num; i++)
{
if(arr[i] < arr[i-increment]) //将arr[i]有序插入
{
arr[0] = arr[i]; //将arr[i]的值暂存于arr[0]
for(j = i-increment; j > 0 && arr[0] < arr[j]; j-=increment)
arr[j+increment] = arr[j]; //找到位置插入
arr[j+increment] = arr[0]; //插入,完成一次交换
}
}
}while(increment > 1);
printf("\n排序后\n");
for(int i = 1; i < num; i++) //输出排序后的结果
{
printf("%d ",arr[i]);
}
printf("\n");
}
结果