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


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值