快速排序
如图显示该分区,它具有以下属性: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的元素都大于等于枢轴项。
上述语句是划分算法的不变式。为是不变式在划分算法开始时为真,必须将数组索引初始化为以下形式,使未知区域涵盖除枢轴项之外的要分区的所有数组段。
l astS1=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);
}
}