#include <iostream> #include <cstring> #include <cmath> #include <ctime> #include <cstdio> #include "windows.h" #include <algorithm> using namespace std; const int sup = 1010; int aryA[sup], aryB[sup]; /** 二分法求数组aryA从s1到e1,aryB从s2到e2,第k大的数 思路如下: 1,首先取二者的中点位置idxA = k / 2, idxB = k / 2, 然后判断aryA[idxA]和aryB[idxB]的大小关系, 假如相等,那么表示已经找到,为aryA[idxA];否则,不失一般性: 假设aryA[idxA] < aryB[idxB],那么第k大的元素一定在aryB的 前k / 2个数中,取aryB的前k / 4的元素,idxB = k / 4, aryA后k / 4 的元素,idxA = idxA + k / 4;重复上述过程,不断二分。 程序中求的是第k小的数 */ bool myCMP(int a, int b) { return a < b; } int Bsearch(int s1, int e1, int s2, int e2, int kth) { int idxA = (s1 + e1) >> 1; int idxB = (s2 + e2) >> 1; int lenA = idxA - s1 + 1; int lenB = idxB - s2 + 1; if(s1 > e1) lenA = 0; if(s2 > e2) lenB = 0; int Len = lenA + lenB;//两个数组中当前取出的元素个数和 if(Len > kth)//超过了要求的k个元素,那么根据不同情况, //将两个数组中的一个截掉后半部分,保留前半部分 { if(0 != lenB && (0 == lenA || aryA[idxA] <= aryB[idxB]))//数组A中没元素或者当前aryB中的中间元素更大,那么第k大的元素倾向于存在aryB的前半部分中 return Bsearch(s1, e1, s2, idxB - 1, kth);//截掉aryB数组中一半元素的前提是aryB中还有元素 else return Bsearch(s1, idxA - 1, s2, e2, kth);//否则只能截取aryA中的元素 } else//两个数组中选取的元素个数不够k个,那么根据不同情况, //将两个数组中的一个后移到后半部分 { if(kth == Len)//正好够 { if(0 == lenA) return aryB[idxB]; else if(0 == lenB) return aryA[idxA];//并且其中一个是空 } if(0 != lenA && (0 == lenB || aryA[idxA] <= aryB[idxB]))//道理类似上面 return Bsearch(idxA + 1, e1, s2, e2, kth - lenA); // 已经知道前lenA个大的,然后就是在剩下的元素中找到第kth - lenA大的数 else return Bsearch(s1, e1, idxB + 1, e2, kth - lenB); } } const int MAX_RAND = 10000; void Generate(int& n, int& m, int& k) { srand((unsigned)GetCurrentTime()); n = rand() % 16; m = rand() % 16; k = rand() % (m + n); k == 0? k = 1: k = k; for(int i = 0; i < n; ++ i) aryA[i] = rand() % MAX_RAND; for(int i = 0; i < m; ++ i) aryB[i] = rand() % MAX_RAND; } void OUTPUT(int n, int m) { for(int i = 0; i < n; ++ i) printf("%d ", aryA[i]); puts(""); for(int i = 0; i < m; ++ i) printf("%d ", aryB[i]); puts(""); } int main() { int n, m, k; //scanf("%d %d %d", &n, &m, &k); Generate(n, m, k); sort(aryA, aryA + n, myCMP); sort(aryB, aryB + m, myCMP); OUTPUT(n, m); printf("The %dth number in the two ascending arrays is:/n", k); printf("%d/n", Bsearch(0, n - 1, 0, m - 1, k)); return 0; } /** 786 3891 4258 4694 7130 7899 357 720 1292 2579 7889 9255 9611 The 7th number in the two ascending arrays is: 7 */ nlogn复杂度,同时此方法能推广到多个有序数组求第k大数。