快速排序及快速选择问题

3 篇文章 0 订阅
2 篇文章 0 订阅

快速排序及快速选择问题

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 10
using 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

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值