分治法--线性时间选择(求第k小数)
線性時(shí)間選擇問(wèn)題:
給定線性序集中n個(gè)元素和一個(gè)整數(shù)k,1≤k≤n,要求找出這n個(gè)元素中第k小的元素,(這里給定的線性集是無(wú)序的)。 ? ? ?
1、隨機(jī)劃分線性選擇 ? ? ? ?
線性時(shí)間選擇隨機(jī)劃分法可以模仿隨機(jī)化快速排序算法設(shè)計(jì)。基本思想是對(duì)輸入數(shù)組進(jìn)行遞歸劃分,與快速排序不同的是,它只對(duì)劃分出的子數(shù)組之一進(jìn)行遞歸處理。
利用隨機(jī)函數(shù)產(chǎn)生劃分基準(zhǔn),將數(shù)組a[p:r]劃分成兩個(gè)子數(shù)組a[p:i]和a[i+1:r],使a[p:i]中的每個(gè)元素都不大于a[i+1:r]中的每個(gè)元素。接著"j=i-p+1"計(jì)算a[p:i]中元素個(gè)數(shù)j.如果kj,則第k小元素在子數(shù)組a[i+1:r]中。注意:由于已知道子數(shù)組a[p:i]中的元素均小于要找的第k小元素,因此,要找的a[p:r]中第k小元素是a[i+1:r]中第k-j小元素。 ? ? ? 在最壞的情況下,例如:總是找到最小元素時(shí),總是在最大元素處劃分,這是時(shí)間復(fù)雜度為O(n^2)。但平均時(shí)間復(fù)雜度與n呈線性關(guān)系,為O(n) 。
Type RandomizedSelect(Type a[],int p,int r,int k) {if (p==r) return a[p];int i=RandomizedPartition(a,p,r),j=i-p+1;if (k<=j) return RandomizedSelect(a,p,i,k);else return RandomizedSelect(a,i+1,r,k-j); }2、利用中位數(shù)線性時(shí)間選擇
中位數(shù):是指將數(shù)據(jù)按大小順序排列起來(lái),形成一個(gè)數(shù)列,居于數(shù)列中間位置的那個(gè)數(shù)據(jù)。
例子:
?按遞增順序,找出下面29個(gè)元素的第18個(gè)元素:8,31,60,33,17,4,51,57,49,35,11,43,37,3,13,52,6,19,25,32,54,16,5,41,7,23,22,46,29.
?(1) 把前面25個(gè)元素分為5=floor(29/5)組;? (8,31,60,33,17),(4,51,57,49,35),(11,43,37,3,13),(52,6,19,25,32),(54,16,5,41,7).
?(2) 提取每一組的中值元素,構(gòu)成集合{31,49,13,25,16};
?(3) 遞歸地使用算法求取該集合的中值,得到m=25;
?(4) 根據(jù)m=25, 把29個(gè)元素劃分為3個(gè)子數(shù)組:
–P={8,17,4,11, 3,13,6,19,16,5,7,23,22}
–Q={25}
–R={31,60,33,51,57,49,35,43,37,52,32,54,41,46,29}
?(5) 由于|P|=13,|Q|=1,k=18,所以放棄P,Q,使k=18-13-1=4,對(duì)R遞歸地執(zhí)行本算法;
?(6) 將R劃分成3(floor(15/5))組:{31,60,33,51,57},{49,35,43,37,52},{32,54,41,46,29}
?(7) 求取這3組元素的中值元素分別為:{51,43,41},這個(gè)集合的中值元素是43;
?(8) 根據(jù)43將R劃分成3組:
–{31, 33, 35,37,32, 41, 29},{43},{60, 51,57, 49, 52,54, 46}
?(9)? 因?yàn)?/span>k=4,第一個(gè)子數(shù)組的元素個(gè)數(shù)大于k,所以放棄后面兩個(gè)子數(shù)組,以k=4對(duì)第一個(gè)子數(shù)組遞歸調(diào)用本算法;
?(10)? 將這個(gè)子數(shù)組分成5個(gè)元素的一組:{31,33,35,37,32},取其中值元素為33;
?(11)? 根據(jù)33,把第一個(gè)子數(shù)組劃分成{31,32,29},{33},{35,37,41};
?(12)? 因?yàn)?/span>k=4,而第一、第二個(gè)子數(shù)組的元素個(gè)數(shù)為4,所以33即為所求取的第18個(gè)小元素。
Type Select(Type a[], int p, int r, int k) {if (r-p<75) {用某個(gè)簡(jiǎn)單排序算法對(duì)數(shù)組a[p:r]排序;return a[p+k-1];};for ( int i = 0; i<=(r-p-4)/5; i++ )將a[p+5*i]至a[p+5*i+4]的第3小元素與a[p+i]交換位置;//找中位數(shù)的中位數(shù),r-p-4即上面所說(shuō)的n-5Type x = Select(a, p, p+(r-p-4)/5, (r-p-4)/10);int i=Partition(a,p,r, x),j=i-p+1;if (k<=j) return Select(a,p,i,k);else return Select(a,i+1,r,k-j); }實(shí)現(xiàn)步驟:
算法思路:
如果能在線性時(shí)間內(nèi)找到一個(gè)劃分基準(zhǔn)使得按這個(gè)基準(zhǔn)所劃分出的2個(gè)子數(shù)組的長(zhǎng)度都至少為原數(shù)組長(zhǎng)度的ε倍(0<ε<1),那么就可以在最壞情況下用O(n)時(shí)間完成選擇任務(wù)。例如,當(dāng)ε=9/10,算法遞歸調(diào)用所產(chǎn)生的子數(shù)組的長(zhǎng)度至少縮短1/10。所以,在最壞情況下,算法所需的計(jì)算時(shí)間T(n)滿足遞推式T(n)<=T(9n/10)+O(n)。由此可得T(n)=O(n)。
?
總結(jié)
以上是生活随笔為你收集整理的分治法--线性时间选择(求第k小数)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mes建设指南_给予和接受建设性批评的设
- 下一篇: open-falcon_NASA在Fal