查找集合 S 中第 k 個最小元的算法幾乎與快速排序算法相同。事實上前三步是相同的,咱們把這種算法叫作快速選擇(quickselect)。另 | Si | 爲 Si 中元素的個數:ios
1) 若是 | S | = 1,則 k = 1, 並將S 中的元素做爲答案返回。若是使用小數組的截止方法 | S | <= Cutoff, 則將 S 排序並返回第 k 個最小元。算法
2) 選取一個樞紐元 v (v 屬於 S)。數組
3) 將集合 S 中的剩餘元素 分割成 S1 和 S2,就像在快速排序中所作的那樣。ui
4) 若是 k <= | S1 |, 那麼第 k 個最小元必定在 S1 中。在這種狀況下,返回 quickselect(S1, k)。 若是 k = S1 + 1,那麼樞紐元就是第 k 個最小元,將其返回便可。不然,第 k 個最小元在 S2 中, 它是 第(k - | S1 | - 1)個最小元,進行一次遞歸調用並返回 quickselect(S2 , k - | S1 | - 1)。spa
與快速排序相比,快速選擇只作了一次遞歸調用,而不是兩次。快速選擇的最壞情形和快速排序的相同,也是 O(N^2)。直觀來看,只由於快速排序的最壞情形是發生在當 S1 或 S2 爲空的時候【三數中值選取樞紐元能夠使最壞情形發生的機會幾乎是微不足道的】;因而,快速選擇就不是真正的節省一次遞歸調用。不過,平均運行時間爲 O(N)。排序
快速選擇算法中止時,第 k 個最小元就在第 k 個位置上,這破壞了原來的順序;若是不但願這樣,那麼須要作一份拷貝。遞歸
代碼實現:io
//利用快速排序解決選擇問題:找出含有 N 個元素的表 S 中的第 k 個最小的元素
#include<iostream>
#define Cutoff 3
using namespace std;stream
typedef int ElemType;select
void Swap_1(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void InsertionSort(ElemType A[], int N)
{
int i, j, tmp;
for(i = 1; i < N; i++)
{
tmp = A[i];
for(j = i; j > 0 && A[j - 1] > tmp; j--)
{
A[j] = A[j - 1];
}
A[j] = tmp;
}
}
int Media_3(ElemType A[], int Left, int Right)
{
int Center;
Center = (Left + Right) / 2;
if(A[Left] > A[Center])
Swap_1(&A[Left], &A[Center]);
if(A[Left] > A[Right])
Swap_1(&A[Left], &A[Right]);
if(A[Center] > A[Right])
Swap_1(&A[Center], &A[Right]);
Swap_1(&A[Center], &A[Right - 1]);
return A[Right - 1];
}
void QuickSelect(ElemType A[], int k, int Left, int Right)
{
ElemType Pivot;
int i, j;
if(Left + Cutoff <= Right)
{
Pivot = Media_3(A, Left, Right);
i = Left;
j = Right -1;
for(;;)
{
while(A[++i] < Pivot){}
while(A[--j] > Pivot){}
if(i < j)
Swap_1(&A[i], &A[j]);
else
break;
}
Swap_1(&A[i], &A[Right - 1]);
if(k <= i)
QuickSelect(A, k, Left, i - 1);
else if(k > i + 1)
QuickSelect(A, k, i + 1, Right);
}
else
InsertionSort(A + Left, Right - Left + 1); //元素少於3個,可用直接插入排序
}
int main()
{
int data[] = {3, 0, 4, 5, 8, 9, 7, 2, 6, 1};
QuickSelect(data, 7, 0, 9);
cout << data[7] << endl;
for(int i = 0; i < 10; i++)
cout << data[i] << " ";
cout << endl;
system("pause"); return 0;}