使用快排一次劃分求第k小 使用優先順序佇列 使用堆

2021-10-22 18:35:07 字數 4531 閱讀 2810

快排

#include

using

namespace std;

/**************************************

* * partition() 快排的一次劃分函式

* */

// 把小的插入頭部位置,可用於鍊錶

intpartition

(int

* ar,

int left,

int right)

j +=1

;}std::

swap

(ar[left]

, ar[i]);

return i;

}// 雙指標單方向推進

intpartition1

(int

* ar,

int left,

int right)

std::

swap

(ar[j -1]

, ar[left]);

return j -1;

}// 雙指標,兩邊夾逼推進

intpartition2

(int

* ar,

int left,

int right)

std::

swap

(ar[i]

, ar[left]);

return i;

}// 快排中間層,遞迴呼叫一次劃分

void

quickpass

(int

* ar,

int left,

int right)

}// 快排介面

void

quicksort

(int

* ar,

int n)

intmain()

;quicksort

(arr,

sizeof

(arr)

/sizeof

(arr[0]

));for

(int a : arr)

std::cout << a <<

' ';

std::cout << std::endl;

return0;

}

有關快排優化:參考:萬字長文帶你走進快速排序的前世今生【拓跋阿秀】

非遞迴優化基準選取位置,如三位取中法等

設定乙個閾值,在閾值範圍內使用插入排序(插入排序在元素比較少時效率最高)

三向切分。

使用快排的的一次劃分,我們可以實現尋找無序數列中的第k小。

#include

using

namespace std;

intonepartition

(int

* ar,

int left,

int right)

}while

(left < right)}}

return left;

}int

select_k

(int

* ar,

int left,

int right,

int pos)

intmain()

;int n =

sizeof

(arr)

/sizeof

(arr[0]

);//cout << cpair_ar(arr, n);

for(

int i =

1; i <

11; i++

) cout << i <<

": "

<<

select_k

(arr,

0, n -

1, i)

<< endl;

return0;

}/*輸出:

1: 12

2: 23

3: 34

4: 45

5: 56

6: 67

7: 78

8: 89

9: 90

10: 100

*/

除此之外,我們可以使用優先順序佇列,或直接使用資料結構堆。

優先順序佇列,大數優先順序高(底層大根堆實現)。使用小數優先順序高的方式也可以實現下列演算法。

#include

#include

#include

using

namespace std;

// 第k大

intkthlargest

(int arr,

int n,

int k)

// 把第1大,第2大,第3....,到第k次時為第k大

while

(k >1)

return pq.

top();

}// 第k小

intkthsmall

(int arr,

int n,

int k)

k = n - k +1;

// 求第k小,把n-k+1的大資料出隊,剩下的就是第k小

while

(k >1)

return pq.

top();

}int

main()

;int n =

sizeof

(arr)

/sizeof

(arr[0]

);for(

int i =

1; i <= n; i++

) cout << i <<

":\t small "

<<

kthsmall

(arr, n, i)

<<

"\t big"

<<

kthlargest

(arr, n, i)

<< endl;

return0;

}/*輸出:

1: small 12 big100

2: small 23 big90

3: small 34 big89

4: small 45 big78

5: small 56 big67

6: small 67 big56

7: small 78 big45

8: small 89 big34

9: small 90 big23

10: small 100 big12

*/

直接使用資料結構堆。

#include

#include

#include

using

namespace std;

// 第k大

intkthlargest

(int arr,

int n,

int k)

return arr[0]

;}// 第k小

intkthsmall

(int arr,

int n,

int k)

return arr[0]

;}intmain()

;int brr=

;int n =

sizeof

(arr)

/sizeof

(arr[0]

);for(

int i =

1; i <= n; i++

) cout << i <<

":\t small "

<<

kthsmall

(arr, n, i)

<<

"\t big"

<<

kthlargest

(arr, n, i)

<< endl;

return0;

}/*輸出:

1: small 12 big100

2: small 23 big90

3: small 34 big89

4: small 45 big78

5: small 56 big67

6: small 67 big56

7: small 78 big45

8: small 89 big34

9: small 90 big23

10: small 100 big12

*/

快速排序 快排求第K大

快速排序 快排採用分治的策略,先從數列中取出乙個元素作為作為基準元素,以基準元素為標準,將問題分解為兩個子串行,使小於基準的子串行在左側,使大於等於基準元素的子串行右側,對兩個子串行再進行快速排序,最終得到排好序的序列。時間複雜度 o nlogn 空間複雜度o logn 快速排序是不穩定的 code...

快排的思想求第K小的數

描述輸入n 個數,m 次查詢。每次查詢給出乙個數x。要求 每次查詢輸出前 x個數中第 i小的數。i為第 i次查詢 你可以假設 m n xi xi 1 xi 2 xm xm n 輸入 line0 t line1 n,m line2 linen 1 num1,numn linen 2 linen 2 m...

基於快排求無序陣列的第K大元素

package other pratice 怎麼最快的求無序陣列的第k大元素。author sxy 我們知道快排的排序是從大到小,還是從小到大取決於分割槽那個函式是如何寫的,本題是在陣列中尋找第幾大元素 所以需要在陣列的大小的順序要是從大到小 快速排序每次排序完找的 基準點即是第幾大元素。如果 如果...