希尔排序

本文内容来源于数据结构教材(C语言版)
希尔排序(Shell’s Sort),又称缩小增量排序(Diminishing Increment Sort),它也是一种属插入排序类的方法,但在时间效率上较前几种插入排序有较大改进。

它的基本思想是:先将整个待排序记录序列分割成为若干子序列,分别进行,直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序。
希尔排序_第1张图片
上述图片描述太过模棱两可,不好理解,详细分解图如下:
希尔排序_第2张图片
排序使用增量(步进)一次为5, 3, 1,第一轮使用5为步进,从下标0开始向后与下标为(0+5)处的数字进行比较,小的数字向前(左侧),大的数字向后(右侧),然后下标为1开始,为2开始,依次向后直到再也没有步进为5的第二个数字,则第一轮排序完毕。
下面以第一轮为例详细分析:

  • 第一步
    希尔排序_第3张图片
  • 第二步
    希尔排序_第4张图片
  • 第三步
    希尔排序_第5张图片
  • 第四步
    希尔排序_第6张图片
  • 第五步
    希尔排序_第7张图片
    以上就是第一轮排序的详细过程,第二轮,第三轮只是改变了步进,基本思想没变。

希尔排序算法使用Java实现如下

	/**
	 * 具体排序过程
	 * @param arr
	 * @param dk 增量
	 */
	void shellInsert(int[] arr, int dk) {
		// 对数组arr作一趟希尔插入排序。
		for (int i = dk; i < arr.length; i++) {
			if (arr[i] <= arr[i - dk]) {
				int temp = arr[i];

				int j = 0;
				for (j = i - dk; j >= 0 && temp <= arr[j]; j -= dk) {
					arr[j + dk] = arr[j];
				}
				arr[j + dk] = temp;
			}

		}
	}// Shell Insert
	
	void ShellSort(int[] arr, int[] dlta, int t) {
		// 按增量序列dlta[0..t-1]对顺序表arr作希尔排序
		for (int i = 0; i < t; i++) {
			shellInsert(arr, dlta[i]);
		}
	}
	
	@Test
	public void fun1() {
		int[] arr = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 04 };
		int[] dlta = { 5, 3, 1 };
		ShellSort(arr, dlta, dlta.length);

		System.out.println(Arrays.toString(arr));
	}

希尔排序的分析是一个复杂的问题,因为它的时间是所取增序列量的函数,这涉及一些数学上尚未解决的难题。(教材的印刷时间2009年2月,出版时间是2007年,今年2019年,距离出版大约过去了12年,不知道这些年这些数学上的难题解决了没有。)剩下的内容如:大量研究得出的局部结论,增量序列的取法,还是看教材吧,内容有些多。

你可能感兴趣的:(算法)