2n个数的中位数问题_python_算法与数据结构

问题 :
对于两个长度均为n的已排序的序列,确定这两个序列的2n个元素的中位数。

解决此问题的算法思想:
设两个长度为n的数列分别为x[ 0 : n -1]和y[ 0 : n -1],分别找出这两个数列的中位数x[i]和
y[ j ],二者进行比较,根据比较结果可以在每个数列中减少一半的搜索范围,然后再分别取
两个子数列的中位数再比较,再减少搜索范围,继续下去直到找到最后结果。采用分治法来做,时间复杂度:O(lgn).

   网址:中位数问题 对这个问题进行了较为深入的阐述。下面给出了Python的代码实现:

def fidMid(cx1,cx2):
    size = len(cx1)
    mid = (size -1) //2
    midSize = mid 
    if(size %2 == 0):
        midSize = mid+1 
    if (size ==1 ):
        if(cx1[0] >=cx2[0]):
            return cx2[0]
        else:
            return cx1[0]
    if(cx1[mid] <=cx2[mid]):
        for i in range(0, midSize):
                 cx1.pop(0)
                 cx2.pop()
           
    else:
        for i in range(0, midSize):
                 cx1.pop()
                 cx2.pop(0)

    return fidMid(cx1, cx2)
if '__name__ = __main__' :
     x=[10, 15, 16, 19]
     y=[11, 17, 18, 20]
     print(fidMid(x, y))
 

复杂性分析:采用了二分查找的办法,树的节点个数为2n,因此算法的时间复杂度为clip_image002= clip_image004.

下面是网上别人的C++代码:

#include <iostream>    
#include <fstream>    
#include <vector>    
#include <string>    
   
using namespace std;   
#include<stdlib.h>    
   
int findMiddle(vector<int> a, vector<int> b)   
{   
    int size = a.size();   
    int mid_size = size/2;   
    if(size == 1)   
    {   
        if(a[0] > b[0])   
            return b[0];   
        else   
            return a[0];   
    }   
   
    if(a[mid_size] < b[mid_size])   
    {   
        copy (a.begin()+mid_size, a.end(),      
             a.begin());   
         for(int i = 0; i < mid_size; i++)   
          {   
            a.pop_back();   
          }   
         if((size%2) == 0)   
         {   
             for(int j = mid_size; j < size; j++)   
             {   
                b.pop_back();   
             }   
   
         }   
         else   
         {   
             for(int j = mid_size; j < size - 1; j++)   
             {   
                b.pop_back();   
             }   
   
         }   
            
   
        return  findMiddle(a,b);   
    }   
    else if(a[mid_size] > b[mid_size])   
    {   
           
        copy (b.begin()+mid_size, b.end(),      
             b.begin());   
         for(int i = 0; i < mid_size; i++)   
          {   
            b.pop_back();   
          }   
         if((size%2) == 0)   
         {   
             for(int j = mid_size; j < size; j++)   
             {   
                a.pop_back();   
             }   
   
         }   
         else   
         {   
             for(int j = mid_size; j < size - 1; j++)   
             {   
                a.pop_back();   
             }   
   
         }   
        return  findMiddle(a,b);   
    }   
    else    
        return a[mid_size];   
   
}   
   
int main()   
{   
    vector<int> a;   
    vector<int> b;   
   
    int number;   
    int mid_number;   
    int temp = 0;   
    int i = 0;   
    int j = 0;     
   
    ifstream infile;   
    ofstream outfile;   
   
    infile.open("middleNumber.txt");   
    outfile.open("out.txt");   
   
    if(!infile)   
    {   
        cerr << "Can not open middleNumber file!" << endl;   
        return 0;   
    }   
   
    if(!outfile)   
    {   
        cerr << "Can not open OUT file!" << endl;   
        return 0;   
    }   
       
        infile >> number;   
           
        for(i = 0; i < number; i++)   
        {   
            infile >> temp;   
            a.push_back(temp);   
   
        }   
   
        for(i = 0; i< number; i ++)   
        {   
            infile >> temp;   
            b.push_back(temp);   
        }   
           
//      cout << a[0] << "  " << a[1] << "   " << a[2] << endl;    
//      cout << b[0] << "  " << b[1] << "  " << b[2] << endl;    
   
        mid_number = findMiddle(a,b);   
   
        outfile << mid_number;   
        cout << mid_number << endl;   
   
        return 0;   
   
  
}  

转载于:https://www.cnblogs.com/ChenxofHit/archive/2011/03/16/1986591.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值