快速排序及快速选择问题

来源:互联网 发布:海通大智慧下载软件 编辑:程序博客网 时间:2024/05/16 16:14

快速排序及快速选择问题

1. 快速排序

  1. 采取分治,通过找到一个中枢值,使得中枢值左边的数小于等于其值,右边大于其值。
  2. 递归求解问题
  3. 当每一个数被当做一次中枢值,这个数组已经有序
//挖坑填数+分治//函数出口为l=r时//把数组分成中枢两侧,采取两个指针,挖坑填数void quickSort(int a[],int left,int right){    int l=left,r=right,key=a[l];    if(l<r){        while(l<r){            while(l<r && key<a[r])                r--;            a[l]=a[r];            while(l<r && key>=a[l])                l++;            a[r]=a[l];        }        a[l]=key;        quickSort(a,left,l-1);              //左边递归,重复上面找中枢步骤        quickSort(a,l+1,right);             //右边递归,重复上面找中枢步骤    }}

2. 快速选择问题

快速选择问题。输入n个整数和一个正整数k(1≤k≤n),输出这些整数从小到大排序后的第k个(例如,k=1就是最小值)。n≤107。

在快速排序的基础上,只需要找到第k个作为中枢的值,即为有序数列的第k个数的数值

int quickSort1(int a[],int left,int right,int num){    //快速选择问题。输入n个整数和一个正整数k(1≤k≤n),输出这些整数从小到大排序后的第k个    //函数出口为 l==r==num  和快排有差别    int l=left,r=right,key=a[l];    if(l<r){        while(l<r){            while(l<r && key<a[r])                r--;            a[l]=a[r];            while(l<r && key>=a[l])                l++;            a[r]=a[l];        }        a[l]=key;    }        if(num==l)                                          //此时出现要找的数组下标            return key;        if(num<l)            return quickSort1(a,left,l-1,num);              //递归左区间求解   必须带return,否则函数没法一级一级返回        else            return quickSort1(a,l+1,right,num);             //递归左区间求解   必须带return,否则函数没法一级一级返回}

快速排序和快速问题完整代码

#include <iostream>#include <cstring>#include <time.h>#include <stdlib.h>#define N 10using namespace std;int quickSort1(int a[],int left,int right,int num){    //快速选择问题。输入n个整数和一个正整数k(1≤k≤n),输出这些整数从小到大排序后的第k个    //函数出口为 l==r==num  和快排有差别    int l=left,r=right,key=a[l];    if(l<r){        while(l<r){            while(l<r && key<a[r])                r--;            a[l]=a[r];            while(l<r && key>=a[l])                l++;            a[r]=a[l];        }        a[l]=key;    }        if(num==l)            return key;        if(num<l)            return quickSort1(a,left,l-1,num);              //递归左区间求解   必须带return,否则函数没法一级一级返回        else            return quickSort1(a,l+1,right,num);             //递归左区间求解   必须带return,否则函数没法一级一级返回}void quickSort(int a[],int left,int right){    int l=left,r=right,key=a[l];    if(l<r){        while(l<r){            while(l<r && key<a[r])                r--;            a[l]=a[r];            while(l<r && key>=a[l])                l++;            a[r]=a[l];        }        a[l]=key;        quickSort(a,left,l-1);              //左边递归,重复上面找中枢步骤        quickSort(a,l+1,right);             //右边递归,重复上面找中枢步骤    }}int a[N];int b[N];int main(){    unsigned seek=unsigned(time(NULL));    srand(seek);    cout<<"Array:"<<endl;    for(int i=0;i<N;i++)    {        a[i]=rand();        cout<<a[i]<<"\t";    }    cout<<endl;    memcpy(b,a,sizeof(a));    quickSort(a,0,N-1);    int pos=3;                                      //要查找数的位置    cout<<"Result:"<<endl;    for(int i=0;i<N;i++)        cout<<a[i]<<"\t";  int ans=quickSort1(b,0,N-1,pos-1);              cout<<endl<<"部分排序:"<<endl;                    //通过打印这个数组,验证O(n)复杂度,不是全部操作,只操作一部分    for(int i=0;i<N;i++)       cout<<b[i]<<"\t";    cout<<endl<<endl<<"第 "<<pos<<" 个数是:"<<ans<<endl;    return 0;}

输出结果:

Array:
11973 4898 13514 6085 14958 17750 2789 2706 20714 19060
Result:
2706 2789 4898 6085 11973 13514 14958 17750 19060 20714
部分排序:
2706 2789 4898 6085 11973 17750 14958 13514 20714 19060

第 3 个数是:4898

0 0
原创粉丝点击