算法讲解请参阅下面参考书籍,这里只给出自己练习时的代码实现。
参考书籍:《算法设计与分析基础·3ed》
1.伪代码
Lomuto划分算法:
LomutoPartition(A[l...r])
//采用Lomuto算法,用第一个元素作为轴对子数组进行划分
//输入:数组A[0...n-1]的一个子数组A[l...r],左索引l,右索引r,l<=r
//输出:A[l...r]的划分和中轴的新位置
p = A[l]
s = l
for i = l+1 to r do
if A[i] < p
s = s+1;swap(A[s], A[i])
swap(A[l], A[s])
return s
快速选择算法(quickselect):
Quickselect(A[l...r], k)
//用基于划分的递归算法解决选择问题,查找数组中第k最小元素
//输入:可排序数组A[0...n-1]的子数组A[l...r]和整数k(1 <= k <= r-l+1)
//输出:A[l...r]中第k小元素的值
s = LomutoPartition(A[l...r]) //或者其他划分算法
if s = l+k-1 return A[s]
else if s > l+k-1 Quickselect(A[l...s-1], k)
else Quickselect(A[s+1...r], l+k-1-s)
2.CPP实现:
#include <iostream>
using namespace std;
void swap(int &a, int &b);
int lomuto_partition(int arr[], int l, int r);
int quick_select(int arr[], int l, int r, int k);
int main()
{
int arr[] = {25, 45, 15, 40, 90, 5, 85, 75, 32, 65, 10, 5, 100, 15};
int length = sizeof(arr) / sizeof(int);
int v = quick_select(arr, 0, length-1, 6);
cout << v << endl;
return 0;
}
//swap a and b
void swap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}
//Lomuto Partition
int lomuto_partition(int arr[], int l, int r)
{
int p = arr[l];
int s = l;
for(int i = l+1; i <= r; i++){
if(arr[i] < p){
++s;
swap(arr[s], arr[i]);
}
}
swap(arr[l], arr[s]);
return s;
}
//Quick Select
int quick_select(int arr[], int l, int r, int k)
{
int s = lomuto_partition(arr, l, r);
if(s == l+k-1) return arr[s];
else if(s > l+k-1) quick_select(arr, l, s-1, k);
else quick_select(arr, s+1, r, l+k-1-s);
}
3.算法复杂度:
输入规模:n
基本操作:数值比较
复杂度: