递归与分治策略之利用中位数线性时间选择
前言
這一篇文章就上上一篇博文算法的進(jìn)一步優(yōu)化了!
這里我們就利用中位數(shù)來(lái)進(jìn)行線性時(shí)間的選擇算法!
中位數(shù)就是指將數(shù)據(jù)按大小順序排列起來(lái),形成一個(gè)數(shù)列,居于數(shù)列中間位置的那個(gè)數(shù)據(jù)就是中位數(shù)。
算法思路
(1)將輸入的n個(gè)數(shù)劃分成 ?n5? 個(gè)組,當(dāng)然最后一組的數(shù)目可能是小于5的!
(2)用任意的排序方法對(duì)他們進(jìn)行排序,并取出一共 ?n5? 個(gè)中位數(shù)。
(3)找出該 ?n5? 個(gè)中位數(shù)中的中位數(shù)。(如果 ?n5? 是偶數(shù)則取相對(duì)大的那個(gè)數(shù))
(4)將全部的數(shù)劃分為兩個(gè)部分,小于基準(zhǔn)的在左邊,大于等于基準(zhǔn)的放右邊。
我們用小圓點(diǎn)表示元素,得到如下圖:
說(shuō)明:
圖中中間白色圈表示各組數(shù)據(jù)的中位數(shù),最中間灰色表示中位數(shù)的中位數(shù)! 箭頭是從較小的數(shù)指向較大的數(shù)!
故我們可以使用該數(shù)作為劃分的基準(zhǔn)(比上一個(gè)隨機(jī)基準(zhǔn)的方法會(huì)好很多)!
圖中
3?A1=3?(n?5)10當(dāng)n≥75時(shí),3A1大于等于 14n。所以按此基準(zhǔn)劃分所得的左右2個(gè)子數(shù)組的長(zhǎng)度都至少縮短 14。
代碼描述
int Select(int a[],int p,int r,int k) { if(r-p<75) { //這里對(duì)數(shù)組 a[p->r] 進(jìn)行排序 return a[p+k-1]; } //(r-p-4)/5相當(dāng)于n-5 for(int i=0; i<=(r-p-4)/5; i++) { //這里將元素每5個(gè)分成一組,分別排序,并將該組中位數(shù)與a[p+i]交換位置 //使所有中位數(shù)都排列在數(shù)組最左側(cè),以便進(jìn)一步查找中位數(shù)的中位數(shù) } int x = Select(a,p,p+(r-p-4)/5,(r-p-4)/10); //找中位數(shù)的中位數(shù) int i = Partition(a,p,r,x); //以x為基準(zhǔn)對(duì)數(shù)組a進(jìn)行劃分 int j = i-p+1; if(k<=j) { return Select(a,p,i,k); } else { return Select(a,i+1,r,k-j); } }總結(jié)
以上是生活随笔為你收集整理的递归与分治策略之利用中位数线性时间选择的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 前端学习(2951):上午回顾
- 下一篇: [html] 制作一个页面时,需要兼容P