洗牌演算法是乙個比較常見的面試題。
一副撲克54張牌,有54!種排列方式。最佳的洗牌演算法,應該能夠等概率地生成這54!種結果中的一種
github鏈結
原理這是完全合乎現實洗牌邏輯的演算法。
就是抽出紙牌的最後一張隨機插入到牌庫中,這般抽54次就完成了對撲克牌的洗牌
複雜度空間o(1),時間o(n^2)
優缺點如果牌庫是以乙個陣列描述,這種插入式的洗牌不可避免地要大量移動元素。
原理取兩個列表,乙個是洗牌前的序列a
10 pukes.resetpuke(newlist.toarray());//
序列b為洗牌後的結果
優缺點演算法原理清晰,但額外開闢了乙個list,而且為list刪除元素是不可避免地需要移動元素
通過54次生成的隨機數取1/54,1/53,…1/1能等概率地生成這54!種結果中的一種
knuth 和durstenfeld 在fisher 等人的基礎上對演算法進行了改進。每次從未處理的資料中隨機取出乙個數字,然後把該數字放在陣列的尾部,即陣列尾部存放的是已經處理過的數字 。這是乙個原地打亂順序的演算法,演算法時間複雜度也從fisher演算法的 o ( n 2 )提公升到了 o ( n )。
1是最佳的洗牌演算法for(int i = pukes.pukes.length - 1;i>0;--i)
2
c++ stl中random_shuffle使用的就是這種演算法
原理在[0, i]之間隨機乙個下標j,然後用位置j的元素替換掉位置i的數字
通過54次生成的隨機數取1/1,1/2,…1/54能等概率地生成這54!種結果中的一種
複雜度空間o(1),時間o(n)
**實現
1關於c++ stl 的random_shufflepublic
static
void
shuffle(pukes pukes)
29 }
它的演算法原理和knuth_durstenfeld類似
先從所有元素中選乙個與位置1的元素交換,然後再從剩下的n-1個元素中選擇乙個放到位置2,以此類推
維基百科-fisher–yates shuffle
每日演算法 洗牌演算法
給定乙個n個數的序列,設計乙個演算法將其隨機打亂,保證每個數出現在任意乙個位置的概率相同 也就是說在n 個的排列中,每乙個排列出現的概率相同 假設輸入為陣列num length 隨機選乙個數,放到num 0 中,再隨機選數,如果該數已經選過,重新選,直到該數未選過時放入num 1 中,以此類推,直到...
遊戲中常見的洗牌演算法
今天把遊戲中用到的洗牌演算法好好看了看,把自己感覺最易懂的和最經典的一種分享出來,當然,我這個是看過別人之後自己寫的。我們以撲克牌當做例子,一共有54張,如何一次就把排序全部打亂呢?1 最笨的洗牌演算法 先把54張牌按照順序排好,每次取乙個0 54的隨機數,根據隨機數取出該牌,放入新的牌序中,這樣經...
洗牌演算法小結
1.for i 1 to n do swap a i a random 1,n 湊合,但不是真正隨機 2.for i 1 to n do swap a i a random i,n 真正的隨機演算法 其中,random a,b 函式用於返回乙個從a到b 包括a和b 的隨機整數。第乙個 概率事件總的發...