Golang洗牌算法

两种洗牌算法:
1、Fisher-Yates
2、Knuth

type Handle struct {
}

Fisher–Yates 洗牌算法

// Fisher-Yates正向
func (h *Handle) shuffle_FisherYates_Forward(cards []uint32, r *rand.Rand) {
	var size int = len(cards)
	var j int = 0

	for i, _ := range cards {
		j = r.Intn(size-i) + i
		cards[i], cards[j] = cards[j], cards[i]
	}
}

// Fisher-Yates反向
func (h *Handle) shuffle_FisherYates_Reverse(cards []uint32, r *rand.Rand) {
	var size int = len(cards)
	var j int = 0

	for i := size - 1; i > 0; i-- {
		j = r.Intn(i + 1)
		cards[i], cards[j] = cards[j], cards[i]
	}
}

Knuth洗牌算法

// 第一步:为每张牌生成一个随机数
// 第二步:按这个随机数进行排序
type Knuth struct {
	index int
	ran   int
}

func (h *Handle) shuffle_Knuth(cards []uint32, r *rand.Rand){
	l := len(cards)
	tmp := make([]uint32, l)
	rands := make([]Knuth, l)

	for i := 0; i < l; i++{
		rands[i] = Knuth{index:i, ran:r.Intn(l)}
		tmp[i] = cards[i]
	}

	BubbleSort(rands)

	for i,v := range rands{
		cards[i] = tmp[v.index]
	}
}

// 冒泡排序
func BubbleSort(arr []Knuth) []Knuth {
	num := len(arr)
	for i := 0; i < num; i++ {
		status := false
		for j := i + 1; j < num; j++ {
			if arr[i].ran > arr[j].ran {
				status = true
				arr[i], arr[j] = arr[j], arr[i]
			}
		}
		if status == false {
			break
		}
	}
	return arr
}

入参解释

1、cards []uint32 // 即将要洗的牌
2、r *rand.Rand // 随机方式
生成方式:var r *rand.Rand = rand.New(rand.NewSource(“一个64位的随机种子”)
随机种子的选择建议:由于实际情况下,多机器运行速率很快,可能导致并发的时候,生成的纳秒种子可能多次相同。所以建议种子由snowflake算法生成唯一性。

个人眼界有限,如果有什么好的洗牌算法,希望大家留言~~

你可能感兴趣的:(GO)