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
方法进行排序。 - 自定义类排序有两种方式:
- 继承接口
IComparable
。 - 在
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