它是在接收输入的同时,为了随机选择的目的,还接收一串随机比特流并且在运行过程中使用该比特流的算法
Las Vegas算法:它建立的那些随机算法总是或者给出正确的解,或者误解。
Monte Carlo算法:它建立的算法总是给出解,但偶尔可能会产生非正确的解。
由推论得知,QUICKSORT的平均运行时间是O(nlogn),但在许多应用中时不同的。
如果输入的是已排序的元素,那么运行时间是O(n^2),对于几乎排好序的输入的情况也适用。
例如,考虑一种应用,给一个大的已排序文件增添少量元素,然后用算法QUICKSORT来重新排序。在这种情况下,添加的元素越少,运行时间越接近O(n^2)
解决这种问题并保证平均运行时间为O(nlogn)的方法是引入预处理步骤,它唯一的目的是改变元素的顺序使之随机排序。这种预处理步骤可在O(n)时间运行。
能够起到同样作用的另一种简单方法是在算法中引入一个随机元素,这可以通过随机地选择拆分元素的主元来完成。
随机选择主元的结果放宽了关于输入元素的所有排列的可能性。
新算法只是在区间[low...high]中一致随机地选择一个索引mark,并将data[mark]与data[low]交换,然后就按照原来的算法QUICKSORT进行。
#include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; int arr[1005]; // 与快速排序相同 int split(int data[], int l, int r) { int i = l; int x = data[l]; for (int j = i+1; j < r; ++ j) { if (data[j] < x) { ++ i; if (i != j) swap(data[i],data[j]); } } swap(data[l],data[i]); return i; }; // 生成l~r之间的随机位置 int random(int l, int r) { return l+rand()%(r-l); }; void rquicksort(int data[], int l, int r) { if (l < r) { int mark = random(l,r); swap(data[l],data[mark]); int w = split(data, l, r); rquicksort(data, l, w); rquicksort(data, w+1, r); } }; int main() { int T, n; scanf("%d",&T); while (T -- ) { scanf("%d",&n); for (int i = 0; i < n; ++ i) scanf("%d",&arr[i]); rquicksort(arr, 0, n); for (int i = 0; i < n-1; ++ i) printf("%d ",arr[i]); printf("%d\n",arr[n-1]); } }