高效随机排序C#列表
在C#中,对泛型列表进行随机排序是软件开发中常见的任务。例如,在彩票应用程序中,您可能需要对有限的数字集合进行随机排序。
最佳实践:
在C#中,随机排序列表最有效的方法是使用基于Fisher-Yates洗牌算法的扩展方法。下面提供的此方法确保高效且真正随机地洗牌列表元素:
private static Random rng = new Random(); public static void Shuffle<T>(this IList<T> list) { int n = list.Count; while (n > 1) { n--; int k = rng.Next(n + 1); T value = list[k]; list[k] = list[n]; list[n] = value; } }
使用方法:
使用此扩展方法很简单。考虑以下示例:
List<Product> products = GetProducts(); products.Shuffle();
随机数生成器的选择:
虽然上面的代码使用System.Random
方法,但必须承认其在随机性方面的潜在局限性。如果您的应用程序需要更高质量的随机性,您可以利用System.Security.Cryptography
中提供的随机数生成器,如下所示:
using System.Security.Cryptography; ... public static void Shuffle<T>(this IList<T> list) { using (RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider()) { int n = list.Count; while (n > 1) { byte[] box = new byte[1]; do provider.GetBytes(box); while (!(box[0] < (byte)((double)byte.MaxValue * (double)n / (double)uint.MaxValue))); int k = (int)(box[0] / ((double)byte.MaxValue / n)); T value = list[k]; list[k] = list[n - 1]; list[n - 1] = value; } } }
线程安全:
为了确保线程安全的随机化,必须考虑以下修改后的扩展方法:
public static void Shuffle<T>(this IList<T> list) { int n = list.Count; while (n > 1) { n--; int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1); T value = list[k]; list[k] = list[n]; list[n] = value; } }
其中ThreadSafeRandom
定义为:
public static class ThreadSafeRandom { [ThreadStatic] private static Random Local; public static Random ThisThreadsRandom { get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); } } }
通过这些方法,您可以根据您的需求选择最合适的随机排序方法。 请注意using
语句在使用RNGCryptoServiceProvider
时的重要性,以确保正确释放资源。
以上是如何在C#中有效地列出列表?的详细内容。更多信息请关注PHP中文网其他相关文章!