我们先来做一道简单的题:
题目描述:
利用快速排序算法将读入的N个数从小到大排序后输出。(N≤10^5)
很简单是不是? sort()函数扫一遍,只要数据不是特别的大,就能过。
但是你如果不用sort()函数呢,你会做吗?
快速排序说:我可以~
快速排序算法:
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 1e6+1;
int n,a[MAX];
void qsort(int begin ,int end){
int temp = a[(begin+end)/2]; // 取中间数
int i = begin; //定义两个指针,从数组的两端扫
int j = end;
while(i <= j){
while(a[i] < temp) i++; //这两个循环结束后会得到一对不满足左小右大的下标
while(a[j] > temp) j--;
if(i<=j){
swap(a[i],a[j]);
i++;
j--;
}
}
if(i < end) qsort(i,end);
if(j > begin) qsort(begin,j); //在左右两边分别再递归这个过程,排序完成
}可能大家会说:有了sort()还那么麻烦干嘛?
那你再看一道题:
输入n(n<5000000且n为奇数)个数字ai(ai<1e9)输出第k小的数字,最小的数字是第0小。
这么大的数据量,你用sort()还能过吗????
哈哈,用二分法
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 5e6+1;
int n,k, a[MAX];
void qsort(int begin ,int end){
int temp = a[(begin+end)/2]; // 取中间数
int i = begin; //定义两个指针,从数组的两端扫
int j = end;
while(i <= j){
while(a[i] < temp) i++; //这两个循环结束后会得到一对不满足左小右大的下标
while(a[j] > temp) j--;
if(i<=j){
swap(a[i],a[j]);
i++;
j--;
}
}
if(k <= j) qsort(begin,j); //在哪一边就在哪边查找
else if(k >= i) qsort(i,end);
else{
cout<<a[k]<<endl;
return ; //此时k=j+1=i-1; 也就是(i>j)
}
}大家发现了吗? 快速排序和求第k小数字的相同点就在于分治这个算法。
好了就到这里。
不会的可以给我留言哦~

京公网安备 11010502036488号