算法描述
-
Fisher-Yates 洗牌算法(Fisher-Yates Shuffle)是一种用于随机打乱数组或列表元素顺序的算法,以获取随机排列。这个算法是由 Ronald A. Fisher 和 Frank Yates 于 1938 年开发的,用于生成无偏的、随机的排列顺序。
-
Fisher-Yates 洗牌算法的基本思想是从数组中的最后一个元素开始,逐步将当前位置的元素与数组中之前的位置中的一个随机元素进行交换,直到第一个元素。这个过程确保了每个元素都有相等的机会出现在任何一个位置上,从而获得了真正的随机性。
具体步骤如下:
从数组末尾开始,选择一个随机位置(可以是前面任何一个位置,包括当前位置)。
将当前位置的元素与随机位置的元素进行交换。
重复步骤 1 和 2,逐步向前,直到到达数组的第一个元素。
通过多次重复这个过程,数组的元素就会被随机打乱,从而实现了洗牌效果。
Fisher-Yates 洗牌算法是一种简单且高效的洗牌方法,适用于需要随机排列的各种情况,如随机抽样、模拟和算法中的随机化等。
#ifndef ALGO_SHUFFLE_H__
#define ALGO_SHUFFLE_H__
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
namespace alg {
/**
* shuffle the 'list' of length 'len'
*/
template<typename T>
static void shuffle(T * list, int len) {
srand(time(NULL));
int i = len, j;
T temp;
if ( i == 0 ) return;
while ( --i ) {
j = rand() % (i+1);
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
#endif //
demo
#include <stdio.h>
#include <stdlib.h>
#include "generic.h"
#include "shuffle.h"
using namespace alg;
int main()
{
const int MAX_ELEMENTS = 10;
int list[MAX_ELEMENTS];
int i = 0;
// generate random numbers and fill them to the list
for(i = 0; i < MAX_ELEMENTS; i++ ){
list[i] = i;
}
printf("The list before Shuffle is:\n");
printlist(list,MAX_ELEMENTS);
// shuffle the list
shuffle<int>(list,MAX_ELEMENTS);
// print the result
printf("The list after using Yates' shuffle algorithm:\n");
printlist(list,MAX_ELEMENTS);
return 0;
}