線性時間選擇問題

2021-08-09 08:54:43 字數 3278 閱讀 8642

將n個元素劃分成n/5組,每組5個元素,只可能有一組不是5個元素。再用氣泡排序法,將每組內的五個元素排好序,取出其中位數,共n/5個。

然後遞迴呼叫select方法找出這n/5個數中的中位數。若n/5是偶數,就找其最大的數。以這個元素作為劃分標準。判斷k與n的位置,再進行下一步的劃分。

以[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]為例查詢這29個元素中的第18個元素:

(1)把這29個元素分成6組:

(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)

(2)取出每一組的中位數,為31,49,13,25,16

(3)遞迴出的中值為25

(4)根據25將29個元素劃分為3個子陣列:

p =

q =

l =

(5)因為|p| = 13,|q| = 1,18>13 +1,所以第18個元素在l區域,找第18-13-1=4個元素,對l遞迴;

(6)將l劃分成3組:

(7)取出每一組的中位數,為51,43,41遞迴出的中值為43

(8)根據43將l組劃分為3個子陣列:

(9)因為第乙個子陣列中的元素的個數大於4,所以第18個元素在第乙個子陣列中,對第乙個子陣列遞迴;

(10)將第乙個子陣列分成了1組:

(11)取出中位數為33;

(12)根據33將第乙個子陣列分成3個子陣列:

(13)因為第乙個,第二個子陣列的元素的個數之和為4,所以33即為所求的第18個元素。

(一)**實現:

#include 

#define size (29)

//主函式

int main (void);

//遞迴分組

int select(int

array,int left,int right,int ith);

//尋找中位數

int findmiddata(int

array,int left,int right);

//排序取中位數下標

int insertsort(int

array,int a,int b);

//分組,以中位數為界,將比中位數小的放在左邊,比中位數大的放在右邊

int partition(int

array,int left,int right,int mid);

//交換

void swap (int

array,int a,int b);

int main(void) ;

int size = size ;

int ith = 18 ;

for(int i = 0;i < size;i++)

printf("\n");

printf("該陣列的第%d位的元素是:%d\n",ith,select(array,0,size - 1,ith));

}//遞迴分組

int select(int

array,int left,int right,int ith)

if(partitionmid < ith - 1)else

}//尋找中位數

int findmiddata(int

array,int left,int right)

swap(array,i,mid);

}mid = insertsort(array,0,(right - left) / 5);

return mid;

}//排序取中位數下標

int insertsort(int

array,int a,int b)}}

//取中位數的下標

if((b - a + 1) % 2 == 0)else

}//分組,以中位數為界,將比中位數小的放在左邊,比中位數大的放在右邊

int partition(int

array,int left,int right,int mid)

while (array[j] > value)

if (i < j)

swap(array,i,j) ;

else

break ;

}for(int k = 0; k < size;k++)

}return mid;

}//交換

void swap (int

array,int a,int b)

(二)執行結果:

****

(1)時間複雜度

上述演算法中,設n = r - p + 1,即n為輸入陣列的長度,演算法的遞迴呼叫只有在n>=75時執行。因此,當n<75時,演算法select所用的計算時間不超過乙個常數,找到中位數的中位數x後,演算法select以x為劃分基準呼叫函式partition對陣列進行劃分,這需要o(n)時間。演算法select的迴圈共執行n/5次,每一次要o(1)時間,因此,共需o(n)時間。

設對n個元素的陣列呼叫select需要t(n)時間,那麼找中位數的中位數x至少要t(n/5)時間。先以證明,按照演算法所選的基準x進行劃分所得的兩個子陣列分別至多有3n/4個元素,所以無論對哪個子陣列呼叫select都至多用t

(3n/4)時間。

所以演算法的時間複雜度為

由此可得t(n)=o( n ).

(2)空間複雜度

演算法在歸併過程中,共需要n個輔助儲存空間來臨時儲存合併的結果。所以空間複雜度s(n)= o(n)

TopK問題 線性時間選擇

相信計算機專業的同學應該都對快速排序有或多或少的了解。設定此模組是因為,線性時間選擇topk與快速排序的思想有相通之處,可以輔助我們理解。快速排序的思路 設定乙個瞭望元素 劃分元素 以此元素為基礎,將工作區間 l,r 內的所有元素分割成兩部分。劃分元素以左均比其小,劃分元素以右均比其大。對分割元素左...

線性時間選擇

今天學習了線性時間選擇,主要是通過快排的方法,在乙個平均時間線性的情況下進行第k小元素的選擇,結合一道題目進行描述 題目來自演算法設計與分析就是王曉東的那本 output.txt 這題目分析一下可以得出就是尋找中位數 為什麼呢?將這些數字排列在數軸上尋找乙個到各個點距離最小的那個點,可以得知最中間的...

線性時間選擇

出自 http algorithm.chaoskey.com 02 07 題目 給定線性序集中n個元素和乙個整數k,1 k n,要求找出這n個元素中第k小的元素,這裡給定的線性集是無序的 具體解題 這裡我們將所有的數 n個 以每5個劃分為一組,共 n 5 組 將不足五個的那組忽略 然後用任意一種排序...