1. 程式人生 > >《演算法導論》——期望為線性時間的選擇演算法

《演算法導論》——期望為線性時間的選擇演算法

《演算法導論》——期望為線性時間的選擇演算法

在這裡插入圖片描述
在這裡插入圖片描述

#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)