求两个有序数组的中位数之非递归实现
2014-11-10 19:18
411 查看
作者:静水流风
求两个有序数组的中位数,一般都是用递归方式来实现。
我自己写了一个非递归实现版本,供大家参考。如果有bug,请不吝赐教。
此函数求在元素总数为奇数时求出唯一中位数,在偶数情况下,求出下中位数。
该算法的时间复杂度为O(k), k为两数组中较短数组的长度。
算法思路:
1.采用分而治之。
2.以短数组为中心,以折半方式逐步缩小范围,以耗尽短数组。
附上测试程序:
求两个有序数组的中位数,一般都是用递归方式来实现。
我自己写了一个非递归实现版本,供大家参考。如果有bug,请不吝赐教。
此函数求在元素总数为奇数时求出唯一中位数,在偶数情况下,求出下中位数。
该算法的时间复杂度为O(k), k为两数组中较短数组的长度。
int find_median(int *a, int lengtha, int *b, int lengthb) { assert(lengtha > 0); assert(lengthb > 0); int *sa = lengtha <= lengthb ? a : b; int *la = lengtha <= lengthb ? b : a; const int lens = lengtha <= lengthb ? lengtha: lengthb; const int lenl = lengtha <= lengthb ? lengthb: lengtha; const int c = (lens + lenl -1) / 2; int ls = 0; int us = lens - 1; while (ls <= us) { const int cs = (us + ls) / 2; const int cl = c - cs; if (sa[cs] < la[cl]) { if (ls != cs) ls = cs; else if (cl == 0 || sa[cs] >= la[cl-1]) return sa[cs]; else if (us == cs) return la[cl-1]; else ls = cs + 1; } else if (sa[cs] > la[cl]) { if (us != cs) us = cs; else if (cs == 0 || la[cl] >= sa[cs-1]) return la[cl]; else us = cs - 1; } else { return sa[cs]; } } assert(0); return 0; }
算法思路:
1.采用分而治之。
2.以短数组为中心,以折半方式逐步缩小范围,以耗尽短数组。
附上测试程序:
#include <iostream> #include <assert.h> #include <vector> #include <algorithm> // 编译时,请在此处插入find_median的实现体 int test_find_median(int *A, int sizeA, int *B, int sizeB) { for (int i=0; i< sizeA; i++) std::cout << A[i] << " "; std::cout << std::endl; for (int i=0; i< sizeB; i++) std::cout << B[i] << " "; std::cout << std::endl; const int median = find_median(A,sizeA,B,sizeB); std::cout<<"my median : "<< median <<std::endl;; std::vector<int> a(A, A+sizeA); a.insert(a.end(), B, B+sizeB); std::sort(a.begin(), a.end()); const int stl_median = a[(a.size()-1)/2]; std::cout<<"stl median : "<< stl_median <<std::endl;; assert(stl_median == median); return 0; } int main(int argc, char* argv[]) { { int A[] = {5,6,7} ; int B[] = {2,4}; test_find_median(A, sizeof(A)/sizeof(int), B, sizeof(B)/sizeof(int)); } { int A[] = {1,3,5} ; int B[] = {6,7}; test_find_median(A, sizeof(A)/sizeof(int), B, sizeof(B)/sizeof(int)); } { int A[] = {1,3,5} ; int B[] = {2,4}; test_find_median(A, sizeof(A)/sizeof(int), B, sizeof(B)/sizeof(int)); } { int A[] = {1,2,3,6,8} ; int B[] = {6,7,8,9,10}; test_find_median(A, sizeof(A)/sizeof(int), B, sizeof(B)/sizeof(int)); } { int A[] = {1,3,5,7,9,11} ; int B[] = {2,4,6,8,10,12}; test_find_median(A, sizeof(A)/sizeof(int), B, sizeof(B)/sizeof(int)); } { int A[]={2}; int B[]={1,3,5}; test_find_median(A, sizeof(A)/sizeof(int), B, sizeof(B)/sizeof(int)); } { int A[]={1,3,5,7,8,9,10}; int B[]={2,4,6,10,11,12,13,14,17,19,20}; test_find_median(A, sizeof(A)/sizeof(int), B, sizeof(B)/sizeof(int)); } return 0; }
相关文章推荐
- Java实现O(log(n+m))两个有序数组中第K大元素或中位数
- 算法练习4.Median of Two Sorted Arrays两个有序数组的中位数(递归、分治)
- 求两个有序数组的中位数
- 求两个等长有序数组的中位数的logN算法 分治法
- 求两个有序数组的中位数
- 寻找两个有序数组合并之后的中位数
- 给定两个有序的n长度的数组,如何找出这两个数组合并后的中位数?
- 给定两个有序数组求他们的中位数
- 求两个等长有序数组的中位数的logN算法 分治法
- 给定两个长度相同,分别有序的数组A和B,求两个数组中所有数的中位数
- 实现两个有序数组的归并
- 用递归方法实现两个链表head1和head2各自有序,请把它们合并成一个链表仍然有序。(c/c++)
- 合并两个有序数组Java实现
- 递归实现合并两个有序链表成一个链表依然有序
- 两个有序链表合并递归实现及非递归实现
- 求两个有序数组的中位数
- 求两个有序数组的中位数
- 两个有序数组的中位数 Median of Two Sorted Arrays
- [转载]寻找两个有序数组中的第K个数或者中位数
- 求两个不等长的有序数组的中位数