随机算法的定义:
它是在接收输入的同时,为了随机选择的目的,还接收一串随机比特流并且在运行过程中使用该比特流的算法
分类:
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进行。
代码实现:(HDU1040)
#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]);
}
}