300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 洗牌算法(Fisher–Yates Shuffle and Knuth-Durstenfeld Shuffle)

洗牌算法(Fisher–Yates Shuffle and Knuth-Durstenfeld Shuffle)

时间:2022-02-14 13:01:39

相关推荐

洗牌算法(Fisher–Yates Shuffle and Knuth-Durstenfeld Shuffle)

一、Fisher–Yates Shuffle

1、算法思想:

从原始数组中随机抽取一个新的数字到新数组。

2、算法描述:

初始化原始数组和新数组,原始数组长度为n(已知);针对未处理的原始数组元素(假如还剩k个),随机产生一个[0, k)之间的数字p(假设数组从0开始);从原始数组剩下的k个数中把第p个数取出,放入新数组;重复步骤(2)和(3)直到数字全部取完;取出的数字序列(新数组)便是一个打乱了的数列。

3、时间复杂度:

O(n^2)

4、C++代码实现:

vector<int> Fisher_Yates(vector<int> &nums){srand((unsigned)time(NULL));vector<int> res;int p;for(int i=0;i<nums.size();++i){p=rand()%nums.size();//k为nums.size()res.push_back(nums.size);nums.erase(nums.begin()+p);}return res;}

二、Knuth-Durstenfeld Shuffle

1、算法思想:

Knuth和Durstenfeld在Fisher等人的基础上对算法进行了改进,在原始数组上对数字进行交互,省去了额外O(n)的空间。该算法的基本思想和 Fisher 类似,每次从未处理的数据中随机取出一个数字,然后把该数字放在原来数组的尾部,即该数组尾部存放的是已经处理过的数字。

2、算法描述:

初始化一个大小为n的原始数组,假设数组拥有i+1个未经处理的元素,此时i+1=n;在[0,i]范围内,生成随机数p;交换原始数组第i个元素与第p个元素(下标从0开始);i=i-1(原数组尾部位置已经随机处理完成,向前处理数组其他位置);重复(2)-(4)步,直至未经处理的元素全被处理。

3、时间复杂度:

O(n)

4、C++代码实现:

void Knuth_Durstenfeld(vector<int> &nums){srand(unsigned(time(NULL)));for(int i=nums.size()-1;i>=0;--i){int p=rand()%(i+1);//前i+1个元素未被处理过swap(nums[i],nums[p]);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。