从0开始学算法--排序(1.7快速排序)

算法理解:

  对于无序数组里的任意一个数字V,总有一部分数字小于V,一部分数字大于V。如果我们将比V小的数字放在V的前面,比V大的数字放在后面,那V所在的位置就是整个数组排序后V应该在的位置。

  同时我们得到了两个连续的无序数组,和归并排序一样左右递归处理即可。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

const int maxn=1e5+10;
int num[maxn];

void quicksort(int left,int right){
    int temp,t,i,j;
    if(left>=right)return;
    temp=num[left];
    i=left;
    j=right;
    while(i<j){
        while(num[j]>temp&&i<j){
            j--;
        }
        while(num[i]<=temp&&i<j){
            i++;
        }
        if(i<j){
            t=num[j];
            num[j]=num[i];
            num[i]=t;
        }
    }
    num[left]=num[i];
    num[i]=temp;
    quicksort(left,i-1);
    quicksort(i+1,right);
    return;
}

int main(){
    int i,n;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&num[i]);
    }
    quicksort(0,n-1);
    for(i=0;i<n;i++){
        printf("%d ",num[i]);
    }
    return 0;
}

例一:求数组第k小元素

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

const int maxn=1e5+10;
//分治思想,如果当前值使第6小,那么求第3小时只用查找前6个元素,而不用找后面的元素
void quickselect(int a[],int l,int r,int rank){
    int i=l,j=r,mid=a[(l+r)/2];
    do{
        while(a[i]<mid)++i;
        while(a[j]>mid)--j;
        if(i<=j){
            swap(a[i],a[j]);
            ++i,--j;
        }
    }while(i<=j);
    if(l<=j&&rank<=j-l+1)quickselect(a,l,j,rank);
    if(i<=r&&rank>=i-l+1)quickselect(a,i,r,rank-(i-l));
}

int quick_select(int a[],int n,int k){
    quickselect(a,1,n,k);
    return a[k];
}

int main(){
    int a[maxn];
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    printf("%d\n",quick_select(a,n,k));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wz-archer/p/11689372.html
今日推荐