我是靠谱客的博主 狂野猎豹,这篇文章主要介绍快速排序(含图解),现在分享给大家,希望可以做个参考。

简称快排,是对冒泡排序的一种改进,基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。




实现原理及过程(含图解)

比如我们对 “8,9,1,3,5,2,7,6” 这组数据进行排序,首先我们随便找一个数作为参照数称为支点,然后想办法的让比支点小的数堆在左边,让比支点大的数堆在右边,以此来分成两部分,再对余下两边使用快速排序即可。



首先,选取支点,用 i 指着数组最左边,用 j 指着数组最右边,要使支点的左边小于等于5,右边大于等于5,就要让 i 往右移比较,让 j 往左移比较,直至 i 与 j 交叉错开即可保证左边都小于支点,右边都大于支点 (如下图)

在这里插入图片描述

让 i 和 j 移动过程中与支点比较,如果a[ i ]大于支点,a[ j ]小于支点,两者交换,否则 i 、j 继续移动。

(如:一开始a[0]大于5,那么 i 先停止移动,a[ j ]由于大于5,j左移,直到a[5]时小于支点,那么a[0]与a[5]的值进行交换,然后 i 、j 再进行移动直至错开。)


交换第一次后:
在这里插入图片描述
循环上述步骤直至错开

最终错开时:
在这里插入图片描述
至此,从a[0]到a [ j ] 的数都小于等于5,从a[ i ]到a [7] 的数都大于等于5,我们完成了第一步,接下来就分别让左边和右边再进行快速排序即可。


因此我们可以用递归来做,所以我们要考虑递归出口条件:
即 数组元素下标 < j ,左边需进行快速排序;
即 数组元素下标 > i ,右边需进行快速排序;

代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream> using namespace std; void quicksort(int a[],int left, int right) { int i,j,point,t; point = a[(left+right)/2]; i = left; j = right; while(i<=j) //i与j没错开就要继续循环 { while(point>a[i]) { i++; } while(point<a[j]) { j--; } if(i<=j) { t=a[i]; a[i]=a[j]; a[j]=t; i++; j--; } } if(left<j) quicksort(a,left,j); if(i<right) quicksort(a,i,right); } int main() { int a[8]={8,9,1,4,3,5,7,6},i; i=8; quicksort(a,0,i-1); for(i=0;i<8;i++) cout<<a[i]<<endl; return 0; }

时间复杂度:O(NlogN)

快速排序相比于冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个支点,将小于等于支点的数放到支点的左边,将大于等于支点的数放到支点的右边。这样在每次交换的时候就不会像冒泡排序一样只能在相邻的数之间进行交换,交换的距离就大得多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最坏时间复杂度和冒泡排序是一样的都是O(N2),但它的平均时间复杂度为O(NlogN)。

最后

以上就是狂野猎豹最近收集整理的关于快速排序(含图解)的全部内容,更多相关快速排序(含图解)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(83)

评论列表共有 0 条评论

立即
投稿
返回
顶部