算法篇:快速排序
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. 代码实现(C语言版)
/* 函数声明*/
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, 0, 9); //快速排序
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八股文面试题 基础篇 -- 二分查找算法冒泡排序选择排序插入排序希尔排序快速排序