转自:http://blog.csdn.net/liufeng_king/article/details/8480430
线性时间选择问题:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,(这里给定的线性集是无序的)。
1、随机划分线性选择
线性时间选择随机划分法可以模仿随机化快速排序算法设计。基本思想是对输入数组进行递归划分,与快速排序不同的是,它只对划分出的子数组之一进行递归处理。
程序清单如下:
1 //2d9-1 随机划分线性时间选择 2 #include "stdafx.h" 3 #include <iostream> 4 #include <ctime> 5 using namespace std; 6 7 int a[] = {5,7,3,4,8,6,9,1,2}; 8 9 template <class Type> 10 void Swap(Type &x,Type &y); 11 12 inline int Random(int x, int y); 13 14 template <class Type> 15 int Partition(Type a[],int p,int r); 16 17 template<class Type> 18 int RandomizedPartition(Type a[],int p,int r); 19 20 template <class Type> 21 Type RandomizedSelect(Type a[],int p,int r,int k); 22 23 int main() 24 { 25 for(int i=0; i<9; i++) 26 { 27 cout<<a[i]<<" "; 28 } 29 cout<<endl; 30 cout<<RandomizedSelect(a,0,8,3)<<endl; 31 } 32 33 template <class Type> 34 void Swap(Type &x,Type &y) 35 { 36 Type temp = x; 37 x = y; 38 y = temp; 39 } 40 41 inline int Random(int x, int y) 42 { 43 srand((unsigned)time(0)); 44 int ran_num = rand() % (y - x) + x; 45 return ran_num; 46 } 47 48 template <class Type> 49 int Partition(Type a[],int p,int r) 50 { 51 int i = p,j = r + 1; 52 Type x = a[p]; 53 54 while(true) 55 { 56 while(a[++i]<x && i<r); 57 while(a[--j]>x); 58 if(i>=j) 59 { 60 break; 61 } 62 Swap(a[i],a[j]); 63 } 64 a[p] = a[j]; 65 a[j] = x; 66 return j; 67 } 68 69 template<class Type> 70 int RandomizedPartition(Type a[],int p,int r) 71 { 72 int i = Random(p,r); 73 Swap(a[i],a[p]); 74 return Partition(a,p,r); 75 } 76 77 template <class Type> 78 Type RandomizedSelect(Type a[],int p,int r,int k) 79 { 80 if(p == r) 81 { 82 return a[p]; 83 } 84 int i = RandomizedPartition(a,p,r); 85 int j = i - p + 1; 86 if(k <= j) 87 { 88 return RandomizedSelect(a,p,i,k); 89 } 90 else 91 { 92 //由于已知道子数组a[p:i]中的元素均小于要找的第k小元素 93 //因此,要找的a[p:r]中第k小元素是a[i+1:r]中第k-j小元素。 94 return RandomizedSelect(a,i+1,r,k-j); 95 } 96 }