拓展资料:C#Shuffle算法(洗牌算法、抽样算法) - 简书
代码:
using System.Collections.Generic;
using UnityEngine;
/*
*
* Writer:June
*
* Date: 2020.12.21
*
* Function:三种洗牌算法
*
* Remarks:
*
*/
public class ShuffleLogic : MonoBehaviour
{
#region 三种洗牌算法
/// <summary>
/// Fisher-Yates Shuffle 算法,会打乱原链表,时间复杂度O(n^2) 空间复杂度O(n)
/// </summary>
/// <typeparam name="T">链表类型</typeparam>
/// <param name="_list">目标链表</param>
public void FisherYatesShuffle<T>(List<T> _list)
{
List<T> tempList = new List<T>();
int rand;
T tempValue;
while (_list.Count > 0)
{
//随机索引 所能取得的最大长度是链表的长度-1
rand = Random.Range(0, _list.Count);
tempValue = _list[rand];
//放到新建的链表中
tempList.Add(tempValue);
//将取出后的值从链表中移除,下次遍历则不会再取出
_list.RemoveAt(rand);
}
//将打乱顺序后的链表重新赋给原链表
for (int i = 0; i < tempList.Count; i++)
{
_list.Add(tempList[i]);
}
}
/// <summary>
/// Knuth-Durstenfeld Shuffle算法,效率最高,会打乱原数组,时间复杂度O(n) 空间复杂度O(1)
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <param name="_array">目标数组</param>
public void KnuthDurstenfeldShuffle<T>(T[] _array)
{
int rand;
T tempValue;
for (int i = 0; i < _array.Length; i++)
{
rand = Random.Range(0, _array.Length - i);
tempValue = _array[rand];
_array[rand] = _array[_array.Length - 1 - i];
_array[_array.Length - 1 - i] = tempValue;
}
}
/// <summary>
/// Inside-Out Algorithm 算法,不会打乱原链表,返回打乱后的链表,时间复杂度O(n),空间复杂度O(n)
/// </summary>
/// <typeparam name="T">链表类型</typeparam>
/// <param name="_list">目标链表</param>
/// <returns>返回打乱顺序后的链表</returns>
public List<T> InsideOutAlgorithm<T>(List<T> _list)
{
List<T> tempList = new List<T>(_list);
int rand;
T tempValue;
for (int i = tempList.Count - 1; i >= 0; i--)
{
rand = Random.Range(0, i + 1);
tempValue = tempList[rand];
tempList[rand] = tempList[i];
tempList[i] = tempValue;
}
return tempList;
}
#endregion
}