洗牌算法与又一次排序

    这次我来说说洗牌算法以及又一次排序问题~(前几天回家了。并且也没遇到什么我认为值得写的。

。所以木有写新的文章- -)

    这个洗牌算法,事实上就是一种打乱顺序的算法。在网上有非常多种方法,今天我自己写了写。參考了下别人写的。总结了两种方法。下面全是在C#project下写的,所以不用打开Unity了- -。。。。
   
第一种:利用数组。这样的方法应该说是最基本最主要的了。

 //利用数组
            int[] int_array = new int [100];

            //放入数据
            for (int i = 0; i < int_array.Length; i++ )
            {
                int_array[i] = i + 1 ;
            }
            Random r = new Random ();

            //打乱顺序
            for (int i = int_array.Length - 1; i > 0; i-- )
            {
                int index = r.Next( 0, i);

                int temp = int_array[ i];
                int_array[i] = int_array [index];
                int_array[index ] = temp ;
            }
            //输出
            foreach (int a in int_array)
            {
                Console.WriteLine (a);
            }


另外一种:利用List

   //定义两个List
            List< int   > origin_list = new List <int   >();
            List< int > reshuffle_list = new List <int   >();

            //加入元素
            for (int i = 0; i < 100; i++ )
            {
                origin_list.Add((i + 1 ));
            }

            Random c = new Random ();
            int num = origin_list.Count ;

            //有序List中元素打乱后向新list转移
            for (int i = 0; i < num; i++ )
            {
                int random_index = c.Next( 0, origin_list.Count );
                reshuffle_list.Add(origin_list [random_index]);
                origin_list.RemoveAt(random_index );
            }

            //输出
            for (int i = 0; i < reshuffle_list.Count; i++ )
            {
                Console.WriteLine (reshuffle_list[ i]);
            }



以上是两种洗牌算法,以下我来说又一次排序。

    对于又一次排序。我相信大家的第一反应是冒泡了。。那些什么桶排序啊、高速排序啊、各种各样的排序算法啊我就不说了。我想说的又一次排序是基于我上述的另外一种方法的。

     以下我把我的另外一种方法加入一句话(在输出之前加入这句话):
reshuffle_list.Sort ();

这是list中存在的一个方法,目的就在于又一次排序。但是这样的排序方法有种限制,就是list中所存放的类型必须是int类型。
可是在Unity中。我们所涉及的list中的类型绝不可能仅仅有int类型,假如将来我们在做项目时,碰到须要排序的非int类型。那该怎么办呢?

    我们先来看看sort中的參数有哪些。




 先不解释sort中的參数,我如今把我之前另外一种方法改写一下,让list中存放的是string类型。

      //定义两个List
            List< string > origin_list = new List <string > ();
            List< string > reshuffle_list = new List <string > ();

            //加入元素
            for (int i = 0; i < 100; i++ )
            {
                origin_list.Add((i + 1 ).ToString ());
            }

            Random c = new Random ();
            int num = origin_list.Count ;

            //有序List中元素打乱后向新list转移
            for (int i = 0; i < num; i++ )
            {
                int random_index = c.Next( 0, origin_list.Count );
                reshuffle_list.Add(origin_list [random_index]);
                origin_list.RemoveAt(random_index );
            }

            //又一次排序
            reshuffle_list.Sort(( string x , string y ) =>
            {
                return int .Parse(x ) - int.Parse (y);
            });

            //输出
            for (int i = 0; i < reshuffle_list.Count; i++ )
            {
                Console.WriteLine (reshuffle_list[ i]);
            }

 
    这时候请注意我的排序方式,你能够试着执行一下,看看结果。
   以下我来解释一下,在list中的sort方法,其有用到了托付。

托付是什么?我的理解事实上就是给方法一个专门的“类型”,这个“类型”事实上跟string、int差点儿相同的。

关于托付。网上有太多的资料能够查阅。

而C#中,对于托付有一个很酷的方法就是lambda表达式。利用lambda表达式避免了定义一个新的方法,直接套用lambda表达式的固定格式,在中括号内写方法体就能够了,很高效。

    至于我上述的又一次排序中的方法体,为什么这样写?以下我来把sort的代码实现写在以下:
namespace LambdaWar
{
    public delegate int Comparer (int x , int y);
    public  class MyList
    {
        public   void Sort( Comparer compare)
        {
            for (int i = 0; i < data_list.Length - 1; i++ )
            {
                for (int j = 0; j < data_list .Length - i -1; j++ )
                {
                    if (compare(data_list [j], data_list [j + 1]) > 0)
                    {
                        int temp = data_list[ j];
                        data_list[j ] = data_list [j + 1];
                        data_list[j + 1 ] = temp ;
                    }
                }
            }
        }
    }
    class Program
    {
        static void Main( string [] args)
        {
        }
    }
}

      事实上sort就是利用冒泡排序所进行排序的,只是此时传递的是一个方法。
     细致看下sort的代码实现,再回到又一次排序中的方法体,不难发现,当x - y大于0时。它俩就会进行一次交换。从而实现从小到大的排序方式;假如方法体内换成 y -x ,那自然就是从大到小的排序方式了。
     或许有人会问这在unity中什么时候会用到,事实上假设说你在做一个棋牌类的游戏时(尤其是牌类),这个关于sort的ambda表达式就一定会用到!你想想,就好比打升级,你手里的牌是不是随机发到你手上的(洗牌算法),之后在你手里在排序一次(又一次排序)?
     
     如今我越发的认为基础的重要性。就比方这个lambda表达式,用好了能提高效率。

如今我也在每天补习下基础的东西。希望跟我一样的那些新手们一定要重视起基础啊。。

。。


原文地址:https://www.cnblogs.com/clnchanpin/p/6802401.html