1. 程式人生 > >求等長升序序列A、B的中位數

求等長升序序列A、B的中位數

分別求A、B序列的中位數a,b;

  1. 若a=b;則a或b為所求中位數,演算法結束;
  2. 若a<b;則捨棄序列A中較小一半,捨棄序列B中較大一半;(注:需保證捨棄長度相等,程式碼分奇偶處理即保證等長)
  3. 若a>b;則捨棄序列A中較大一半,捨棄序列B中較小一半;(注:需保證捨棄長度相等,程式碼分奇偶處理即保證等長)
  4. 在保留的兩個序列中,重複1、2、3步,直到兩個序列均只含一個數為止,返回較小者為中位數。

注:這裡定義的含n個元素的序列第int((n+1)/2)個元素為中位數,即元素個數/2向上取整。

#include <bits/stdc++.h>

#define ArrayLen(array) sizeof(array)/sizeof(array[0])
/*
* Created by HarvestWu on 2018/11/11.
*/
using namespace std;
int M_Search(int A[], int B[], int n){
	int start1 = 0, end1 = n - 1;	//序列A首、尾數
	int start2 = 0, end2 = n - 1;	//序列B首、尾數
	int mid1, mid2;					//序列A、B中位數
	while (start1 != end1 || start2 != end2){
		mid1 = (start1 + end1) / 2;
		mid2 = (start2 + end2) / 2;
		if (A[mid1] == B[mid2])
			return A[mid1];
		if (A[mid1] < B[mid2]){				
			if ((end1 - start1) % 2 == 0){	//奇數個元素
				start1 = mid1;				//捨棄A中點以前的部分並保留中點
				end2 = mid2;				//捨棄B中點以後的部分並保留中點
			}
			else{							//偶數個元素
				start1 = mid1+1;			//捨棄A中點及其以前的部分
				end2 = mid2;				//捨棄B中點以後的部分並保留中點
			}
		}
		else{
			if ((end2 - start2) % 2 == 0){	//奇數個元素
				start2 = mid2;				//捨棄B中點以前的部分並保留中點
				end1 = mid1;				//捨棄A中點以後的部分並保留中點
			}
			else{							//偶數個元素
				start2 = mid2 + 1;			//捨棄B中點及其以前的部分
				end1 = mid1;				//捨棄A中點以後的部分並保留中點
			}
		}
	}
	return A[start1] < B[start2] ? A[start1] : B[start2];
}

int main(){

	int A[] = { 1, 3, 5, 7, 9,11 };
	int B[] = { 2, 4, 6, 8, 10 ,12};

	cout << M_Search(A, B, ArrayLen(A));
	return 0;
}