出自: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這個題目關鍵在尋找劃分基準,從而提高尋找效率,時間複雜度為o(n);#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: "< }
線性時間選擇
今天學習了線性時間選擇,主要是通過快排的方法,在乙個平均時間線性的情況下進行第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...