希尔排序(Shell)

来源:互联网 发布:大学生应知相关法律 编辑:程序博客网 时间:2024/06/09 16:45
希尔排序(Shell)
======================================================
先取一个小于n(n为元素个数)的整数d1作为第一个增量,
所有距离为dl的倍数的记录放在同一个组中,这样全部记录就分成了d1个组,
先在各组内进行直接插入排序,@;

然后,取第二个增量d2(d2<d1)重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<;…<d2<d1),

即所有记录放在同一组中进行直接插入排序为止。

该方法实质上是一种分组插入方法

@处应该添加一句话:

各组内直接插入排序后,依次取
第1组第一个数,第2组第一个数,...,第d1组第一个数,
然后第1组第二个数,第2组第二个数,...,第d1组第二个数,
......

所得即为第一趟排序结果.

例如:分组后为
a1,a2,a3
b1,b2,b3
c1,c2,c3
则第一趟排序结果为:a1,b1,c1, a2,b2,c2, a3,b3,c3

增量序列的一个流行(但是不好)的选择是使用Shell建议的序列(希尔增量):d1=n/2, d2=d1/2 ...... ,1
其余的增量序列还有Hibbard:{1, 3, ..., 2^k-1}

原理图

Java实现:
public class ShellSort {public static void main(String[] args) {int []a = {70,30,40,10,80,20,90,100,75,60,45};shellSort(a);for(int i : a){System.out.print(i + ",");}}public static void shellSort(int []a){for(int gap=a.length/2; gap>0; gap/=2){//gap为增量(希尔增量),有几个增量就排序多少趟//每gap间隔的数进行插入排序;也就是各组内进行直接插入排序for(int i=gap; i<a.length; i++){int tmp = a[i];int j = i - gap;while(j>=0 && tmp<a[j]){a[j+gap] = a[j];j = j - gap;}a[j+gap] = tmp;}}}}
算法的稳定性:
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,
若经过排序,这些记录的相对次序保持不变,
即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,
则称这种排序算法是稳定的;否则称为不稳定的。

希尔排序的稳定性
由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,
但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,
最后其稳定性就会被打乱,所以shell排序是不稳定的

例如:{
数组有五个数字:{6,6,8,6,6},分别以{a,b,8,c,d}代替,容易分辨。

增量序列为2,1
则增量序列为2时:分成两组1>{a,8,d},排序后为{a,d,8},2>{b,c},排序后还是{b,c};总体排序后为a,b,d,c,8
则增量序列为1时:排序后还是a,b,d,c,8

综上,d,c都为6,顺序颠倒了。
}

参考:http://www.jb51.net/article/60656.htm



0 0
原创粉丝点击