求序列第K大演算法總結

2021-10-04 21:09:27 字數 3052 閱讀 8216

參考部落格:傳送門

在上面的部落格中介紹了求序列第k大的幾種演算法,感覺收益良多,其中最精巧的還是利用快速排序的思想o(n)查詢的演算法。仔細學習以後我將其中的幾個實現了一下。

解法 1:

將亂序陣列從大到小進行排序然後取出前k大,總的時間複雜度為o(nlogn)

解法 2:

利用選擇排序或互動排序,取出前k大,總的時間複雜度為o(nk)

解法 3:

借鑑快速排序的思想,複雜度近似為o(n)

#include

#include

#include

using

namespace std;

intkth_number

(int

*a,int l,

int r,

int k)

}swap

(a[index]

,a[l]);

if(r-index == k)

return a[index];if

(r-index-

1>= k)

return

kth_number

(a,index+

1,r,k)

;else

return

kth_number

(a,l,index,k-r+index)

;}

測試程式

#include

#include

"kth_number.h"

using

namespace std;

intmain()

執行結果

解法 4:

借助堆排序的思想,將前k個數字彈出,複雜度為建立堆的o(4n)加上k次堆排序o(logn)o(4n+klogn)

實現程式

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

void

adjust

(int

*a,int n,

int i)

else

} a[i]

= x;

}void

makeheap

(int

*a,int n)

}void

heapsort

(int

*a,int n,

int k,

int*ans)

*ans = a[m+1]

;}intmain

(int argc,

char

* ar**)

;for

(int i =

1; i <= n;

++i)

int k;

scanf

("%d"

,&k);if

(k > n) k = n;

makeheap

(a, n)

;int ans;

heapsort

(a, n, k,

&ans)

;printf

("ans=%d\n"

, ans)

;return0;

}

測試結果

解法 5:

維護乙個大小為k的小頂堆,對於陣列中的每乙個元素判斷與堆頂的大小,若堆頂較大,則不管,否則彈出堆頂,將當前值插入到堆中。時間複雜度o(4k+nlogk)

實現程式

#include

#include

using

namespace std;

void

adjust

(int

*a,int n,

int i)

else

break;}

a[i]

=x;}

void

makeheap

(int

*a,int n)

}int

kthnumber

(int

*a,int n,

int k)

makeheap

(b,k)

;for

(int i=k+

1;i<=n;

++i)

}return b[1]

;}intmain()

;for

(int i=

1;i<=n;

++i)

scanf

("%d"

,&a[i]);

printf

("%d\n"

,kthnumber

(a,n,k));

// delete a;

return0;

}

測試結果

解法 6:

利用hash儲存陣列中元素出現的次數,利用計數排序的思想,線性從大到小掃瞄中得到結果,時間複雜度為o(n)

單峰陣列求第k大演算法

單峰陣列實際上可以看成兩個有序的陣列,這個問題就轉變成了兩個有序陣列求第k大。容易想到的演算法是對這兩個陣列進行歸併,生成乙個新的有序陣列,求出第k大之後就可以立刻停止,複雜度是o k 的。但是還有更優的演算法,可以使用分治的思想 實際上也是一種二分 來計算。對於兩個有序的陣列a和b,取出他們第k ...

求區間第k大

int a mx void insert int a,int l,int r int divide int a,int l,int r 劃分子問題 a l x return l int select int s,int l,int r,int k,int len 返回s陣列l r的第k大數的下標 w...

演算法題 BFPRT演算法 求第K小或者第K大的數

2017 11 21 bfprt問題 乙個陣列中求第k小或者第k大的數 不通過排序求第k小的數,時間複雜度為o n 1 找到乙個劃分值,按照partition的過程,分為小於區 等於區 大於區,則可知等於區是在整個陣列有序後不變的部分。2 求第k小的數,就是陣列有序後下標為k 1的數。3 所以,如果...