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