洗牌算法总汇以及测试洗牌算法的正确性

转载自:http://www.cnblogs.com/TenosDoIt/p/3384141.html


洗牌算法汇总以及测试洗牌程序的正确性

洗牌可以抽象为:给定一组排列,输出该排列的一个随机组合,本文代码中均以字符数组代表该排列

算法1-算法3 都是在原序列的基础上进行交换,算法空间复杂度为O(1)

算法1(错误):随机交换序列中的两张牌,交换n次(n为序列的长度),代码如下:

void Shuffle_randomSwap(char *arr, const int len)
{
    for(int i = 1; i <= len; i++)
    {
        int a = rand()%len;
        int b = rand()%len;
        char temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

算法2(错误):遍历序列中的每个数,随机选择序列的某个数,把它和当前遍历到的数交换,代码如下:

void Shuffle_FisherYates_change1(char *arr, const int len)
{
    for(int i = len - 1; i >= 0; i--)
    {
        int a = rand()%len;
        int temp = arr[i];
        arr[i] = arr[a];
        arr[a] =  temp;
    }
}

算法3(正确):这是FisherYates洗牌算法,具体可参考wiki,算法的思想是每次从未选中的数字中随机挑选一个加入排列,时间复杂度为O(n),wiki上的伪代码如下

To shuffle an array a of n elements (indices 0..n-1):
  for i from n − 1 downto 1 do
       j ← random integer with 0 ≤ ji
       exchange a[j] and a[i]

代码实现:
void Shuffle_FisherYates(char *arr, const int len)
{
    for(int i = len - 1; i > 0; i--)
    {
        int a = rand()%(i + 1);
        int temp = arr[i];
        arr[i] = arr[a];
        arr[a] =  temp;
    }
}

FisherYates算法分析与介绍

https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

你可能感兴趣的:(Algorithm,C++)