算法总结(4)希尔排序(Shell排序)

     已经总结了3种简单的基本排序算法,现在开始讲的是一些复杂,但是更高效,在数据量大时速度明显更快的一些排序算法,首先讲的是希尔排序。

     一.算法思路

     希尔排序又称为“缩小增量排序”,是一种插入排序类的算法。

     考虑先排序部分原始数组,在它们至少局部有序的情况下去排序整个数组。子数组有序将比初始情况更接近整体有序的最好情况。

     思路:选择第一个增量d1<n,把全部记录按此值从第一个记录分组,所有距离为d1的记录为一组。在各组内进行插入排序;然后缩小间隔,取第二个增量d2<d1;重复,直到di=1为止,即把所有记录放在同一组内排序。

     特点:每次以不同的增量进行插入排序。到最后一趟排序时,许多记录已经有序,不需要多少移动。希尔排序是不稳定的排序方法。

     (稳定性概念:两个相同的值,排序前后的顺序不变;稳定的重要性:交换元素存在开销,按照基数排序,不稳定排序无法完成基数排序。当对基本数据类型的元素进行排序时,使用不稳定的排序方法;非基本数据类型时,则使用稳定的排序方法。)

     (感觉稳定性的理解很重要,后面写一篇来总结一下所有算法的稳定性)

     二.伪代码

     把a分为h个子数组;

             for i=1 to h

                   排序子数组i;

             排序总数组。

     三.代码实现

/**
 * @author garypotter
 * @version 创建时间:2016年4月2日 下午4:12:17
 * @TODO
 * 类说明
 */


public class ShellSort {
	public static void main(String[] args) {
		Object[] a={5,2,3,8,1,9,10,13,4,11};
		shellsort(a);
		
		System.out.println("result:"+a[0]+" "+a[1]+" "+a[2]+" "+a[3]+" "+a[4]+" "+a[5]+" "+a[6]+" "+a[7]+" "+a[8]+" "+a[9]);
	
	}
	
	public static void shellsort(Object[] a){
		int i,j,k,h,start;
		int increments[]=new int[20];
		//根据a的大小计算增量并存入数组
		for(h=1,i=0;h<a.length;i++){
			increments[i]=h;
            h=3*h+1;
		}
		
		
		//最外面的循环控制增量的变化,从最大的增量依次变小,最终为1
		for(i=i-1;i>=0;i--){           //注意i-1这一句,因为上面的i在判断是否超出之前就已经i++了,所以其实应该最后一个元素应该从i-1开始
			h=increments[i]; //获取增量的值,即同一组的间隔值,增量从大到小取出
			System.out.println(h);
			for(start=h;start<2*h;start++){//增量为h,表示分为h个子数组来排序,h在此处不会变了
				//start从h到2h,是不同组的第二个元素!!!
				//插入排序开始
				for(j=start;j<a.length;){            //其实这个start不是第一个元素,而是第二个元素
					Comparable tmp=(Comparable) a[j];//这个就是待插入的值,来进行比较,首先插入的就是第二个元素!!!!
					k=j;
					while(k-h>=0&&tmp.compareTo(a[k-h])<0){
						//k-h>=0表示还有前一个元素
						a[k]=a[k-h];
						k=k-h;
					}
					a[k]=tmp;
					j+=h;
				}
				//插入循环结尾
			}
			
		}
			
	}

}


     



     

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值