/* *寻找最小的k个数 *题目描述:5.查找最小的k个元素 *题目:输入n个整数,输出其中最小的k个。 *例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。 * *Randomized-Select方法,线性期望时间 *时间复杂度O(n) */ #include <iostream> #include <vector> #include <cstdlib> #include <ctime> using namespace std; int random(int min,int max) { time_t t; srand((unsigned) time(&t)); int i=int(rand()%(max-min+1))+min; } void exchange(vector<int>& vi,int i,int j) { int tmp = vi[i]; vi[i] = vi[j]; vi[j] = tmp; } int partition(vector<int>& vi,int start,int end) { int key = vi[end]; int i = start -1; for(int j = start;j < end;++j) { if(vi[j] < key) { ++i; exchange(vi,i,j); } } exchange(vi,i+1,end); return i+1; } int randomized_partition(vector<int>& vi,int start,int end) { int i = random(start,end); exchange(vi,i,end); return partition(vi,start,end); } int randomized_select(vector<int>& vi,int start,int end,int i) { if(start == end) return vi[start]; else if(start < end) { int q = randomized_partition(vi,start,end); int k = q - start + 1; if(i == k) return vi[q]; else if(i < k) { return randomized_select(vi,start,q-1,i); } else return randomized_select(vi,q+1,end,i-k); } } int main(int argc,char **argv) { vector<int> vi; vi.push_back(1); vi.push_back(5); vi.push_back(4); vi.push_back(6); vi.push_back(2); vi.push_back(3); vi.push_back(8); vi.push_back(7); int k = 3; for(int i = 1;i <=vi.size();++i) { int res = randomized_select(vi,0,vi.size()-1,i); cout<<res<<endl; } return 0; }