BFPRT算法求无序数组中第k个值
很好的总结在这:
http://blog.csdn.net/acdreamers/article/details/44656295
BFPRT的两个过程:
I.将数组进行分组,并对每个组进行插入排序,最后得到整体的中位数。时间复杂度为O(n);
II.根据上一步的到的中位数,进行递归划分
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // BFPRT.cpp : 定义控制台应用程序的入口点。 2 //主要过程I.得到中位数的中位数 II.根据中位数进行划分 3 // 4 5 #include "stdafx.h" 6 #include <iostream> 7 8 using namespace std; 9 10 void InsertSort(int*a,int left,int right) 11 { 12 for(int i = left + 1; i != right + 1; i++) 13 { 14 for(int j = i;j != left;j--) 15 { 16 if(a[j-1] > a[j]) 17 swap(a[j-1],a[j]); 18 else 19 break; 20 } 21 } 22 } 23 24 int FindMid(int *a,int left,int right) 25 { 26 if(left == right) 27 return a[left]; 28 int i = 0; 29 int n = 0; 30 for(i = left;i < right-5;i += 5) 31 { 32 InsertSort(a,i,i+4); 33 n = i - 1;// 得到n,n/5即为当前处理的组数 34 swap(a[left + n / 5],a[i + 2]); 35 //排序后,a[i+2]都为各组的中位数。将中位数依次交换到前边 36 } 37 38 //处理剩余的数据,假设14个数,i = 10时,不满足i<r-5没有进入循环体, 39 int num = right - i + 1;//最后一个分组的长度 40 if(num > 0) 41 { 42 InsertSort(a,i,i+num-1); 43 n = i - 1; 44 swap(a[left+n/5],a[i+num/2]); 45 //a[i+num/2]中i为剩余数组开头,长度为num,中位数偏移为num/2 46 } 47 n /= 5;//上一次所得中位数组数;如14个数,第一次寻找得到3个中位数,分别 48 //被交换到了数组开始的位置。n = i - 1 (=9);n /= 5;(n = 9/5 == 1), 49 //即只得到一组中位数 50 51 if(n == left) 52 return a[left]; 53 else 54 return FindMid(a,left,left+n); 55 } 56 57 int FindId(int*a,int left,int right,int midNum) 58 { 59 for(int i = left;i <= right;i++) 60 if(a[i] == midNum) 61 return i; 62 return -1; 63 } 64 65 66 //划分过程 67 int myPartition(int *a,int left,int right,int med_index) 68 { 69 swap(a[right],a[med_index]); 70 int pivot = a[right]; 71 72 while(left < right) 73 { 74 while(left < right && a[left] < pivot) 75 ++left; 76 if(left < right) 77 swap(a[left],a[right]); 78 while(left < right && a[right] >= pivot) 79 --right; 80 if(left < right) 81 swap(a[left],a[right]); 82 } 83 return left; 84 } 85 86 int bfprt(int *a,int left,int right,int k) 87 { 88 int midNum = FindMid(a,left,right);//找中位数的中位数 89 int id = FindId(a,left,right,midNum);//得到中位数对应的下标 90 int index = myPartition(a,left,right,id);//划分 91 92 int m = index - left + 1;//划分所得结果是数组中第几个数 93 94 if(m == k)return a[index]; 95 else if (m > k) 96 return bfprt(a,left,index-1,k); 97 else 98 return bfprt(a,index+1,right,k-m); 99 return 0; 100 } 101 102 103 int _tmain(int argc, _TCHAR* argv[]) 104 { 105 int n; 106 cout<<"请输入n:"<<endl; 107 cin>>n; 108 int *a = new int[n]; 109 cout<<"请输入"<<n<<"数组成数组:"<<endl; 110 for(int i = 0; i < n;i++) 111 cin>>a[i]; 112 113 int k; 114 cout<<"请输入k:"<<endl; 115 cin>>k; 116 117 cout<<"第"<<k<<"个数为:"<<bfprt(a,0,n-1,k)<<endl; 118 system("pause"); 119 return 0; 120 }