您的位置:首页 > 其它

希尔排序(及其与直接插入排序的区别)

2015-10-10 21:27 1301 查看
希尔排序基本思想
基本思想:
  先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
 该方法实质上是一种分组插入方法。

Shell排序的算法实现

void ShellSort(ElemType A,int n)
{
int i,j,dk;
for(dk=n/2;dk>=1;dk=dk/2)//控制步长变化,每次步长缩小为原来的1/2,直到1
{
for(i=dk+1;i<n;i++)//前dk个默认为dk组的已序
{
if(A[i].key<A[i-dk].key)
{
A[0]=A[i];//暂存A[i],这里不是监视哨;
for(j=i-dk;j>0&&A[0].key<A[j].key;j-=dk)//选寻找插入点
A[j+dk]=A[j];//记录后移
A[j]=A[0];
}
}
}
}


与直接插入排序比较,希尔排序的改进如下:

1、增加了一个for语句,用于控制步长变化。

2、不设置监视哨,故在寻找插入点的for语句中增加j>0来防止访问越界。

其实,假如去掉这些改进,我们去掉外层的for,然后把dk替换成1,是否发现算法变成了没有设监视哨的直接插入排序?

void InsertSort(SeqList R,int n)
{
int i,j;
for(i=2;i<=n;i++)
{
if(R[i].key<R[i-1].key)
{
R[0]=R[i];
for(j=i-1;R[0].key<R[j].key;--j)
R[j+1]=R[j];
}
}
R[j]=R[0];
}


看看直接插入排序

性能分析:

1、空间复杂度O(1)。

2、时间复杂度:由于希尔排序的时间复杂度依赖于增量序列的函数。当n在某个特定的范围时,希尔的时间复杂度约为O(n^1.3),最坏的情况下希尔排序的时间复杂度为O(n^2);

到目前为止,尚未得出一个最好的增量方法序列,希尔提出的方法是d[1]=n/2,d[t]=d[t-1]/2,其中,增量取整数。

稳定性:不稳定
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: