洗牌算法

作者: xhbisme | 来源:发表于2018-06-08 16:36 被阅读0次

一次偶然的机会,需要我生成一个长度为len的数组。数组的内容是[0-len)。这并不难,分分钟生成这样一个数组:

源数组

但是,当然不仅仅这么简单。需求还让我们去做一件事情,就是随机排序。我们知道怎么把一个乱序数组排好序,返回去呢?然后我就去搜了一下javaScript数组随机排列。然后就偶遇了洗牌算法。借鉴前辈的一些思想的,自己实现了一套更简单的洗牌算法。我们先看下前辈的思想。

经典实现:

思路从原始数组中随机抽取一个新的元素到新数组中

时间复杂度:O(n^2)(其实看到这个,我就不想看这个实现了,时间复杂度有点厉害)

具体实现

1.从还没处理的数组(假如还剩n个)中,产生一个[0, n]之间的随机数 random

2.从剩下的n个元素中把第 random 个元素取出到新数组中

3.删除原数组第random个元素

4.重复第 2 3 步直到所有元素取完

5.最终返回一个新的打乱的数组

具体代码

经典实现

Knuth实现:

思路:每次从未处理的数组中随机取一个元素,然后把该元素放到数组的尾部,即数组的尾部放的就是已经处理过的元素。(

时间复杂度:O(n)

具体实现

1.选取数组(长度n)中最后一个元素(arr[length-1]),将其与n个元素中的任意一个交换,此时最后一个元素已经确定

2.选取倒数第二个元素(arr[length-2]),将其与n-1个元素中的任意一个交换

3.重复第 1 2 步,直到剩下1个元素为止

Sort实现:

利用Array的sort方法可以更简洁的实现打乱,对于数量小的数组来说足够。因为随着数组元素增加,随机性会变差。

sort 时间

我的实现

Knuth的实现方法已经很好了,但美中不足的是,我的每一个元素始终不能在原来的位置,也就是说,这一通操做下来,每个位置的数字都变了,要知道,洗牌的过程中要有洗不到的地方,也就是位置不动的元素,于是基于Knuth的思路,写了一个实现。

上边是生成了数组,下边是一次随机拿两个来交换。执行len/2次,运气好的情况下可以洗一遍,但这微乎其微。如果觉得洗的不满意,可以自己改操作次数。我觉得,有的保持原位才是真正的洗牌。

实现 效率不输sort

相关文章

  • Golang洗牌算法,抢红包算法

    本文为转载,原文:Golang洗牌算法,抢红包算法 1. 洗牌算法 洗牌算法,即将原来的顺序打乱,组成新的随机排序...

  • 洗牌算法

    一次偶然的机会,需要我生成一个长度为len的数组。数组的内容是[0-len)。这并不难,分分钟生成这样一个数组: ...

  • 洗牌算法

    在工作中需要重写一个洗牌算法,根据网络中的资料分析了一下,已经有总结得很好的了,就直接总结转载了一下。 洗牌算法大...

  • 洗牌算法

    洗牌算法是一个比较形象的术语,本质上让一个数组内的元素随机排列。

  • 洗牌算法

    问题 实现一个最简单的洗牌算法。 分析 很多人第一次都可能会很迷惑,其实只要理解好了这个题目,实现起来相信并不难。...

  • 洗牌算法

    概述### 洗牌算法(可以归类到随即算法中),顾名思义,就是只利用一次循环等概率的取到不同的元素(牌)。 描述##...

  • 洗牌算法

    打乱一个序列 暴力方法 每次生成一个随机数,然后将对应下标的原序列数添加到新数组中。同时应该有一个memo用来记录...

  • 洗牌算法

    第一次接触洗牌算法是在一次面试上,面试官要求我写出一个算法将一个1~100的有序数组打乱,不考虑性能,那次我想了许...

  • 洗牌算法

    随机打乱一个数组的顺序。场景:验证码之类。要求生成n位不重复的数字组合(0

  • 洗牌算法

    Source Code Usage

网友评论

    本文标题:洗牌算法

    本文链接:https://www.haomeiwen.com/subject/avyasftx.html