排序算法之希尔排序,分步调试分析原理(java)。

希尔排序

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

最佳情况:
T(n) = O(nlog2 n) 最坏情况:T(n) = O(nlog2 n) 平均情况:T(n) =O(nlog2n)

代码实现:
希尔排序的移位法能够极大的提高运算速度,避免了交换法的大小过度比较。

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
//希尔排序
public class ShellSort {
	
	public static void main(String[] args) {
		int[] arr = {8,9,1,7,2,3,5,4,6,0};
		System.out.println("结果是:"+Arrays.toString(ShellsSortmv(arr)) );
		int[] arr2 = new int[80000];
		for(int i =0;i<80000;i++){
			arr2[i] =(int)( Math.random()*80000);	//[0-8000000]
		}
		SimpleDateFormat simdate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		System.out.println(simdate.format(new Date()));
		ShellsSortmv(arr2);
		//ShellsSortchange(arr2);
		System.out.println(simdate.format(new Date()));	
	}
	//希尔排序移位法
	//2020-11-09 22:35:27 437
	//2020-11-09 22:35:27 469
	public static int[] ShellsSortmv(int[] arr) {
		for(int step = arr.length/2;step > 0;step /= 2) {
			//step = arr.length/2;
			//从第step个元素 逐个对其所在的组直接插入 排序
			for(int i = step ;i<arr.length;i++) {
				int j=i;
				int temp = arr[j];
					while(j - step >=0 && temp <arr[j - step] ) {
						arr[j] =arr[j-step];
						j-=step;
					}
					//退出循环,就找到了temp插入的位置
					arr[j] = temp ;
			}
		}
		return arr;
	}

	//希尔排序交换法
	//2020-11-09 22:36:08 970
	//2020-11-09 22:36:18 314
	public static int[] ShellsSortchange(int[] arr) {
		int temp = 0;
		for(int step = arr.length/2;step > 0;step /= 2) {
			//step = arr.length/2;
			//遍历各组中所有的元素(共i组,每组有)
			for(int i = step ;i<arr.length;i++) {
				for(int j = i-step ;j>=0;j-=step) {
					//如果当前元素大于加上步长后的那个元素,说明要交换
					if(arr[j] > arr[j+step]) {
						temp = arr[j];
						arr[j] = arr[j+step];
						arr[j+step] =temp;
					}
				}
			}
		}
		return arr;
	}
}

分步来进行分析如下:

public static int[] ShellsSortStep3(int[] arr) {
		int temp = 0;
		//第一轮
		int step = arr.length/2;
		//遍历各组中所有的元素(共i组,每组有)
		for(int i = step ;i<arr.length;i++) {
			for(int j = i-5 ;j>=0;j-=5) {
				//如果当前元素大于加上步长后的那个元素,说明要交换
				if(arr[j] > arr[j+5]) {
					temp = arr[j];
					arr[j] = arr[j+5];
					arr[j+5] =temp;
				}
			}
		}
		System.out.println("第一轮");
		System.out.println( Arrays.toString(arr) );
		//第二轮
		step = step/2;
		//遍历各组中所有的元素(共i组,每组有)
		for(int i = step ;i<arr.length;i++) {
			for(int j = i-2 ;j>=0;j-=2) {
				//如果当前元素大于加上步长后的那个元素,说明要交换
				if(arr[j] > arr[j+2]) {
					temp = arr[j];
					arr[j] = arr[j+2];
					arr[j+2] =temp;
				}
			}
		}
		System.out.println("第二轮");
		System.out.println( Arrays.toString(arr) );
		//第三轮
		step = step/2;
		//遍历各组中所有的元素(共i组,每组有)
		for(int i = step ;i<arr.length;i++) {
			for(int j = i-1 ;j>=0;j-=1) {
				//如果当前元素大于加上步长后的那个元素,说明要交换
				if(arr[j] > arr[j+1]) {
					temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] =temp;
				}
			}
		}
		System.out.println("第三轮");
		System.out.println( Arrays.toString(arr) );
		return arr;
	}

输出结果是:
第一轮
[3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
第二轮
[0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
第三轮
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

可以看到,希尔排序在组内使用了插入排序

理解希尔排序,可以从插入排序入手。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值