概述
简称快排,是对冒泡排序的一种改进,基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
实现原理及过程(含图解)
比如我们对 “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 ,右边需进行快速排序;
代码:
#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)。
最后
以上就是狂野猎豹为你收集整理的快速排序(含图解)的全部内容,希望文章能够帮你解决快速排序(含图解)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复