一、希尔排序


希尔排序需要使用一个增量排序,因为每趟的排序间隔逐渐缩小,希尔排序也称为“缩小增量排序”。


这个算法可以看作是插入排序的优化版,因为插入排序需要一位一位比较,然后放置到正确位置。为了提升比较的跨度,希尔排序将数组按照一定步长分成几个子数组进行排序,通过逐渐减短步长来完成最终排序。该方法实质上是一种分组插入方法。

尔排序的想法是避免大量的数据移动,先比较那些离的比较远的元素,再比较那些离的比较近的元素,以此类推,逐步逼近基本的插入排序。

增量数列的选择对希尔排序的性能有着极大的影响。[Mark Allen Weiss]指出,最好的增量序列是 Sedgewick提出的 (1, 5, 19, 41, 109,…),该序列的项来自 9 * 4^i - 9 * 2^i + 1 和 4^i - 3 * 2^i + 1 这两个算式。当然,也可以这样选择:希尔排序为多轮等跨度插入排序。第一轮等跨度插入排序的跨度为 n/2,有 n/2 次插入排序。后面每轮跨度缩小到原来的一半。

案例:对【49,38,65,97,76,13,27,49,55,4】进行由大到小排序。
增量序列:【5,3,1】

第一步:取步长为5的增量,可以得到5个子序列,并且子序列之内是由大到小排序的,即对得到的5个子列进行比较大小,把大的放到前面,也就是比较的两个数交换了位置。

排序算法:排序三剑客之【希尔、归并、快速】_希尔排序


第二步:取步长为3的增量,可以得到7个子序列,并且子序列之内是由大到小排序的,即对得到的5个子列进行比较大小,把大的放到前面,也就是比较的两个数交换了位置。

第三步:取步长为1的增量,可以得到9个子序列,并且子序列之内是由大到小排序的,即对得到的5个子列进行比较大小,把大的放到前面,也就是比较的两个数交换了位置。

二、归并排序

归并排序是一个典型的基于分治的递归算法。它不断地将原数组分成大小相等的两个子数组(可能相差1),最终当划分的子数组大小为1时,将划分的有序子数组合并成一个更大的有序数组。

归并排序的递归公式:T(N) = 2T(N/2) + O(N)

从公式中可以看出:将规模为 N 的原问题分解成两个规模 N/2 的两个子问题;并且,合并这两个子问题的代价是 O(N)—[后面的 +O(N) 表示合并的代价]

过程:

排序算法:排序三剑客之【希尔、归并、快速】_希尔排序_02


例子:

对以下数据进行有小到大排列:

排序算法:排序三剑客之【希尔、归并、快速】_数据_03


将原序列分为若干组,并且分组的时候组内的顺序是有小到大的:

排序算法:排序三剑客之【希尔、归并、快速】_希尔排序_04


重复进行两两合并,合并得到数组也要保证是有小到大排序的:

排序算法:排序三剑客之【希尔、归并、快速】_希尔排序_05


最后归并排序完成:

排序算法:排序三剑客之【希尔、归并、快速】_快速排序_06

三、快速排序

快速排序算法其实是在冒泡排序的基础上的一个改进;
快速排序的基本思想是: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比另一部分的所有数据要小,再按这种方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,使整个数据变成有序序列。

原理: 排序算法的思想非常简单,在待排序的数列中,我们首先要找一个数字作为基准数(这只是个专用名词)。为了方便,我们一般选择第 1 个数字作为基准数(其实选择第几个并没有关系)。

接下来我们需要把这个待排序的数列中小于基准数的元素移动到待排序的数列的左边,把大于基准数的元素移动到待排序的数列的右边。

这时,左右两个分区的元素就相对有序了;接着把两个分区的元素分别按照上面两种方法继续对每个分区找出基准数,然后移动,直到各个分区只有一个数时为止。这是典型的分治思想,即分治法。

案例解释:
存在数列:3、5、8、1、2、9、4、7、6;对这个数列进行排序。
解答:

第一步:

选择最后一个数为基准数:6 (代号B)
数列的最左边的那个数字标记为:L
数列的最右边的那个数字【这个数字是基准数的前一个】标记为:R

第二步:
左标记L向右移动,左标记的值小于等于B时,继续向右移动,当左标记L>基准数B时,L停止移动;
这时候右标记向左移动,当右标记R<B时,停止移动;

  • 如果此时左右标记已经停止移动且没有触碰的话,将左标记和右标记此时的值互换,然后左标记继续向右移动,右标记继续向左移动,如果L和R触碰的话,那么把他们两个触碰的那个位置和B互换位置,然后对此时B的两边分别进行快速排序;如果不触碰的话那么继续移动和比较、以及互换位置,直到触碰为止。
  • 如果左右标记触碰了,那么将触碰的位置与B互换位置,然后对B的两边分别进行快速排序。

解释:

左标记和右标记触碰的时候代表快速排序第一轮的任务完成:

排序算法:排序三剑客之【希尔、归并、快速】_数据_07


第一轮任务完成之后,只需要对B的两边分别进行快速排序即可。