17.List排序

17.List排序


17.1 知识点

List自带排序方法

主函数内

// 创建一个整型列表,随便加点元素
List<int> list = new List<int>();
list.Add(3);
list.Add(2);
list.Add(6);
list.Add(1);
list.Add(4);
list.Add(5);

// 输出查看
for (int i = 0; i < list.Count; i++)
{
    Console.WriteLine(list[i]);
    // 3
    // 2
    // 6
    // 1
    // 4
    // 5
}

// list提供了排序方法Sort
list.Sort(); // 默认是升序排序

Console.WriteLine("*****list.Sort排序后*****");
for (int i = 0; i < list.Count; i++)
{
    Console.WriteLine(list[i]);
    // 1
    // 2
    // 3
    // 4
    // 5
    // 6
}

自定义类的排序

class语句块外 namespace语句块内

// 物品类
// 想要调用排序方法正常排序,要让Item继承了IComparable或IComparable<Item>接口
class Item : IComparable<Item>
{
    // 物品价钱
    public int money;

    // 构造函数初始化传入物品价钱
    public Item(int money)
    {
        this.money = money;
    }

    // IComparable<>接口要实现的方法,自己定义比较规则
    public int CompareTo(Item other)
    {
        // 返回值的含义:
        // 小于0:放在传入对象的前面
        // 等于0: 保持当前的位置不变
        // 大于0:放在传入对象的后面
        // 自己定义比较规则是比较不同item的价钱
        if (this.money > other.money)
        {
            return -1;
        }
        else
        {
            return 1;
        }
    }
}

主函数内

// 创建一个物品列表,随便加几个元素
List<Item> itemList = new List<Item>();
itemList.Add(new Item(45));
itemList.Add(new Item(10));
itemList.Add(new Item(99));
itemList.Add(new Item(24));
itemList.Add(new Item(100));
itemList.Add(new Item(12));

// 想要调用排序方法正常排序,要让Item继承了IComparable或IComparable<Item>接口
itemList.Sort();

Console.WriteLine("*****itemList.Sort排序后*****");
for (int i = 0; i < itemList.Count; i++)
{
    Console.WriteLine(itemList[i].money);
    // 100
    // 99
    // 45
    // 24
    // 12
    // 10
}

通过委托函数进行排序

class语句块外 namespace语句块内

// 商店物品类
class ShopItem
{
    // 物品id
    public int id;

    // 商店物品类构造函数,初始化id
    public ShopItem(int id)
    {
        this.id = id;
    }
}

class语句块内 主函数外

// 自己写一个函数传到Sort方法里,返回值和参数保持对应格式即可
// 排序商店物品方法
static int SortShopItem(ShopItem a, ShopItem b)
{
    // 传入的两个对象为列表中的两个对象
    // 进行两两的比较,用左边的和右边的条件比较
    // 返回值规则和之前一样:0做标准,负数在左(前),正数在右(后)
    if (a.id > b.id)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

主函数内

// 创建一个商店物品列表,随便加几个元素
List<ShopItem> shopItemList = new List<ShopItem>();
shopItemList.Add(new ShopItem(2));
shopItemList.Add(new ShopItem(1));
shopItemList.Add(new ShopItem(4));
shopItemList.Add(new ShopItem(3));
shopItemList.Add(new ShopItem(6));
shopItemList.Add(new ShopItem(5));

// Sort方法里其实有重载的,其中有一个重载是传委托进去的
// 所以可以自己写一个函数或者委托传到Sort方法里,返回值和参数保持对应格式即可

// 传入自己写的排序商店物品方法
shopItemList.Sort(SortShopItem);

// 传入匿名函数
shopItemList.Sort(delegate (ShopItem a, ShopItem b)
{
    if (a.id > b.id)
    {
        return -1;
    }
    else
    {
        return 1;
    }
});

// 传入lambda表达式
// 可以省略参数类型,因为传入的委托是泛型,是当前列表中的元素类型ShopItem
// 配合三目运算符完美呈现
shopItemList.Sort((a, b) => { return a.id > b.id ? 1 : -1; });

Console.WriteLine("*****shopItemList.Sort排序后*****");
for (int i= 0; i < shopItemList.Count; i++)
{
    Console.WriteLine(shopItemList[i].id);
    // 1
    // 2
    // 3
    // 4
    // 5
    // 6
}

总结

  • 系统自带的变量(int, float, double等)一般都可以直接使用Sort方法进行排序。
  • 自定义类排序有两种方式:
    1. 继承接口IComparable
    2. Sort方法中传入委托函数。

17.2 知识点代码

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace Lesson16_List排序
{
    //class语句块外 namespace语句块内

    #region 知识点二 自定义类的排序

    //物品类
    //想要调用排序方法正常排序 要让Item继承了IComparable或IComparable<Item>接口
    class Item : IComparable<Item>
    {
        //假如继承的是IComparable
        //无非就是把参数改成object类型 然后排序是as成item再处理

        //物品价钱
        public int money;

        //构造函数初始化传入物品价钱
        public Item(int money)
        {
            this.money = money;
        }

        //IComparable<>接口要实现的方法
        //自己定义比较规则
        public int CompareTo(Item other)
        {
            //返回值的含义
            //小于0:放在传入对象的前面
            //等于0:保持当前的位置不变
            //大于0:放在传入对象的后面

            //可以简单理解 传入对象的位置 就是0
            //如果你的返回为负数 就放在它的左边 也就前面
            //如果你返回正数 就放在它的右边 也就是后面

            //自己定义比较规则是比较不同item的价钱
            if (this.money > other.money)
            {
                return -1;
            }
            else
            {
                return 1;
            }
        }
    }

    #endregion

    #region 知识点三 通过委托函数进行排序

    //商店物品类
    class ShopItem
    {
        //物品id
        public int id;

        //商店物品类构造函数 初始化id
        public ShopItem(int id)
        {
            this.id = id;
        }
    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("List排序");

            //主函数内

            #region 知识点一 List自带排序方法

            //创建一个整形列表 随便加点元素
            List<int> list = new List<int>();
            list.Add(3);
            list.Add(2);
            list.Add(6);
            list.Add(1);
            list.Add(4);
            list.Add(5);
            //输出查看
            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i]);
                //3
                //2
                //6
                //1
                //4
                //5
            }

            //list提供了排序方法Sort
            list.Sort();//默认是升序排序
            //ArrayList中也有Sort排序方法
            //int能自动排序是因为int继承了IComparable和IComparable<Int32>接口

            Console.WriteLine("*****list.Sort排序后*****");
            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i]);
                //1
                //2
                //3
                //4
                //5
                //6
            }


            #endregion

            #region 知识点二 自定义类的排序

            //创建一个物品列表 随便加几个元素
            List<Item> itemList = new List<Item>();
            itemList.Add(new Item(45));
            itemList.Add(new Item(10));
            itemList.Add(new Item(99));
            itemList.Add(new Item(24));
            itemList.Add(new Item(100));
            itemList.Add(new Item(12));

            //想要调用排序方法正常排序 要让Item继承了IComparable或IComparable<Item>接口
            itemList.Sort();

            Console.WriteLine("*****itemList.Sort排序后*****");
            for (int i = 0; i < itemList.Count; i++)
            {
                Console.WriteLine(itemList[i].money);
                //100
                //99
                //45
                //24
                //12
                //10
            }

            #endregion

            #region 知识点三 通过委托函数进行排序

            //创建一个商店物品列表 随便加几个元素
            List<ShopItem> shopItemList = new List<ShopItem>();
            shopItemList.Add(new ShopItem(2));
            shopItemList.Add(new ShopItem(1));
            shopItemList.Add(new ShopItem(4));
            shopItemList.Add(new ShopItem(3));
            shopItemList.Add(new ShopItem(6));
            shopItemList.Add(new ShopItem(5));

            //Sort方法里其实有重载的 其中有一个重载是传委托进去的

            //public delegate int Comparison<in T>(T x, T y);
            //
            // 摘要:
            //     Represents the method that compares two objects of the same type.
            //
            // 参数:
            //   x:
            //     The first object to compare.
            //
            //   y:
            //     The second object to compare.
            //
            // 类型参数:
            //   T:
            //     The type of the objects to compare.
            //
            // 返回结果:
            //     A signed integer that indicates the relative values of x and y, as shown in the
            //     following table. Value Meaning Less than 0 x is less than y. 0 x equals y. Greater
            //     than 0 x is greater than y.

            //所以可以自己写一个函数或者委托传到Sort方法里 返回值和参数保持对应格式即可

            //传入自己写的排序商店物品方法
            shopItemList.Sort(SortShopItem);

            //传入匿名函数
            shopItemList.Sort(delegate (ShopItem a, ShopItem b)
            {
                if (a.id > b.id)
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            });

            //传入lambda表达式
            //可以省略参数类型 因为传入的委托是泛型 是当前列表中的元素类型ShopItem
            //配合 三目运算符 完美呈现
            shopItemList.Sort((a, b) => { return a.id > b.id ? 1 : -1; });

            Console.WriteLine("*****shopItemList.Sort排序后*****");
            for (int i = 0; i < shopItemList.Count; i++)
            {
                Console.WriteLine(shopItemList[i].id);
                //1
                //2
                //3
                //4
                //5
                //6
            }
            #endregion
        }

        //class语句块内 主函数外

        #region 知识点三 通过委托函数进行排序

        //public delegate int Comparison<in T>(T x, T y);
        //自己写一个函数传到Sort方法里 返回值和参数保持对应格式即可
        //排序商店物品方法
        static int SortShopItem(ShopItem a, ShopItem b)
        {
            //传入的两个对象 为列表中的两个对象
            //进行两两的比较  用左边的和右边的条件 比较 
            //返回值规则 和之前一样 0做标准 负数在左(前) 正数在右(后)
            if (a.id > b.id)
            {
                return -1;
            }
            else
            {
                return 1;
            }
        }

        #endregion
    }

    //总结
    //系统自带的变量(int,float,double.....) 一般都可以直接Sort
    //自定义类Sort有两种方式
    //1.继承接口 IComparable
    //2.在Sort中传入委托函数

}

17.3 练习题

写一个怪物类,创建10个怪物将其添加到List中,对List列表进行排序,根据用户输入数字进行排序:1攻击排序2防御排序3血量排序4反转

class语句块外 namespace语句块内

// 怪物类
class Monster
{
    // 静态变量 排序类型
    // 1、攻击排序
    // 2、防御排序
    // 3、血量排序
    public static int SortType = 1;

    // 攻击
    public int atk;
    // 防御
    public int def;
    // 血量
    public int hp;

    // 怪物构造函数初始化攻击防御血量
    public Monster(int hp, int atk, int def)
    {
        this.hp = hp;
        this.atk = atk;
        this.def = def;
    }

    // 重写怪物的ToString方法
    public override string ToString()
    {
        return string.Format("怪物信息-血量{0} 攻击力{1} 防御力{2}", this.hp, this.atk, this.def);
    }
}

class语句块内 主函数外

// 怪物排序函数
static int SortMonsterFun(Monster m1, Monster m2)
{
    switch (Monster.SortType)
    {
        case 1:
            return m1.atk > m2.atk ? 1 : -1;
        case 2:
            return m1.def > m2.def ? 1 : -1;
        case 3:
            return m1.hp > m2.hp ? 1 : -1;
    }
    return 0;
}

主函数内

// 创建怪物列表 随机丢10个怪物进去
List<Monster> monsters = new List<Monster>();
Random r1 = new Random();

Console.WriteLine("*****怪物排序前*****");

for (int i = 0; i < 10; i++)
{
    monsters.Add(new Monster(r1.Next(100, 201), r1.Next(5, 21), r1.Next(2, 10)));
    Console.WriteLine(monsters[i]);
}

try
{
    Console.WriteLine("请输入1~4的数字进行排序");
    Console.WriteLine("1:按攻击力升序排列");
    Console.WriteLine("2:按防御力升序排列");
    Console.WriteLine("3:按血量序排列");
    Console.WriteLine("4:翻转");

    Monster.SortType = int.Parse(Console.ReadLine());

    if (Monster.SortType == 4)
    {
        monsters.Reverse();
    }
    else
    {
        monsters.Sort(SortMonsterFun);
    }

    Console.WriteLine("*****怪物排序后*****");

    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine(monsters[i]);
    }
}
catch
{
    Console.WriteLine("请输入数字");
}

写一个物品类,创建10个物品,添加到List中,同时使用类型、品质、名字长度进行比较,排序的权重是:类型>品质>名字长度

class语句块外 namespace语句块内

// 物品类
class Item
{
    // 类型
    public int type;
    // 名字长度
    public string name;
    // 品质
    public int quality;

    public Item(int type, string name, int quality)
    {
        this.type = type;
        this.name = name;
        this.quality = quality;
    }

    public override string ToString()
    {
        return string.Format("道具信息-类型{0} 名字{1} 品质{2}", type, name, quality);
    }
}

主函数内

// 创建物品列表 随机丢10个物品进去
List<Item> itemList = new List<Item>();
Random r2 = new Random();

Console.WriteLine("*****Item排序前*****");

for (int i = 0; i < 10; i++)
{
    itemList.Add(new Item(r2.Next(1, 6), "Item" + r2.Next(1, 200), r2.Next(1, 6)));
    Console.WriteLine(itemList[i]);
}

itemList.Sort((a, b) =>
{
    // 类型不同 按类型比
    if (a.type != b.type)
    {
        return a.type > b.type ? -1 : 1;
    }
    // 否则按品质比
    else if (a.quality != b.quality)
    {
        return a.quality > b.quality ? -1 : 1;
    }
    // 否则就直接按名字长度比
    else
    {
        return a.name.Length > b.name.Length ? -1 : 1;
    }
});

Console.WriteLine("*****Item排序后*****");
for (int i = 0; i < 10; i++)
{
    Console.WriteLine(itemList[i]);
}

请尝试利用List排序方式对Dictionary中的内容排序

主函数内

// 创建字典 丢10个元素进去
Dictionary<int, string> dic = new Dictionary<int, string>();
dic.Add(2, "123123");
dic.Add(6, "123123");
dic.Add(1, "123123");
dic.Add(4, "123123");
dic.Add(3, "123123");
dic.Add(5, "123123");

// 创建KeyValuePair<int, string>这个结构体类型的list 方便遍历字典时加入到list中
List<KeyValuePair<int, string>> list = new List<KeyValuePair<int, string>>();

// 遍历字典的时候 逐个添加到list中
foreach (KeyValuePair<int, string> item in dic)
{
    list.Add(item);
    Console.WriteLine(item.Key + "_" + item.Value);
}

// 对键进行排序
list.Sort((a, b) =>
{
    return a.Key > b.Key ? 1 : -1;
});

Console.WriteLine("*****List<KeyValuePair<int, string>> list排序后*****");

for (int i = 0; i < list.Count; i++)
{
    Console.WriteLine(list[i].Key + "_" + list[i].Value);
}

17.4 练习题代码

using System;
using System.Collections.Generic;

namespace Lesson16_练习题
{
    //class语句块外 namespace语句块内

    #region 练习题一
    //写一个怪物类,创建10个怪物将其添加到List中
    //对List列表进行排序,根据用户输入数字进行排序
    //1、攻击排序
    //2、防御排序
    //3、血量排序
    //4、反转

    //怪物类
    class Monster
    {
        //静态变量 排队类型
        //1、攻击排序
        //2、防御排序
        //3、血量排序
        public static int SortType = 1;

        //攻击
        public int atk;
        //防御
        public int def;
        //血量
        public int hp;

        //怪物构造函数初始化攻击防御血量
        public Monster(int hp, int atk, int def)
        {
            this.hp = hp;
            this.atk = atk;
            this.def = def;
        }

        //重写怪物的ToString方法
        public override string ToString()
        {
            return string.Format("怪物信息-血量{0}攻击力{1}防御力{2}", this.hp, this.atk, this.def);
        }
    }
    #endregion

    #region 练习题二
    //写一个物品类(类型,名字,品质),创建10个物品
    //添加到List中
    //同时使用类型、品质、名字长度进行比较
    //排序的权重是:类型>品质>名字长度

    //物品类
    class Item
    {
        //类型
        public int type;
        //名字长度
        public string name;
        //品质
        public int quality;

        public Item(int type, string name, int quality)
        {
            this.type = type;
            this.name = name;
            this.quality = quality;
        }

        public override string ToString()
        {
            return string.Format("道具信息-类型{0} 名字{1} 品质{2}", type, name, quality);
        }
    }
    #endregion

    #region 练习题三
    //linq  SQL

    //请尝试利用List排序方式对Dictionary中的内容排序
    //提示:得到Dictionary的所有键值对信息存入List中
    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("List排序练习题");

            //主函数内

            #region 练习题一

            //创建怪物列表 随机丢10个怪物进去
            List<Monster> monsters = new List<Monster>();
            Random r1 = new Random();

            Console.WriteLine("*****怪物排序前*****");

            for (int i = 0; i < 10; i++)
            {
                monsters.Add(new Monster(r1.Next(100, 201), r1.Next(5, 21), r1.Next(2, 10)));
                Console.WriteLine(monsters[i]);
            }

            try
            {
                Console.WriteLine("请输入1~4的数字进行排序");
                Console.WriteLine("1:按攻击力升序排列");
                Console.WriteLine("2:按防御力升序排列");
                Console.WriteLine("3:按血量序排列");
                Console.WriteLine("4:翻转");

                //常规做法
                //inputIndex = int.Parse(Console.ReadLine());

                Monster.SortType = int.Parse(Console.ReadLine());

                //常规做法
                //switch(inputIndex)
                //{
                //    case 1:
                //        monsters.Sort((a, b)=>
                //        {
                //            return a.atk > b.atk ? 1 : -1;
                //        });
                //        break;
                //    case 2:
                //        monsters.Sort((a, b) =>
                //        {
                //            return a.def > b.def ? 1 : -1;
                //        });
                //        break;
                //    case 3:
                //        monsters.Sort((a, b) =>
                //        {
                //            return a.hp > b.hp ? 1 : -1;
                //        });
                //        break;
                //    case 4:
                //        //Reverse方法 翻转API
                //        monsters.Reverse();
                //        break;
                //}

                if (Monster.SortType == 4)
                {
                    monsters.Reverse();
                }
                else
                {
                    monsters.Sort(SortMonsterFun);
                }

                Console.WriteLine("*****怪物排序后*****");

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(monsters[i]);
                }
            }
            catch
            {
                Console.WriteLine("请输入数字");
            }

            #endregion

            #region 练习题二

            //创建物品列表 随机丢10个物品进去
            List<Item> itemList = new List<Item>();
            Random r2 = new Random();

            Console.WriteLine("*****Item排序前*****");

            for (int i = 0; i < 10; i++)
            {
                itemList.Add(new Item(r2.Next(1, 6), "Item" + r2.Next(1, 200), r2.Next(1, 6)));
                Console.WriteLine(itemList[i]);
            }

            itemList.Sort((a, b) =>
            {
                //类型不同 按类型比
                if (a.type != b.type)
                {
                    return a.type > b.type ? -1 : 1;
                }
                //否则按品质比
                else if (a.quality != b.quality)
                {
                    return a.quality > b.quality ? -1 : 1;
                }
                //否则就直接按名字长度比
                else
                {
                    return a.name.Length > b.name.Length ? -1 : 1;
                }
            });

            Console.WriteLine("*****Item排序后*****");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(itemList[i]);
            }

            #endregion

            #region 练习题三

            //创建字典 丢10个元素进去
            Dictionary<int, string> dic = new Dictionary<int, string>();
            dic.Add(2, "123123");
            dic.Add(6, "123123");
            dic.Add(1, "123123");
            dic.Add(4, "123123");
            dic.Add(3, "123123");
            dic.Add(5, "123123");

            //创建KeyValuePair<int, string>这个结构体类型的list 方便遍历字典时加入到list中
            List<KeyValuePair<int, string>> list = new List<KeyValuePair<int, string>>();

            //遍历字典的时候 逐个添加到list中
            foreach (KeyValuePair<int, string> item in dic)
            {
                list.Add(item);
                Console.WriteLine(item.Key + "_" + item.Value);
            }

            //对键进行排序
            list.Sort((a, b) =>
            {
                return a.Key > b.Key ? 1 : -1;
            });

            Console.WriteLine("*****List<KeyValuePair<int, string>> list排序后*****");

            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i].Key + "_" + list[i].Value);
            }

            #endregion
        }

        //class语句块内 主函数外

        #region 练习题一

        //怪物排序函数
        static int SortMonsterFun(Monster m1, Monster m2)
        {
            switch (Monster.SortType)
            {
                case 1:
                    return m1.atk > m2.atk ? 1 : -1;
                case 2:
                    return m1.def > m2.def ? 1 : -1;
                case 3:
                    return m1.hp > m2.hp ? 1 : -1;
            }
            return 0;
        }

        #endregion
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏