快排以及BFPRT演算法的學習日記

2021-09-23 14:06:55 字數 2099 閱讀 4814

快排:

之前一直久仰快排大名,今日終於決定學習一下(主要是c++直接sort多爽(滑稽))

直接原因是接觸到乙個叫bfprt的演算法,快排作為應該是它的前導知識,於是今天就手打了乙個(假)快排,在打的過程中遇到了一些問題,於是寫下了這篇日記(滑稽)

關於快排我再贅述一下

就是乙個數列中選取乙個基準點,然後從左右向中間遍歷,將大於它的放右邊,小於它的放左邊。

具體做法:

1.確定 l,r指標,以及flag基準點

2.r指標先動,r--,直到遇到乙個數小於flag停下

3.l指標再動,l++,直到遇到乙個數大於flag停下

4.交換l,r指標

5.重複上述操作直到l==r

6.交換基準點和l,r相遇那個位置的指標

7.遞迴呼叫上述過程。

疑問1:      l,r移動過程中若是遇到乙個數的值等於基準點怎麼辦,用不用帶上它一起移到最後l,r相等的位置?

疑問2:     為什麼要r先動,l後動?

答:應該和基準數的選擇有關,在公升序排序下,選左邊那個,假如l先動,那麼我們考慮這種情況: 5 4 3 6 7 8 ,l會在6那裡停下來,然後r再動,在6那裡被l逼停下來,交換6 和 5 ,結果: 6 4 3 5 7 8 ,就出錯了。

因此應該選基準數相對的另外一邊作為開始。

放**:

#includeusing namespace std;

const int maxn = 1e5 + 7;

int num[maxn];

void q_sort(int *beg,int *end)

sto = *beg;

*beg = *l;

*l = sto;

q_sort(beg, l); //含前不含後啊鴿鴿

q_sort(l + 1, end);

}int main()

bfprt演算法:

好的施工完畢

我發現用這個演算法過不了我們學校oj上面一道用nth_element能過的題,感覺這個還是不夠快啊!!!

這個演算法可以解決無序陣列中第k大的問題,因為使用partition的思想做得話,因為其基準點預設第乙個數,因此存在一定情況會退化成o(n^2)的演算法。

這個演算法就解決了這個不穩定的問題,其通過自選基準點解決。

做法:1.分組,每5個為一組

2.組內排序,組外不需要管

3.將每個組的中位數拿出來組另外一組,名字為qq

5.得到qq的中位數,用那個作劃分

#include#include#includeusing namespace std;

const int maxn = 1e7 + 7;

int num[maxn], cnt[maxn];

inline int read()

int get_mid(int l,int r)

int part_sort(int l,int r)

sort(middle, middle + flag);

return middle[flag / 2]; //返回中位數陣列的中位數

}inline void swap(int a, int b)

void partation(int l,int r,int div)

else if (num[cur]==div)

else

} cnt[0] = ll + 1;

cnt[1] = rr - 1; //表示中間區域的座標

}int bfprt(int l,int r,int k)

int divide = part_sort(l, r);

partation(l, r, divide);

if (k >= cnt[0] && k <= cnt[1]) return num[k];

else if (k < cnt[0]) return bfprt(l, cnt[0] , k);

else return bfprt(cnt[1] + 1, r, k);

}int main()

第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...

快排演算法的實現

它的基本思想是 通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許...

c 演算法學習之快排

一趟排序步驟 確定乙個基數作為分界值,一般用陣列的第乙個元素 定義 j j 為陣列最後乙個元素 從 j 開始從右至左比較,若 j 所在的元素小於基數,則停止比較 定義 i i 為陣列第乙個元素 從 i 開始從左至右比較,若 i 所在的元素大於基數,則停止比較 交換i j 所在元素 當 i j時,交換...