快排
#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 我們知道快排的排序是從大到小,還是從小到大取決於分割槽那個函式是如何寫的,本題是在陣列中尋找第幾大元素 所以需要在陣列的大小的順序要是從大到小 快速排序每次排序完找的 基準點即是第幾大元素。如果 如果...