2017/11/21
bfprt問題
乙個陣列中求第k小或者第k大的數
不通過排序求第k小的數,時間複雜度為o(n)。
1、找到乙個劃分值,按照partition的過程,分為小於區、等於區、大於區,則可知等於區是在整個陣列有序後不變的部分。
2、求第k小的數,就是陣列有序後下標為k-1的數。
3、所以,如果等於區包含這個k-1,則等於區的數就是第k小的數,直接返回。否則,繼續partition過程。
bfprt的思想是對劃分值的選擇進行優化,不再是隨機選取劃分值,而是通過這樣乙個過程:
1、將陣列分為5個一組,不足5個的自動成一組。劃分組所用時間為o(1)。
2、將每個組進行組內排序,可用插入排序。因為排序只有5個數,時間複雜度可記為o(1),所有組都排序為o(n)。
3、得到每個組內的上中位數,然後將這些上中位數組成新的陣列mediums。
4、求出mediums陣列中的上中位數pvalue,不使用排序,用的是遞迴呼叫bfprt的過程,求上中位數就是求mediums陣列第mediums.size()/2小的數。
5、此時得到的pvalue就是選取的劃分值,然後進行partition過程即可。
為什麼要這樣選取劃分值,這是因為,假設陣列長度為n,則mediums陣列的長度為n/5,則得到的pvalue在medium中會有n/10的數比其小,而這n/10的數,在自己的5個數的小組中,又會有3個數比pvalue小,所以,至少有n/10*3即3n/10個數比pvalue小,至多有7n/10個數比pvalue大,可以確定的淘汰掉3n/10的數。這樣劃分比較均衡。
6、剛才拿到pvalue劃分值之後,進行partition過程,會返回等於區的邊界下標。
7、如果k在等於的範圍內,則返回pvalue;k在等於區的左邊,則遞迴呼叫左邊小於區的部分;k在等於區的右邊,則遞迴呼叫大於區的部分。
#include
#include
using
namespace
std;
/*2017/11/18
bfprt演算法:
乙個陣列中求第k小或者第k大的數
*/#if 1
#define max(a,b)(a>b?a:b)
#define min(a,b)(aint mink(vector
&a, int k);
int findkmin(vector
&a, int start, int end, int k);
int getmediumofmedium(vector
a, int start, int end);
vector
partition(vector
&a, int start, int end, int value);
int getmedium(vector
a, int start, int end);
void insertsort(vector
&a, int start, int end);
void myswap(int &a, int &b);
void myswap(int &a, int &b)
void insertsort(vector
&a, int start, int end)
}}int getmedium(vector
a, int start, int end)
vector
partition(vector
&a, int start, int end, int value)
vector
p;p.push_back(less + 1);
p.push_back(more - 1);
return p;
}int getmediumofmedium(vector
a, int start, int end)
return findkmin(mediums, 0, mediums.size() - 1, (mediums.size() - 1) / 2);
}int findkmin(vector
&a, int start, int end, int k)
int mink(vector
&a, int k)
void main()
; cout
<< mink(a, 4) << endl;
system("pause");
}#else
#endif
BFPRT演算法O n 解決第k小的數
第k小演算法 我們通常會簡單地進行乙個快速排序後,得到第k個位置上的數字即可。我們都知道的是快速排序是個不穩定的排序,它的排序過程簡單的理解主要是兩個概念partion,pivot 基準數 一趟快速排序的過程如下 先從序列中選取乙個數作為基準數 將比這個數大的數全部放到它的右邊,把小於或者等於它的數...
分治演算法求第k小元素
1.問題 用分治的演算法求乙個陣列s n 中第k小的元素。2.解析 採取和快速演算法相同的思路,但是結合分治的思想,選取恰當的基準值。找到基準值以後,再按照快速排序的方法進行查詢就好了。3.設計 int r 5int r group ceil high low 1 1.0 r ceil取上限,總共分...
第k個小的數 bfprt演算法與快排改進
public static intfindk int nums,int m,int n int k while i temp if i nums m nums j nums j temp if j 1 k else if j 1 k else public static void main stri...