找第k大數,最壞時間複雜度O n

2022-07-30 21:51:12 字數 1555 閱讀 8243

第一種方法:用快排的分治方法,是先任意找陣列中的乙個元素a(a用陣列的第乙個元素比較方便),然後進行一次劃分,就是將陣列中所有大於a的數都移到a的一邊,所有小於等於a的數都移到a的另一邊。然後選擇在哪邊繼續進行劃分,最後找到第k大的值。

第二種方法:用冒泡的方法,是每個元素挨著比,第一趟找出最大的數,第二趟找出第2大的數,一直到找到第k大的數結束。

其實第一種方法的平均複雜度能到o(n),但是它的複雜度依賴於劃分元素,最壞的時間複雜度是o(n^2)。

如果在第一種方法之上,加上乙個篩選劃分元素的過程,就能把最壞時間複雜度降到o(n)。篩選的過程就是把所有的數等分成很多小段,然後求所有小段的中間值。構成乙個由所有中間值組成的段,然後再取中間值,作為劃分元素。即中間值的中間值作為劃分元素。取中間值可以先任選一種排序方法排序之後選擇,因為每一小段的長度很短,不是影響複雜度的主要因素;取中間值的中間值,利用遞迴的方法呼叫自身即可。

這樣就可以把最壞時間複雜度降到o(n)了,複雜度證明比較繁瑣。

#includeusing

namespace

std;

int r = 5; //

定義全域性變數r, r個元素一段

void insort( int a, int m, int p ) //

插入排序

a[j+1] =t;

}}void swap( int &a, int &b ) //

兩數交換

int partition( int a, int m, int p ) //

一次劃分函式

a[m] =a[j];

a[j] =x;

returnj;}

int select( int a, int m, int p, int k ) //

返回乙個i值,使得a[i]是a[m..p]中第k小元素

while( 1

) j = select( a, m, m + int(n/r) -1, int(int(n/r)/2) + 1

); swap( a[m], a[j] );

//產生劃分元素

找第k大數,最壞時間複雜度O n

以前寫過的一篇,搬過來。上演算法課的時候聽到老師講這個問題,覺得還是蠻有意思的。已知陣列a,找出a m a p 中的第k大值。很容易想到快排和冒泡。第一種方法 用快排的分治方法,是先任意找陣列中的乙個元素a a用陣列的第乙個元素比較方便 然後進行一次劃分,就是將陣列中所有大於a的數都移到a的一邊,所...

最好,最壞和平均時間複雜度

在查詢成功的情況下,若待查詢的資料元素恰好是陣列的第乙個元素,則只需比較一次即可找到,這就是最好情況,t n o 1 稱最好時間複雜度。若是最後乙個元素,則要比較n次才能找到。t n o n 稱最壞時間複雜度。在查詢不成功的情況下,無論何時進行不成功的查詢都需要進行n次比較,t n o n 成功查詢...

時間複雜度分析 最好 最壞 均攤

array 陣列.n array長度.x 需要查詢的值 int searchposition int array,int n,int x return pos 根據上面的演算法來說的話,如果我x的位置在array 0 那麼時間複雜度就是o 1 如果x的位置在array n 1 或者不在array中....