您的位置:首页 > 产品设计 > UI/UE

算法分析之——quick-sort快速排序

2016-04-09 14:10 786 查看
快速排序是一种排序算法,最坏情况运行时间为θ(n²),但其最佳期望运行时间为θ(nlgn),并且θ(nlgn)记号中隐含的常数因子很小,快排是在就地排序的一种排序算法。快排是基于分治思想的,与归并排序一样。快速排序是一种不稳定的排序算法,因为算法实现过程中涉及到元素交换。
思路:
(1)分解:数组A
被划分两个字数组A[0..q-1]和A[q+1..n],使得对于数组A[0..q-1]中的元素都小于A[q], A[q+1..n]中的元素都大于等于A[q]。此时A[q]就得排好序。
(2)解决:通过递归调用快速排序,对字数组A[0..q-1]和A[q+1..n]进行排序
(3)合并:因为两个字数组已经是就地排好序的了,整个数组已经排好序了。


void quicksort(int A[],int p,int r)
{
int q;
if(p<r)
{
q=partition(A,p,r);
quicksort(A,p,q-1);
quicksort(A,q+1,r);
}
}


int partition(int A[],int p,int r)
{
int x,i,j,middle;
x = A[r];
i = p-1;
for(j=p;j<=r-1;j++)
{
if(A[j]<=x)
{
i++;
middle=A[i];
A[i]=A[j];
A[j]=middle;

}
}
middle=A[r];
A[r]=A[i+1];
A[i+1]=middle;
return (i+1);
}


假设输入的数组为A[8]={2,8,7,1,3,5,6,4};下面来实现输入过程,length=8;main函数调用quicksort(A,0,length-1)即quicksort(A,0,7)。

此处举例一次快排的执行过程:



基准选择数组的最后一个元素A[r].



1.步骤7中for循环执行过程见下图:j<=r-1;即j<=6;x=4

(1)j从0到6进行循环:i=-1;j=0



判断if(A[j]<=x):A[j]=A[0]=2<4,执行

i++;

middle=A[i];

A[i]=A[j];

A[j]=middle;


即i=0;A[i]与A[j]交换;

(2)j从1到6进行循环:i=0;j=1



判断if(A[j]<=x):A[j]=A[1]=8>4;不满足。执行下一次for循环

(3)j从2到6进行循环:i=0;j=2



判断if(A[j]<=x):A[j]=A[2]=7>4;不满足。执行下一次for循环

(4)j从3到6进行循环:i=0;j=3



判断if(A[j]<=x):A[j]=A[3]=1<4;满足,执行i++;A[i]与A[j]交换;

i++;
middle=A[i];
A[i]=A[j];
A[j]=middle;


i=1;A[i]=A[1]=8;A[j]=A[3]=1;如下图



(5)j从4到6进行循环:i=1;j=4



判断if(A[j]<=x):A[j]=A[4]=3<4;满足,执行i++;A[i]与A[j]交换;

i=2;A[i]=A[2]=7;A[j]=A[4]=3;如下图:



(6)j从5到6进行循环:i=2;j=5



判断if(A[j]<=x):A[j]=A[5]=5>4;不满足。执行下一次for循环

(7))j从6到6进行循环:i=2;j=6



判断if(A[j]<=x):A[j]=A[6]=6>4;不满足。执行下一次for循环

(8)j++;j=7,跳出for循环。此时数组如下图:图a



2.接下来执行步骤8,执行完后如图b



返回i+1=3,即主元素的下标。

最后第一次递归执行的结果图如下:



下次递归,主元素不再进行排序,分别对其左边和右半边的数组进行排序。即2、1、3和7、5、6、8分别递归。此处不再一一举例。

最后给出程序运行的结果:



源代码下载地址源代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: