1.说明
这个快速排序算法是对前面的 快速排序算法QuickSort 一种改进。
只是修改了int Partition(int arry[],int start,int end)这个方法。
2.思路
仔细观察我们可以发现,我们前面Partition方法中,都需要swap(arry,start,end), 但是这一步中有些步骤是可以省略的。
在(<-end)过程中,碰到第一个小于等于pivot的元素时,只需要进行一次赋值arry[start]=arry[end]; 因为当前的arry[start]是值就是pivot ;
在(start->)过程中,碰到第一个大于等于pivot的元素之,只需要进行一次赋值arry[end]=arry[start]; 因为当前的arry[end]的值就是pivot的值。
整个过程中,不是start就是end指向pivot所存储的单元 ,所以在整个过程中,pivot没有必要每次通过swap来保存,只需要在最后找到pivotkey的时候, 令arry[pivotkey]=pivot即可。
具体修改如下代码实例。
3.改进的快速排序QuickSort
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
#define maxNum 100
/*
改进的int Partition(int arry[],int start,int end)
仔细观察我们可以发现,我们前面Partition方法中,都需要swap(arry,start,end),
但是这一步中有些步骤是可以省略的。
在(<-end)过程中,碰到第一个小于等于pivot的元素时,只需要进行一次赋值arry[start]=arry[end];
因为当前的arry[start]是值就是pivot
在(start->)过程中,碰到第一个大于等于pivot的元素之,只需要进行一次赋值arry[end]=arry[start];
因为当前的arry[end]的值就是pivot的值,
整个过程中,不是start就是end指向pivot所存储的单元
所以在整个过程中,pivot没有必要每次通过swap来保存,只需要在最后找到pivotkey的时候,
令arry[pivotkey]=pivot即可。
*/
int Partition(int arry[],int start,int end)
{
//cout<<"轴心数组"<<endl;
//for(int i=start;i<=end;i++)
// cout<<arry[i]<<" ";
//cout<<endl;
int pivot=arry[start];
while(start<end)
{
while(arry[end]>pivot&&start<end)
end--;
arry[start]=arry[end];
while(arry[start]<pivot&&start<end)
start++;
arry[end]=arry[start];
}
arry[start]=pivot;
/*cout<<"输出轴心位置:"<<start<<endl;*/
return start;
}
void QSort(int arry[],int start,int end)
{
if(start<end)
{
int pivotkey=Partition(arry,start,end);
QSort(arry,start,pivotkey-1);
QSort(arry,pivotkey+1,end);
}
}
void QuickSort(int arry[],int len)
{
QSort(arry,1,len);
}
void main()
{
int n;
int arry[maxNum]={0};
srand(time(NULL));
cout<<"输入随机数组长度n:"<<endl;
cin>>n;
cout<<"生成长度为"<<n<<"的100以内的随机数组"<<endl;
cout<<"排序前:"<<endl;
for(int i=1;i<=n;i++)
{
arry[i]=rand()%100;
cout<<arry[i]<<" ";
}
cout<<endl;
QuickSort(arry,n);
cout<<"排序后:"<<endl;
for(int i=1;i<=n;i++)
{
cout<<arry[i]<<" ";
}
cout<<endl;
system("pause");
}
/*
输入随机数组长度n:
10
生成长度为10的100以内的随机数组
排序前:
91 67 99 37 40 70 49 71 43 42
排序后:
37 40 42 43 49 67 70 71 91 99
请按任意键继续. . .
*/
PS:2012-5-4
今天发现以前一直以为对的快排写错了,因此没有考虑需要排序的数相等的情况,如果排序的数组中有相同的数,那么就会出现死循环,一直没有结果,要做的修改就是修改Partition函数,修改以后如下:
int Partition(int arry[],int start,int end) { //cout<<"轴心数组"<<endl; //for(int i=start;i<=end;i++) // cout<<arry[i]<<" "; //cout<<endl; int pivot=arry[start]; while(start<end) { while(arry[end]>=pivot&&start<end) end--; arry[start]=arry[end]; while(arry[start]<=pivot&&start<end) start++; arry[end]=arry[start]; } arry[start]=pivot; /*cout<<"输出轴心位置:"<<start<<endl;*/ return start; }
做的唯一修改就是将原来的arry[end]>pivot改为arry[end]>=pivot,arry[start]<pivot改为arry[start]<=pivot
快排练习(PS:2012-10-2)
#include<iostream> #include<stdlib.h> using namespace std; int Partition(int arry[],int start,int end) { int pivot=arry[start]; while(start<end) { while(start<end&&arry[end]>=pivot)//找到第一个小于pivot的元素为止,如果arry[end]>=pivot则过滤掉 end--; arry[start]=arry[end]; while(start<end&&arry[start]<=pivot)//找到第一个大于pivot的元素为止 start++; arry[end]=arry[start]; } arry[start]=pivot; return start;//此时start=end,所以返回start跟返回end一样。 } void QuickSort(int arry[],int start,int end) { if(start>=end) return; int pivotkey=Partition(arry,start,end); QuickSort(arry,start,pivotkey-1); QuickSort(arry,pivotkey+1,end); } void PrintArry(int arry[],int len) { for(int i=0;i<len;i++) cout<<arry[i]<<" "; cout<<endl; } int main() { int arry[]={1,2,3,2,2,2,5,4,2}; int len=sizeof(arry)/sizeof(int);//求数组长度 QuickSort(arry,0,len-1);//快排 PrintArry(arry,len);//打印数组 system("pause"); return 0; }