快速排序(quick sort)

快速排序

如图显示该分区,它具有以下属性:S1=theArray[first....poivotIndex-1]分区的所有项都小于枢轴项p,而S2=theArray[pivotIndex+1 .....last]的所有项大于等于p。这个属性并未说明数组已经完成排序,但指出一个重要的事实:在正确排序数组后,虽然位置first到pivotIndex-1的元素的相对位置可能变化,但依然在first到pivotIndex-1范围内。同样,在正确排序数组后,虽然位置pivotIndex+1 到last的相对位置可能变化,但依然在pivotIndex+1 到last范围内。最终的有序数组中,枢轴项的位置保持不变。
分区列出作为递归解决方案组分的数组项之间的关系。围绕枢轴项p排列数组,将产生两个更小的排序问题:排序数组的左侧部分(S1),排序数组的右侧部分(S2)。枢轴项和数组项之间的关系指示:一旦解决了左侧和右侧的数组排序问题,就解决了原始排序问题。在递归调用前,分解数组,可以在正确的位置放置枢轴项,并确保:在排序更小的数组段后,他们的元素将与数组其余部分简历适当的关系。另外,快速排序最后将终止:左侧和右侧的排序问题是更小的数组排序问题,实际上,因为枢轴项不属于S1和S2,所以与原始排序问题相比,左侧与右侧的排序问题跟接近基例;基例是包含一个元素的数组。

这个问题的难点之所在围绕枢轴项划分数组部分。因此,设计一个划分函数是很必要的。

划分函数的参数为数组段theArray[first....last]。该函数必须将数组段的元素分为两个区域:小于枢轴项的元素集合S1,大于等于枢轴项的元素集合S2。如下图所示。应使用哪个枢轴项?若数组元素的随机排列,则可随机地选择枢轴项。

例如,可将theArray[first]选作枢轴项。在开发分区时,不管选择哪个枢轴项,将枢轴项放在theArray[first]的位置会更方便。准备放到S1和S2区域的元素全部都在数组的另一区域,称为未知区域。数组索引first、lastS1、firstUnknow 和 last 按上述划分数组。枢轴项和未知区域(theArray[firstUnknow...last])元素的关系同样未知!
在整个分区过程中,下面的描述一定为真:
区域S1的元素都小于枢轴项,而区域S2的元素都大于等于枢轴项。
上述语句是划分算法的不变式。为是不变式在划分算法开始时为真,必须将数组索引初始化为以下形式,使未知区域涵盖除枢轴项之外的要分区的所有数组段。
lastS1=first
firstUnknown=first+1;
划分算法的每个步骤分析未知区域的一项,确定它属于S1还是属于S2,并将其放入适当的位置。这样,未知区域的大小每次减1,当未知区域的大小为0时,即firstunknow>last时算法终止。

#include<iostream> using namespace std; int find(int arr[],int first,int last); void sort(int arr[],int first,int last); int main() { const int SIZE=10; int aarray[SIZE]={4,8,9,6,3,2,15,7,1,12}; for(int i=0;i<SIZE;i++) cout<<"the "<<i+1<<"th item is "<<aarray[i]<<endl; sort(aarray,0,SIZE-1); cout<<"the sorted array aarray is :"<<endl; for(int i=0;i<SIZE;i++) cout<<"the "<<i+1<<"th item is "<<aarray[i]<<endl; return 0; } int find(int arr[],int first,int last) { int firsts1=first; int firstUnknow=first+1; int temp; for(;firstUnknow<=last;firstUnknow++) { if(arr[first]>=arr[firstUnknow]) { temp=arr[firstUnknow]; arr[firstUnknow]=arr[lasts1+1]; arr[lasts1+1]=temp; lasts1++; } } temp=arr[first]; arr[first]=arr[lasts1]; arr[lasts1]=temp; return lasts1; } void sort(int arr[],int first,int last) { if(first<last) { int index=find(arr,first,last); sort(arr,first,index); sort(arr,index+1,last); } }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值