列表排序

本文介绍了C#中List<T>的Sort()方法,详细讲解了如何利用快速排序算法对列表元素进行排序。讨论了Sort()方法的不同重载形式,包括使用IComparable<T>接口、IComparer<T>接口以及Comparison<T>委托。通过自定义类Racer和RacerComparer,展示了如何根据特定属性(如姓名、国籍、获胜次数)进行排序。同时,还阐述了使用lambda表达式和Comparison<T>委托实现自定义排序逻辑的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

List<T>类可以使用Sort()方法对元素排序。Sort()方法使用快速排序算法,比较所有的元素,直到整个列表排好序为止。

Sort()方法使用了几个重载的方法。可以传递给它的参数由泛型委托Comparison<T>和泛型接口IComparer<T>以及一个范围值和泛型接口IComparer<T>。

public void List<T>.Sort();
public void List<T>.Sort(Comparison<T>);
public void List<T>.Sort(IComparer<T>);
public void List<T>.Sort(Int32,Int32,IComparer<T>);

只有集合中的元素实现了IComparable接口,才能使用不带参数的Sort()方法。

自定义类Racer实现了IComparable<T>接口,可以按姓氏对赛车手排序:

racers.Sort();

如果需要按照元素类型不默认支持的方式排序,就应使用其他技术,例如,传递一个实现了IComparer<T>接口的对象。

RacerComparer类为Racer类型实现了接口IComparer<T>。这个类允许按名字、姓氏、国籍或获胜次数排序。排序的种类用内部枚举类型CompareType定义。CompareType枚举类型用RacerComparer类的构造函数设置。ICompaer<Racer>接口定义了排序所需的Compare()方法。在这个方法的实现代码中,使用了string和int类型的CompareTo()方法:

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

namespace 列表排序
{
    class Program
    {
        static void Main(string[] args)
        {
            var racer = new Racer(3,"Jenny","Henry","Japan",34);
            var racer2 = new Racer(2,"Code","Winders","China",12);
            var racer3 = new Racer(1,"Visual","Studio","Ameraca",9);
            List<Racer> racers = new List<Racer> {
                racer,
                racer2,
                racer3

            };
            System.Console.WriteLine("Sort by FirstName");
            //现在,可以对RacerCompare类的一个实例使用Sort()方法。传递枚举RacerCompare.CompareType.Country,
            //按属性FirstName对集合排序。
            racers.Sort(new RacerComparer(RacerComparer.ComapareType.FirstName));
            foreach(var value in racers){
                System.Console.WriteLine(value);

            }
            System.Console.WriteLine();
            System.Console.WriteLine("Sort by Wins");
            racers.Sort(new RacerComparer(RacerComparer.ComapareType.Wins));
            foreach(var value in racers){
                System.Console.WriteLine(value);
            }
        }

        
    }

    public class Racer{
        public int Id{get;}
        public string FirstName{get;}
        public string LastName{get;}
        public string Country{get;}
        public int Wins{get;}
        public Racer(int id,string firstName,string lastName,string country,int wins){
            Id = id;
            FirstName = firstName;
            LastName = lastName;
            Country = country;
            Wins = wins;        
        }
        public override string ToString()=>$"{Id} {FirstName} {LastName} {Country} {Wins}";
    }


    public class RacerComparer: IComparer<Racer>{
        public enum ComapareType{
            FirstName,
            LastName,
            Country,
            Wins
        }
        private ComapareType _compareType;
        public RacerComparer(ComapareType comapareType)=>_compareType = comapareType;
        public int Compare(Racer x,Racer y){
            if(x == null && x == null) return 0;
            if(x == null) return -1;
            if(y == null) return 1;
            int result;
            switch(_compareType){
                case ComapareType.FirstName:
                return string.Compare(x.FirstName,y.FirstName);
                case ComapareType.LastName:
                return string.Compare(x.LastName,y.LastName);
                case ComapareType.Country:
                result = string.Compare(x.Country,y.Country);
                if(result == 0)
                return string.Compare(x.LastName,y.LastName);
                else
                return result;
                case ComapareType.Wins:
                return x.Wins.CompareTo(y.Wins);
                default:
                throw new ArgumentException("Invalid Compare Type");
                //注:如果传递给Compare方法的两个元素的顺序相同,该方法则返回0.如果返回值小于0,
                //说明第一个参数小于第二个参数;
                //如果返回值大于0,则第一个参数大于第二个参数。
                //传递null作为参数,Compare方法并不会抛出一个NullReferenceException异常。
                //相反,因为null的位置在其他任何元素之前,所以如果第一个参数为null,该方法返回-1,
                //如果第二个参数为null,则返回+1。

            }

        }
    }
}

排序的另一种方式是使用重载的Sort()方法,该方法需要一个Comparison<T>委托:

public void List<T>.Sort(Comparison<T>);

Comparison<T>是一个方法的委托,该方法由两个T类型的参数,返回类型为int。如果参数值相等,该方法就必须返回0.如果第一个参数比第二个参数小,它就必须返回一个小于0的值;否则,必须返回一个大于0的值。

public delegate int Comparison<T>(T x,T y);

现在可以把一个lambda表达式传递给Sort()方法,按获胜次数排序。两个参数的类型是Racer,在其实现代码中,使用int类型的CompareTo()方法比较Wins属性。在实现代码中,因为使用逆序使用r2和r1,所以获胜次数以降序方式排序。调用方法之后,完整的赛车手列表就按赛车手的获胜次数排序。也可以调用Reverse()方法,逆转整个集合的顺序。

            System.Console.WriteLine("Sort by Wins");
            //racers.Sort(new RacerComparer(RacerComparer.ComapareType.Wins));
            racers.Sort((r1,r2)=>r2.Wins.CompareTo(r1.Wins));
            foreach(var value in racers){
                System.Console.WriteLine(value);
            }

            System.Console.WriteLine("Use reverse");
            racers.Reverse();
            foreach(var value in racers){
                System.Console.WriteLine(value);
            }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值