排序算法分析 - java版本

希尔排序分析



希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力加强版。

主要是为了解决插入排序中,在集合前面有序元素过多时导致的重复无用循环的问题。


由于属于插入排序的变种,故基本原理也是插入排序的原理,将整个集合分为有序以及无无序两个部分,然后从无序部分中不断取出元素放入有序集合部分。

但是希尔排序引入了一个叫步长(gap)的概念,本质是将集合分组。

希尔排序是不稳定的,即两个相同的元素相对位置,在排序后可能会发生变化。

如图:
排序算法分析 - java版本_第1张图片
步骤分析

  1. 将长度为10的集合分为 10/2 = 5 组,这五组各自有两个元素。分别对每个组内的这两个元素进行插入排序。

    在这一步之后 ,若集合本身前面是有序的,只是后面有些无序序列时,此时的无序序列也已经会被前移到前半部分了

  2. 继续缩小步长(缩小一倍),再次分批进行插入排序。直至步长为1,再次进行最后一次插入排序,可以有效降低插入排序的无效次数

JAVA代码实现:

/**
     * 希尔排序(插入排序变种)
     * 

* 为了改善插入排序的一些弊端。比如原数组本来在前面就有很多的有序元素,插入排序前面的很多遍历就都成为了徒劳,对程序的浪费 * 希尔排序会将集合先进行分组,先按每组来排序,然后减小分组,继续进行插入排序。直至分组数小于0 * [4, 2, 17, 3, 85, 0, 31, 2, 7, 61, 43, 87, 31, 39, 38, 42, 72, 24, 20, 55] * 20个元素,首先分10组,其中,下标位0,10是一组,1,11 是一组,2,12是一组,。。。 * 第二次,分5组,下表0,5,10,15为一组,1,6,11,16是一组。。。。 * 第三次,分2组,下表0,2,4,6,8,10,12,14,16,18为一组,1,3,5,7,9,11,13,15,17,19 为一组 * 最后分组数为1,进行整体插入排序 * * @param arr */ public void shellOrder(int[] arr) { int buc = arr.length / 2; while (buc > 0) { for (int x = buc; x < arr.length; x++) { int cur = arr[x]; for (int y = x - buc; y < x; y += buc) { if (arr[y] > cur) { int temp = arr[y]; arr[y] = cur; arr[x] = temp; break; } } } buc = buc / 2; } }

你可能感兴趣的:(排序算法,算法,java)