四種洗牌演算法

2021-09-13 12:45:25 字數 2180 閱讀 1126

官方點的話如下:

fisher–yates shuffle 演算法思想就是從原始陣列中隨機抽取乙個新的數字到新陣列中。

演算法描述如下:

1. 從還沒處理的陣列(假如還剩k個)中,隨機產生乙個[0, k]之間的數字p(假設陣列從0開 始);

2. 從剩下的k個數中把第p個數取出;

3. 重複步驟2和3直到數字全部取完;

4. 從步驟3取出的數字序列便是乙個打亂了的數列。

比較好的**寫法如下:

#簡單寫法

import random

def shuffle(lis):

#新列表

result=

while lis:

p=random.randrange(0,len(lis)) #設定隨機下標範圍,左閉右開

return result

lis=[1,2,2,3,3,4,5,10]

result=shuffle(lis)

print("洗完牌後的順序為:",result)

一般的**寫法如下:

import random

def shuffle(lis):

#新列表

result=

while lis:

p=random.randrange(0,len(lis)) #設定隨機下標範圍,左閉右開

value=lis[p]

del lis[p] #lis.remove(lis[p]) ,remove在結果上沒問題,但是在邏輯上有問題,因為如果有兩個相同的2,想移除的是第乙個2但是有可能會移除第二個2,不合邏輯。但是不影響結果。

return result

lis=[1,2,2,3,3,4,5,10]

result=shuffle(lis)

print("洗完牌後的順序為:",result)

缺點:建立新列表,浪費儲存空間

knuth 和durstenfeld 在fisher 等人的基礎上對演算法進行了改進。每次從未處理的資料中隨 機取出乙個數字,然後把該數字放在陣列的尾部,即陣列尾部存放的是已經處理過的數字。這是一 個原地打亂順序的演算法,演算法時間複雜度也從fisher演算法的o(n2)提公升到了o(n)。

**如下:

#原地打亂

import random

def shuffle(lis):

for i in range(len(lis),0,-1):

p=random.randrange(0,i) #從0到i隨機取值,0到i的範圍逐漸縮小

return lis

lis=[1,2,2,3,3,4,5,10]

result=shuffle(lis)

print("洗完牌後的順序為",result)

缺點:在原始資料上打亂的,想看原始資料的話就看不到了。

其內部實現正是使用knuth­durstenfeld shuffle演算法。

import random

lis=[1,2,2,3,3,4,5,10]

random.shuffle(lis)

print(lis)

**如下:

import random

def shuffle(lis):

result=lis[:]

for i in range(1,len(lis)):

j=random.randrange(0,i)

result[i],result[j]=result[j],result[i]

return result

r=shuffle([1,2,2,3,3,4,5,10])

print(r)

Sort List(四種演算法)

sort a linked list in o nlog n time using constant space complexity.演算法一 快速排序。因為鍊錶是單向,所以有很多細節要注意,比如quick sort p,r 排序的區間其實是 p next,r next 因為單向鍊錶不能回頭。de...

四種Block Match演算法

塊匹配block match演算法常用於雙目立體匹配和幀間距離匹配上,特點是實現步驟簡單,這裡介紹四種基本的block match演算法 1.sum of absolute differencse sad 公式如下 c 實現 mat funcsadr2l mat leftimage,mat righ...

排序演算法(四種)

氣泡排序是非常容易理解和實現,以從小到大排序舉例 設陣列長度為n。氣泡排序從前往後遍歷和從後往前遍歷一樣的原理。目標陣列 3,5,2,6,4,9,7,12,11 從前往後 第一波 從第乙個數開始,如果第乙個數大於第二個數,就把這兩個數調換位置,否則保留之前的排列,第二次把第二個和第三個數比較,比較方...