目录
简介:
1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
算法描述:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:
- 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
- 按增量序列个数k,对序列进行k 趟排序;
- 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
代码实现:
#include<iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define range 10000
void myrandom(int a[],int len)
{
srand((unsigned) time(NULL));
for(int i=0;i<len;i++)
a[i]=rand()%range+1;
}
void shellSort(int a[],int len)
{
int gap=len/2; // gap为增量
int i,j;
for(;gap>0;gap/=2) // 每次除二,逐渐缩小增量。
{
for(i=gap;i<len;i++)
{
int num=a[i];
for(j=i-gap;j>=0&&a[j]>num;j-=gap)
{
a[j+gap]=a[j];
}
a[j+gap]=num;
}
}
}
int main()
{
clock_t start,end;
start=clock();
freopen("out_arr.txt","r",stdin);
freopen("out希尔排序.txt","w",stdout);
int arr[range];
int n=range;
for(int i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
shellSort(arr,n);
for(int i=0;i<n;i++)
{
printf("%5d ",arr[i]);
if((i+1)%50==0)
printf("\n");
}
end=clock();
cout<<"希尔排序用时:"<<(float)(end-start)*1000.0/CLOCKS_PER_SEC<<"ms"<<endl;
return 0;
}
测试结果:
总结一下:
希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。
间隔序列也就是增量,但实现增量的缩小方法很多。上面代码仅找了一种简便的缩小方式。
希尔排序是不稳定的。它是第一个突破O(n2)的排序算法。
说点题外话,我暂时也不知道这些排序算法的差别,可能我的测试数据太小了,常常听我老师说好好学,打好基本功,就像建房子打好地基一样,基础好,后面省劲,现在需要的是静下心来打好基础,沉下来,沉下来,不能浮躁,不然以后你的boss,让你做某一方面的研究,你才发现你本科时没认真学,…………,在合适的年龄做最合适的事,方可无悔。
下午有点浮躁,给自己打点鸡血。O(∩_∩)O哈哈~
小伙伴们,如果还看不懂,在评论区留言,乐意解答。