代码改变世界

洗牌算法

2017-09-05 16:40  huoit  阅读(201)  评论(0)    收藏  举报

洗牌:尽可能的与原来的牌不同;当一张牌被随机后,下一次就没有必要再考虑它;

1、剔除法:每次随机一个数,查找该位置的数给结果集然后剔除掉;循环随机

2、交换法:每次随机一个数,把该数作为地址用;然后做位置交换;循环交换

 

    public class Poker
    {
        public int[] num = new int[52];
        //初始化
        public Poker()
        {
            for (int i = 0; i < 52; i++)
            {
                num[i] = i + 1;

            }
        }



        #region 剔除法
        /// <summary>
        /// 去除初始化,复杂度O(N),但使用了更多的内存
        /// </summary>
        /// <param name="n"></param>
        public void Shuffle1(int n)
        {
            //初始化
            List<int> list = new List<int>(num);
            
            //存放结果,占内存
            int[] retnum = new int[52];
            Random random = new Random();
            for (int i = n - 1; i >= 0; i--)
            {
                //随机取一个位置和队尾交换;删除掉再随机
                int numindex = random.Next(0, i);
                retnum[n - 1 - i] = list[numindex];
                list.RemoveAt(numindex);//RemoveAt的原理是使用Array.Copy会使用更多的内存
            }
            num = retnum;
        }
        #endregion

        #region 交换算法
        /// <summary>
        /// 最优
        /// </summary>
        /// <param name="n"></param>
        public void Shuffle2(int n)
        {
            Random random = new Random();
            for (int i = n - 1; i >= 1; i--)
            {
                //每次随机一个放入队尾;本质是一次随机排序
                Swap(ref num[i], ref num[random.Next(0, i + 1)]);

            }
        }

        #endregion



        private void Swap(ref int x, ref int y)
        {
            int temp = x;
            x = y;
            y = temp;
        }




        public void Show()
        {
            for (int i = 0; i < num.Length; i++)
            {
                if (i > 0 && i % 10 == 0) { Console.WriteLine("\n"); }
                Console.Write(num[i] + "");



            }
            Console.WriteLine("\n");
        }
    }