線性時間選擇

2021-05-24 10:07:30 字數 1592 閱讀 8338

出自:http://algorithm.chaoskey.com/02/07

題目】:給定線性序集中n個元素和乙個整數k,1≤k≤n,要求找出這n個元素中第k小的元素,(這裡給定的線性集是無序的)

具體解題】:這裡我們將所有的數(n個),以每5個劃分為一組,共[n/5]組(將不足五個的那組忽略);然後用任意一種排序演算法 (因為只對五個數進行排序,所以任取一種排序法就可以了,這裡我選用氣泡排序),將每組中的元素排好序再分別取每組的中位數,得到[n/5]個中位數;再 取這[n/5]個中位數的中位數(如果n/5是偶數,就找它的2個中位數中較大的乙個)作為劃分基準,將全部的數劃分為兩個部分,小於基準的在左邊,大於 等於基準的放右邊。

在這種情況下,找出的基準x至少比3(n-5)/10個元素大,因為在每一組中有2個元素小於本組的中位數,中位數處於1/2*[n/5-1],即n/5 個中位數中又有(n-5)/10個小於基準x。同理,基準x也至少比3(n-5)/10個元素小。而當n≥75時,3(n-5)/10≥n/4所以按此基 準劃分所得的2個子陣列的長度都至少縮短1/4。

程式**如下:

#include

#include

#include

#define max_value 10000

#define random() rand()%max_value

#define n 10000

int a[n];

class find

} int partition(int p,int r,int x) //

陣列 a

中從 a[p]

到 a[r]

的元素按照 x

劃分 ,

大於 x

的在左邊 ,

小於 x

的在右邊

} }

return i-1;

} int select(int p,int r,int k)   //

尋找中位數

for(int i=0;i<(r-p-4)/5;i++)

int x=select(p,p+(r-p-4)/5,(r-p+6)/10);

i=partition(p,r,x);

int j=i-p+1;

if(k<=j)

return select(p,i,k);

else

return select(i+1,r,k-j);

} };

void main()

cout<

start=clock();

find f;    

int n=5000;

cout<<"the no."<

end=clock();

elapsed=((double)(end-start));///clocks_per_sec;

cout<<"time: "< }

這個題目關鍵在尋找劃分基準,從而提高尋找效率,時間複雜度為o(n);

線性時間選擇

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

線性時間選擇

這相當於是對於快速排序的基準選擇的乙個優化,使得選擇演算法達到線性時間。include include include includevoid swap int a,int b int compare const void a,const void b int partition int a,int...

線性時間選擇

參考演算法設計與分析。include using namespace std inline int random int x,int y int partition int a,int p,int r,int k return j 返回i跟返回j是一樣的。int select int a,int p...