其實就是算法書上的一個問題實現,複雜度O(n)。
給定線性序集中n個元素和一個整數k,1<=k<=n,要求找出這n個元素中第k小的元素,即如果將這n個元素依次線性排序時,排在第k個位置的元素即爲要找的元素。當k-1時,就是要找的最小元素;當k=n時,就是要找的最大元素;當k=(n+1)/2,稱爲中位數。
#include <iostream>
#define LENGTH 16
using namespace std;
void exswap(int& i, int& j)
{
int n;
n = i;
i = j;
j = n;
}
int Partition(int a[], int p, int r, int x)
{
//將小於x的元素放到左邊
//反之放到右邊
int i = p - 1;
for (int j = p; j <= r - 1; j++) {
if (a[j] <= x) {
i++;
exswap(a[i], a[j]);
}
}
exswap(a[i + 1], a[r]);
return i + 1;
}
void QuickSort(int a[], int p, int r)
{
if (p < r) {
int q = Partition(a, p, r, a[r]);
QuickSort(a, p, q - 1);
QuickSort(a, q + 1, r);
}
}
int Select(int a[], int p, int r, int k)
{
if (r - p < 15) //小於閾值時直接使用快排
{
QuickSort(a, p, r);
return a[p + k - 1];
}
for (int i = 0; i <= (r - p - 4) / 5; i++) {
QuickSort(a, p + 5 * i, p + 5 * i + 4); //範圍內數字進行O(1)快排
exswap(a[p + i], a[p + 5 * i + 2]); //這裏是第k小元素與a[p+i]交換位置
}
//查找中位數的中位數
int x = Select(a, p, p + (r - p - 4) / 5, (r - p - 4) / 10);
int i = Partition(a, p, r, x), j = i - p + 1;
if (k <= j)
return Select(a, p, i, k);
else
return Select(a, i + 1, r, k - j);
}
int main()
{
int test[LENGTH] = { 1, 0, 11, 2, 14, 1523, 233, 123, 11, 5, 4, 12, 7, 6, 9, 8 };
int k, x;
cout << "Number of k?" << endl;
cin >> k;
x = Select(test, 0, LENGTH - 1, k);
cout << "Is " << x << endl;
return 0;
}