您的位置:首页 > 其它

求两个有序数组的中位数之非递归实现

2014-11-10 19:18 411 查看
作者:静水流风

求两个有序数组的中位数,一般都是用递归方式来实现。

我自己写了一个非递归实现版本,供大家参考。如果有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: