随机算法

随机算法的定义:

它是在接收输入的同时,为了随机选择的目的,还接收一串随机比特流并且在运行过程中使用该比特流的算法


分类:

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]);
	}
}


你可能感兴趣的:(算法,Random)