快速排序算法-通俗详细讲解-附案例逻辑清晰-- 柚子真好吃
一、快速排序简单介绍
个人理解:快速排序实质上是将一个序列按某个规则分割为两小列,之后再由每个小列继续拆分,直到无法继续拆分。
二、挺老长的小故事
场景:开学初,小宫是XX学校某年级某班的新任命体育委员。在一节体育课上由于老师不愿意动弹就让小宫来组织站队并且要求了,一定要按大小个排排好,而且时间不能消耗太长,否则就带你们回去上数学。但是小宫的同学们脑袋多多少少有点不太好使,他们不会站队。至此热爱编程的小宫(其实是被父母强制学习的编程)就想到了用快速排序的逻辑来实现排队。
- 班级同学身高信息
姓名 | 身高 |
---|---|
尹听粥 | 1.45 |
吴铁钢 | 1.49 |
王中伟 | 1.44 |
宋永恒 | 1.43 |
孙小载 | 1.48 |
张啊条 | 1.42 |
宫燕遵 | 1.46 |
张建健 | 1.44 |
孙小币 | 1.47 |
-
首先小宫让班级的全部同学按当前位置站好。
如下:
-
此时小宫让大傻子出列(尹听粥),拿着他跟其他人进行比较。首先跟最右侧“孙小币”来比。
如下:
-
此时发现“孙小币"的身高高于“尹听粥”,他应该站在“尹听粥”的后面,暂时不管他了,继续让“尹听粥”跟下一位进行比较,也就是“张建建”
如下:
-
这时小宫发现了“张建健”的身高矮与“尹听粥”。小宫大梦初觉明白了这位“张建健”就是他要找的“卧龙先生”。得一“卧龙”小宫并不满足,同时还要寻找属于他得“凤雏”。小宫从身体中后偏下的不可描述的位置,拔出了一只钢笔(用之前甩了甩上面的血)将“张建建”的位置记录了下来。之后从队伍的左侧开始寻找另一位身高高于“尹听粥”的同学。
如下:
-
真是无巧不成书啊“钢子”就是那位“凤雏先生”。小宫同样拔出钢笔还是甩一甩血,记录了“吴铁钢”的位置。
如下:
-
接下来这位小宫要干什么,您能够猜到吗?
没错那就是让2位同学换位置。
如下:
-
至此一次交换完成,虽然过程显的有点磨磨唧唧但是总体还是不错的。
接下来小宫继续排队,同样从右侧开始拿“尹听粥”与“宫燕遵”进行比较,找出身高小于“尹听粥”的同学。
如下:
-
“宫燕遵”身高大于“尹听粥”不是小宫要找的人,继续向左。
如下:
-
来了,对,没错,就是他。小宫还是“拔”“甩”一系列操作记录“张啊条”的位置,并从左侧的“王中伟”开始向右寻找身高大于“尹听粥”的同学。
如下:
-
不是他。
继续:
-
也不是他。
继续:
-
终于找到他了,就是这位“孙小载”,“拔-甩-记”,同样的酸爽。
如下:
-
得到“卧龙凤雏”后,位置转换得到。
-
继续之前的比较,从“孙小载”的左侧开始寻找身高小于“尹听粥”的同学。
第一个比较的同学就是“张啊条”,我们会发现他已经比较过了,此时相当于“张啊条”进行了2此比较,同时我们也是拿着“尹听粥”将整个队伍的人都比较过了。这个时候“尹听粥”不乐意了,说道“比较了这么多次,我累了,我想休息会”。此时小宫就在想用谁来替换“尹听粥”呢,突然想到了刚才比较了2次的那位同学“张啊条”,那就由他来代替“尹听粥”吧,于是将“尹听粥”与“张啊条”的位置进行变换,得到了全新的队列。
如下:
-
此时我们可以断定“尹听粥”左侧都是比他矮的同学,右侧都是比他高的同学,所以。“尹听粥”完全可以原地休息了。我们将原来的一个队伍分割成2个队伍,如下。
-
至此我们可以重复上面得操作。
二、实现思路
- 现在拿到一个无序的序列,我们取左侧第一个值为一个标准。
- 拿这个标准与序列最右侧数值进行比较,如果该数值大于标准数,则向左继续比较。
- 当比较的数值小于标准数则记录该位置,同时从序列左侧开始继续与标准数比较。
- 当比较的数值大于标准数时同样记录该位置。
- 此时已经有2个标记的位置了,随后将其位置对换。
- 然后继续从右侧拿标准数进行比较。
- 当左侧比较与右侧比较为同一个数时,将标准数与其对换。
- 此时我们的序列就被分成了2列,之后重复以上全部操作即可完成排序。
三、完整代码
public class Main {
public static void main(String[] args) {
int[] arr = {5,9,4,3,8,2,6,4,7};
quickSort(arr, 0, arr.length - 1);
for (int i = 0, l = arr.length; i < l; i++) {
System.out.print(arr[i] + " ");
}
}
public static void quickSort(int[] arr, int left, int right) {
if (left > right) {
return;
}
int i = left;
int j = right;
int temp = arr[left];
while (i < j) {
while (temp <= arr[j] && i < j) {
j--;
}
while (temp >= arr[i] && i < j) {
i++;
}
if (i < j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
}
arr[left] = arr[i];
arr[i] = temp;
quickSort(arr, left, j - 1);
quickSort(arr, j + 1, right);
}
}
参考:https://www.cnblogs.com/captainad/p/10999697.html
参考:《啊哈!算法》 (我这里有电子版,有需要可以分享给大家)