算法篇:快速排序

Posted 一口吃成大胖纸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法篇:快速排序相关的知识,希望对你有一定的参考价值。

理解复杂数据结构或算法的最佳方法是直观的感受它们的实际作用。向大家一个推荐关于学习算法的可视化网站。由旧金山大学搭建,链接如下(不确定中国大陆地区是否需要梯子):

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

1. 快速排序概述

  • 快速排序算法被列为二十世纪十大算法之一,由Tony Hoare设计出来。

  • 快速排序是冒泡排序的升级,属于交换排序类。



2. 快速排序思路

  • 以上图片非常直观的反应快速排序的思路:Divide-and-Conquer。我个人理解为分而治之。这个策略不管是在生活还是算法中都是经常用到的,遇见一个难题时,将大问题切成多个小问题(多个步骤),然后再逐个解决或实现。

  • 快速排序:选取一个基准值,通过一趟排序将待排序的数列分割成左右的两个数列,左边的数列均比右边的数列小(也比基准值小),然后再重复以上步骤将这两个数列分别分割成左右两个数列,以达到整个序列有序的目的。



3. 快速排序实现步骤

  1. 在待排序的数列中,首先选出一个数字作为基准值。

  2. 小于基准值的数移动到待排序数列的左边。

  3. 于基准值的数移动到待排序数列的右边。

  4. 此时,数列被分为左右两个数列,分别对左右两个两个重复1、2、3步操作(也就是递归调用,自己再次调用自己两次,至于为什么是两次是因为分词我们切割时分为的是左右两个数列,所以要对左右两个数列分别完成排序)。

  5. 直到各个区块只有一个数为止,此时数列已经排序完成(简单来讲就是当左右两边数列的游标相遇时,则说明数列只剩当前一个元素,已经无法再分割)。



4. 代码实现(C语言版)

#include <stdio.h>
/* 函数声明*/void printfArray(int* testArray, int count);void swapValue(int *value1, int *value2);void quickSort(int* testArray, int begin, int end);
/* main */int main (void){ int testArray[10] = { 6, 1, 2, 7, 9, 3, 4, 5, 8, 9 }; printf("排序前:");  printfArray(testArray, 10);  //output  quickSort(testArray, 09);  //快速排序 printf("排序后:");  printfArray(testArray, 10);  //output
return 0;}
/* 打印数组 */void printfArray (int *testArray, int count){ int i = 0; while (i < count) { printf("%d ", testArray[i]); ++i; } printf("\n");}
/* 交换两数 */void swapValue(int *value1, int *value2){ int temp = *value1; *value1 = *value2; *value2 = temp;}
/* 快速排序 */void quickSort(int* testArray, int begin, int end){ /* 终止条件 */ if (begin < end) { int key = testArray[begin]; //选择首端为基准值 int i = begin; int j = end;
/* 终止条件 */ while (i != j) { /* 1.从尾端开始与基准值比较,如果尾端值大于基准值,则尾端向前移一位。*/ while (i < j && testArray[j] > key) // i<j :保证i始终在j的前面 { j--; //尾端向前移一位 }/* 2.如果跳出循环说明:尾端值小于基准值交换移动权限;或i>j比较结束 */ /* 1.如果首端值小于基准值,则首端向后移一位。*/ while (i < j && testArray[i] <= key) { ++i; //首端向后移动一位 }/* 2.如果跳出循环说明:首端值大于基准值,交换移动权限;或i>j比较结束 */
/* 3.当以上while循环不成立时,交换首端值与尾端值*/ if (i < j) { swapValue(&testArray[i], &testArray[j]); //swap      } }    /* 将基准值归位 */     swapValue(&testArray[begin], &testArray[i]);
    /* 递归调用,排序左右两边的数列 */  quickSort(testArray, begin, i - 1); quickSort(testArray, i + 1, end); }}


5. 算法处理过程图解

以上图片引用至 极客学院wiki

https://wiki.jikexueyuan.com/project/easy-learn-algorithm/fast-sort.html


6. 算法可视化

以上可观察到,当i遇见比基准值大的数停下,然后交换比较权给j;接着j遇见比基准值小的数时停下,然后交换两数,接着交换比较权给i。直到i,j相遇时本轮比较停止。


以上是关于算法篇:快速排序的主要内容,如果未能解决你的问题,请参考以下文章

Java八股文面试题 基础篇 -- 二分查找算法冒泡排序选择排序插入排序希尔排序快速排序

算法篇:快速排序

希尔排序算法

常见排序算法的实现(归并排序快速排序堆排序选择排序插入排序希尔排序)

1秒记住快速排序!

算法排序之堆排序