高级排序之希尔排序

希尔排序是1959年某个叫希尔的数学大大发明的,它其实就是在插入排序的基础上做了一些优化,但是效率却不知道提高了多少倍,我估计几万倍应该有吧(纯属个人瞎蒙)。插入排序是一个一个来插,而希尔排序则是有一个间隔,比如在容量为10的数组里将索引为1和3和5,7插入排序, 2和5,8插入排序。在这其中有一个增量的概念,可别以为这个增量是随便取的,如果取的不科学,可是效率也会大大的下降哦。最科学的取法就是 n = (n * 3)+1。 n是增量,初始值为1,按照这个公式一直增加到array.length / 3这个位置左右,然后在运算一次这个公式,就是最大的增量了。

package sort;

public class ShellSort {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n = 1000000;
		int[] arr = new int[n];
		for (int i = n; i > 0; i--) {
			arr[i - 1] = i;
		}
		shellSort(arr);
		/*for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}*/
	}

	/**我自己写的,效率要低一点。
	 * @param arr
	 */
	public static void shellSort(int[] arr){
		int len = arr.length;
		int h = 1;
		while(h <= len/3){
			h = (h * 3) +1;
		}
		while(h > 0){
			for (int i = 0; i < len; i++) {
				while(i + h < len && arr[i] > arr[i+h]){
					int temp = arr[i];
					arr[i] = arr[i+h];
					arr[i+h] = temp;
				}
			}
			h = (h - 1)/3;
		}
	}
	
	
	/**书上例子,效率较高。
	 * @param arr
	 */
	public static void shellSort3(int[] arr){
		int i,j,n=1,temp,len = arr.length;
		//获取最大增量值
		while(n<=len/3)
			n = n*3+1;
		//增量等于1时是最后一次排序
		while(n > 0){
			for (i = n; i < len; i++) {
				temp = arr[i];
				j = i;
				//按照增量插入排序,由后往前排,这样效率高,我写的由前往后排,做了一些无用功。
				while(j >= n && arr[j - n] >= temp){
					arr[j] = arr[j - n];
					j-=n;
				}
				arr[j] = temp;
			}
			//增量递减公式
			n = (n - 1)/3;
		}
	}
	
}
 在我机器上逆序排100w数据耗时44毫秒,快吧,比归并排序快多了,而且不需要额外空间。算法复杂度和代码量也比较优,快速排序复杂了一点(我是说如果写的更可能完美的情况下)代码量也多。虽然比快速排序稍慢一点点,但是综合其他,我感觉是排序的首选。专家也推荐一般情况下用希尔排序,如果你要更快一点点的话,才考虑快速排序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值