算法理解:
对于无序数组里的任意一个数字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; }
原文地址:https://www.cnblogs.com/wz-archer/p/11689372.html
时间: 2024-11-09 02:52:59