现在的位置: 首页 > 综合 > 正文

快速排序算法QuickSort(二)

2013年02月08日 ⁄ 综合 ⁄ 共 3301字 ⁄ 字号 评论关闭

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

View Code

#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函数,修改以后如下:

View Code

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)

View Code

#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;
}

 

抱歉!评论已关闭.