《算法导论》——期望为线性时间的选择算法
#include "iostream"
#include "algorithm"
using namespace std;
// 一般的快速排序,在最坏的情况下时间复杂度为n2, 这在输入数据有序的情况下会出现,我们应该尽量去避免它。
//采取的策略是,在选择分割点的时候,不再选择第一个点或者最后一个点,而是随机选择一个点,然后将它与最后点互换。
//当然,这并不能完全的避免最坏情况的出现,只能减少发生的概率。
int PARTION(int *array, int low, int high)
{
int k = low + rand() % (high - low + 1);
swap(array[k], array[high]);
int q = array[high];
int j = low - 1;
for (int m = low; m < high ; m++)
{
if (array[m] < array[high])
{
j++;
swap(array[m], array[j]);
}
}
swap(array[j + 1], array[high]);
return j + 1;
}
int RANDOMIZED_SELECT(int a[], int l, int h, int i)
{
if (l == h)
{
return a[l];
}
int q = PARTION(a, l, h);
int k = q - l + 1;
if (k == i)
{
return a[q];
}
else
{
if (k > i)
{
RANDOMIZED_SELECT(a, l, q - 1, i);
}
else
RANDOMIZED_SELECT(a, q + 1, h, i-k);
}
}
void main()
{
int index;
int a[] = { 10, 6, 4, 0, 11, 9, 5 };
int len = sizeof(a) / sizeof(a[0]);
cout << "原始数据为:" << endl;
for (int i = 0; i < len; i++)
{
cout << a[i] << " ";
}
cout << endl;
while (1)
{
cout << "请输入需要查询的第I小的数" << endl;
cin >> index;
while (index > len)
{
cout << "超出界限,重新输入" << endl;
cin >> index;
}
cout << "第" << index << "小的数为:" << RANDOMIZED_SELECT(a, 0, len - 1, index) << endl;
cout << endl;
}
system("pause");
}
期望运行时间为O(N),最坏运行时间为O(n2)