1. 程式人生 > >求兩個等長有序序列的中位數

求兩個等長有序序列的中位數

/*現有兩個等長的升序序列的序列A,B,試設計一個時間和空間都儘可能高效的演算法,找出兩個序列的中位數

演算法的基本思想是:分別求出兩個序列的中位數,即為a b,有下列三種情況
1:a=b;即a 為兩個序列的中位數
2:a<b: 則中位數只能出現在a和b之間,在序列A中捨棄a之後的元素的到序列A1,在序列B中捨棄b之前的元素,得到序列B1
3:a>b:則中位數只能出現在b和a之間,在序列a中捨棄A之後的元素得到序列A1,在序列B中捨棄b之前的元素,得到B1;
在A1和B1中分別求出中位數,重複上述過程,得到倆個序列中只有一個元素,則較小者即為所求

*/

#include<iostream>
using namespace std;
void ZhWei(int m[],int n[],int k)
{
int s1=0,e1=k-1,s2=0,e2=k-1;//初始化初始化兩個序列的上下限;
int mid1;
int mid2;
while(s1<e1&&s2<e2)
{
 mid1=(s1+e1)/2;//序列m的中位數下標
 mid2=(s2+e2)/2;//中位數n的中位數下標
 if(mid1==mid2)
 {
     cout<<m[mid1];
     return;
 }
 else if(m[mid1]<n[mid2])
 {
  s1=mid1+1;
  if((s2+e2)%2==0)
  {
   e2=mid2-1;
  }
   else e2=mid2;
 }
  else
  {
   s2=mid2+1;
   if((s1+e1)%2==0)
   {
    e1=mid1-1;
   }
    else
    {
     e1=mid1;
    }
  }
}

  if(m[s1]<n[s2])//較小者即為所求
  cout<<m[s1];
  else
  
  cout<<n[s2];
   return;
 }

 void main()
 {
  int n[100];
  int m[100];
  int k;
  cout<<"陣列元素的個數"<<endl;
  cin>>k;
  for(int i=0;i<k;i++)
  {
   cin>>n[i];
  
  }
  for(int j=0;j<k;j++)
  {

 cin>>m[j];
  }
     ZhWei(m,n, k);

 }

由於每次求兩個有序序列的中位數後,得到的兩個子序列的長都是上溢序列的一半,因此迴圈共執行log2n次,時間複雜度為O(log2n),演算法除簡單變數外沒有額外開闢儲存空間 ,因此空間複雜度為O(1)