快排概念快速复习

之前已经写了一篇快排的java实现的文章了:https://www.cnblogs.com/jiading/p/11743051.html ,这里引述这篇文章就是为了之后万一考到快排的概念自己忘了,快速回忆用的


快排中,一趟操作的最终目的是把 “支点” 放到它应该去的地方,举个例子,已知序列{7, -1, 5, 23, 100, 101},那么第一趟快排的结果是{_, _, 7, _, _, _}

可以看到,首元(支点)已经去了它该去的地方(在最终的结果序列中,7 就在中间位置,没错吧)

\3. 对子序列进行快排

第 2 步不仅确定了 7 的最终位置,还把原序列自然地划分为两个子序列 {_, } 和{, _, },这里用 "" 代替具体的数值,因为我们也不知道第 2 步的结果具体是什么,除非真正地做一趟快排,当然,在这里不必要,下面会有针对具体例子的详细解释

很自然的我们想到了对子序列进行同样的操作,然后对子序列的子序列再进行同样的操作... 递归

当所有的子序列长度都为 1 的时候,排序结束

三. 具体实例

现有一序列 {9, 0, 8, 10, -5, 2, 13, 7},我们用快速排序算法来对其排序

首先,声明一些特殊的记号,便于描述

a, 数字后面跟的大写字母表示指针,例如 2.5P 表示指针 P 指向元素 2.5 所在的位置

b, @表示垃圾数字,也就是说,当前位置是几都无所谓,不必纠结于此,后面会有具体解释

c, _表示该位的元素与上一行一样(_表示不变)

-------

P.S. 想要真正弄明白的话,现在拿出纸和笔吧,光靠眼睛是绝对不够的

下面正式开始一趟快排的过程解析

【1】9L  0  8  10  -5  2  13  7H

【2】7  0L  _  __  __  _  __  @H

【3】  _  8L  __  __  _  __  _

【4】  _  _  10L  __  _  __  _

【5】_  _  _  @L  __  _  13H  10

【6】  _  _  __  __  2H  13  _

【7】  _  _  2  -5L  @H  __  _

【8】  _  _  _  -5  @HL  __  _

【9】  _  _  _  __  9HL  __  _

解释:

\1. 第一行是初始状态,快排需要两个指针 L 和 H(表示低位 Low,高位 High),一个临时变量 temp

初始时,低位指针 L 指向首元 9,高位指针 H 指向尾元 7,temp = 首元 9(temp 就是所谓的” 支点 “)

\2. 进行如下操作:(先不要问为什么)

比较 * H 与 temp,若 * H 大,则向前移动 H 继续比较,若 * H 小,则 * L = H,H = @(H 指向的值变成垃圾数字了),向后移动 L

因为 7 < 9,所以把 L 指向的 9 变成 7,把 H 指向的 7 变成垃圾数字,向后移动 L 指针,得到第二行的结果

\3. 进行如下操作:(先不要问为什么)

比较 * L 与 temp,若 * L 小,则向后移动 L 继续比较,若 * L 大,则 * H = L,L = @(L 指向的值变成垃圾数字了),向前移动 H

因为 0 < 9,所以向后移动 L,得到第三行的结果

\4. 因为 8 < 9,同上

\5. 因为 10 > 9,所以把 H 指向的垃圾数字 @变成 10,把 L 指向的 10 变成垃圾数字,向前移动 H 指针,得到第 5 行的结果

\6. 因为 13 > 9,所以向前移动 H 指针,得到第 6 行的结果

\7. 因为 2 < 9,所以把 L 指向的垃圾数字 @变成 2,把 H 指向的 2 变成垃圾数字,并向后移动 L 指针,得到第 7 行的结果

\8. 因为 - 5 < 9,所以向后移动 L 指针得到第 8 行的结果

\9. 进行如下操作:(先不要问为什么)

若 L = H,则 * L = *H = temp,一趟快排结束

因为 L 指针与 H 指针重合了,所以把 L 指向的垃圾数字 @变成 temp 的值 9,一趟结束

至此,我们确定了支点 9 的最终位置,给定序列也被自然的分为两个子序列 {7, 0, 8, 2, -5} 和{13, 10},对子序列进行相同的操作,最终能够得到有序序列

posted @ 2020-03-04 00:59  别再闹了  阅读(160)  评论(0)    收藏  举报