演算法課的題目,給定兩個整數陣列x, y,兩個陣列已被排序(公升序),陣列長度都是n,求這2n個數的中位數。
最容易想到的是,新建立以個陣列 z[2n],將x,y的所有元素排序放入,然後取中間兩個數,不過當陣列很大時,效率不行啊。<^_^>,不僅空間複雜度很大,重新排序的話也要不少時間.
分析:因為兩個陣列已經排序了,可以找找規律嗎?這樣就可以直接找出和中位數有關的幾個元素(兩個???)。若x的最大元素小於y的最小元素(或者y的最大元素小於x的最小元素),答案就出來了。如果把x看成是從x[0]到x[maxindex]的連續區間(數抽???),y也是如此。那麼,兩個區間可能有重疊部分,可能完全不重疊,也可能大區間完全包含小區間......
雖然最終確定應該借鑑二分搜尋的思想,但是有很多問題不會證明,只是從同學那裡知道應該這樣,呵呵。以後再試試證明吧,數學沒學好啊。。。。
#include #include /* 比較兩個整數[ x and y]大小的函式.
* return values:
* 1: x > y.
* 0: x == y.
* -1: x < y.
* */
int compare(int x, int y)
//這是個簡單的排序函式, 你懂得<^_^>.
void sortfour(int a, int n)}}
}/* 這個才是主角, 給定兩個長度為(maxindex + 1)的陣列x, y,
* 兩個陣列已被排序(公升序). 使用二分的思想求兩個陣列所有元素的中位數.
* 因為總元素數為偶數,故中位數由中間的兩個數合成。這兩個數可能位
* 於同乙個陣列裡,故每個陣列二分時,最後保留兩個元素,一共
* 四個,再排序,取中間兩個。
* */
double findmedian(const int x, const int y, int maxindex)
int lx, ly, rx, ry, mx, my;
lx = ly = 0;
rx = ry = maxindex;
while ( lx < (rx - 1) )//當只剩兩個(嚴格的說,包括少於兩個的情況,
//額,那就是乙個嘍)元素時,就跳出.
else
switch( compare(x[mx], y[my]) )
}//最後的四個數,
int a[4];
a[0] = x[lx];
a[1] = x[rx];
a[2] = y[ly];
a[3] = y[ry];
sortfour(a, 4);//排個序
//結果用double 存放,保留小數.
double result = (double)(a[1] + a[2]) / 2;
return result;
}int main(void)
while (n < 1);
int num_1[n];
int num_2[n];
printf("inpuut the data of group 1:");
fflush(stdin);
for (i = 0; i < n; ++i)
printf("inpuut the data of group 2:");
fflush(stdin);
for (i = 0; i < n; ++i)
result = findmedian(num_1, num_2, n - 1);
printf("the result is : %.2f", result);
getch();
return 0;
}
求解兩個等長公升序序列的中位數
2011年計算機聯考真題 題目描述 乙個長度為l l 1 的公升序序列s,處在第 l 2 個位置的數稱為s的中位數。例如,若序列s1 11,13,15,17,19 則s1的中位數是15,兩個序列的中位數是含它們所有元素的公升序序列的中位數。例如,若s2 2,4,6,8,20 則s1和s2的中位數是1...
求兩個有序非等長陣列中位數
本部落格所用演算法是受另外一篇部落格所啟發,但該博主給出的 很多邊界條件和n m為偶數的情況未考慮到,這裡我做了一定的完善。原題如下 there are two sorted arrays nums1 and nums2 of size m and n respectively.find the m...
求兩個等長有序陣列的中位數
設兩個有序陣列的長度均為n,求它們組成的2n長的陣列的中位數。首先說明下中位數的定義 統計學名詞,當變數值的項數n為奇數時,處於中間位置的變數值即為中位數 當n為偶數時,中位數則為處於中間位置的2個變數值的平均數。中位數有個性質 在中位數兩側去掉任意數量的數後,中位數不變 為了簡化,先假設n為奇數,...