求兩個等長升序序列的中位數
阿新 • • 發佈:2019-02-08
1. 演算法要求
一個長度為L(L≥1)的升序序列S,處在第L / 2(若為小數則去掉小數後加1)個位置的數稱為S 的中位數。例如,若序列S1=(11,13,15,17,19),則S1 的中位數是15,兩個序列的中位數是含它們所有元素的升序序列的中位數。例如,若S2=(2,4,6,8,20),則S1 和S2 的中位數是11。現在有兩個等長升序序列A 和B,試設計一個在時間和空間兩方面都儘可能高效的演算法,找出兩個序列A 和B 的中位數。
2. 演算法思想
分別求出序列A 和B 的中位數,設為a 和b,求序列A 和B 的中位數過程如下:
1)若a=b,則a 或b 即為所求中位數,演算法結束。
2)若a<b,則捨棄序列A 中較小的一半,同時捨棄序列B 中較大的一半,要求捨棄的長度相等;
3)若a>b,則捨棄序列A 中較大的一半,同時捨棄序列B 中較小的一半,要求捨棄的長度相等;
在保留的兩個升序序列中,重複過程1)、2)、3),直到兩個序列中只含一個元素時為止,較小者即為所求的中位數。
3. 演算法實現
int get_middle_number(int a[], int b[], int n) { int start1 = 0, end1 = n-1, m1; int start2 = 0, end2 = n-1, m2; while (start1 != end1 || start2 != end2) { m1 = (start1 + end1) / 2; m2 = (start2 + end2) / 2; if (a[m1] == b[m2]) return a[m1]; if (a[m1] < b[m2]) { if ((start1+end1) % 2 == 0) { start1 = m1; end2 = m2; } else { start1 = m1 + 1; end2 = m2; } } else { if ((start1+end1) % 2 == 0) { end1 = m1; start2 = m2; } else { end1 = m1; start2 = m2 + 1; } } } return a[start1] < b[start2] ? a[start1] : b[start2]; }
4. 實現原始碼