委托的应用——通用冒泡排序

学习过数据结构和算法的,都知道冒泡排序是如何实现的,它是从最前面两个数开始比较,如果前面的数比后面的大,就交换位置,以此类推,使数据完成从小到大的排序。

但是在实际应用中,不可能是只给你一些整型的数据来让你排序,可能是给你一个类,里面有很多属性,我们需要根据其中的一个属性的大小来排序,所以我们需要使用委托,来进行数据的排序。

我们可以举个最简单的的例子,假如在一个公司里有很多员工,我们需要根据他们的工资来进行排序,首先我们要有一个员工类:

class Employee
    {
        public string Name { get; private set; }
        public int Salary { get; private set; }

        //构造方法
        public Employee(string Name, int Salary)
        {
            this.Name = Name;
            this.Salary = Salary;
        }
    }

然后我们先写出冒泡排序的方法:

static void Sort(int[] sortArray)
        {
            //判断数组是否经过排序
            bool swapped = true;
            do
            {
                swapped = false;
                for (int i = 0; i < sortArray.Length - 1; i++)
                {
                    //判断是否符合前面的数大于后面的数
                    if (sortArray[i] > sortArray[i + 1])
                    {
                        //对两个数进行交换
                        int temp = sortArray[i];
                        sortArray[i] = sortArray[i + 1];
                        sortArray[i + 1] = temp;
                        swapped = true;
                    }
                }
            } while (swapped);
        }

现在我们可以开始使用委托和泛型来修改这个方法,使得这个方法适用于其他数据:

static void CommonSort<T>(T[] sortArray,Func<T,T,bool> CompareMethod)
        {
            bool swapped = true;
            do
            {
                swapped = false;
                for (int i = 0; i < sortArray.Length - 1; i++)
                {
                    //因为泛型无法进行比较,所以需要在类里写一个比较大小的方法,并且使用泛型委托
                    if (CompareMethod(sortArray[i],sortArray[i+1])) 
                    {
                        T temp = sortArray[i];
                        sortArray[i] = sortArray[i + 1];
                        sortArray[i + 1] = temp;
                        swapped = true;
                    }
                }
            } while (swapped);
        }

1.首先,因为我们需要进行排序的数据不再是一串整型数据,所以这个排序方法我们需要用泛型来修饰,传入的数组也需要使用泛型。
2. 然后,因为这些是泛型数据,我们不能够再用“>“”<”这两个符号来判断两个数据的大小,所以我们需要在员工类里写一个比较大小的方法,然后使用泛型委托:

//Employee类里的比较方法
public static bool Compare(Employee e1, Employee e2)
        {
            if (e1.Salary > e2.Salary) return true;
            return false;
        }

3.在员工类里我们已经将比较薪水大小的方法写好了,然后在排序方法里,我们可以使用Func委托来指向我们这个比较大小的方法,由于还是不知道数据的类型,所以这个委托要写为:Func<T,T,bool> CompareMethod
4.现在原来的冒泡排序也被改写成通用的冒泡排序了,我们在主函数里先创建一个员工数组:

Employee[] employees = new Employee[]
            {
                new Employee("shdw",23), 
                new Employee("sdw",452), 
                new Employee("rthg",234), 
                new Employee("ngb",123), 
                new Employee("jyjy",765), 
                new Employee("awdw",567), 
                new Employee("cxc",345), 
                new Employee("erf",789), 
                new Employee("vde",246)
            };

5.然后我们就需要根据员工的薪水来对这个数组进行排序:
CommonSort<Employee>( employees,Employee.Compare );
因为冒泡排序我们是使用泛型来修饰的,所以我们使用这个方法时要指定这个数组的类型。
6.排序之后,我们就要输出这个数组,来验证排序方法是否成功,在这里我们使用foreach方法来对数组进行遍历输出:

foreach (Employee em in employees)
            {
                Console.WriteLine(em); 
            }

但是我们会发现输出的结果并不是员工的数据:
这里写图片描述

因为在这里我们不是遍历变量,而是遍历对象,在遍历对象的时候,编译器会默认调用ToString方法,所以我们需要在员工类里重写ToString方法:

//Employee类
public override string ToString()
        {
            return Name + ":" + Salary;
        }

然后我们再输出一次结果
这里写图片描述

这样,我们对冒泡排序的改造就完成了,他也可以应用于其他相似的类型。通过这个应用,我们也可以对委托和泛型有进一步的了解。

这里放出源代码:

//员工类
class Employee
    {
        public string Name { get; private set; }
        public int Salary { get; private set; }

        public Employee(string Name, int Salary)
        {
            this.Name = Name;
            this.Salary = Salary;
        }

        public static bool Compare(Employee e1, Employee e2)
        {
            if (e1.Salary > e2.Salary) return true;
            return false;
        }

        public override string ToString()
        {
            return Name + ":" + Salary;
        }
    }

    class Program
    {
        static void CommonSort<T>(T[] sortArray,Func<T,T,bool> CompareMethod)
        {
            bool swapped = true;
            do
            {
                swapped = false;
                for (int i = 0; i < sortArray.Length - 1; i++)
                {
                    //因为泛型无法进行比较,所以需要在类里写一个比较大小的方法,并且使用泛型委托
                    if (CompareMethod(sortArray[i],sortArray[i+1])) 
                    {
                        T temp = sortArray[i];
                        sortArray[i] = sortArray[i + 1];
                        sortArray[i + 1] = temp;
                        swapped = true;
                    }
                }
            } while (swapped);
        }

        static void Main(string[] args)
        {
            Employee[] employees = new Employee[]
            {
                new Employee("shdw",23), 
                new Employee("sdw",452), 
                new Employee("rthg",234), 
                new Employee("ngb",123), 
                new Employee("jyjy",765), 
                new Employee("awdw",567), 
                new Employee("cxc",345), 
                new Employee("erf",789), 
                new Employee("vde",246)
            };
            CommonSort<Employee>(employees,Employee.Compare);
            foreach (Employee em in employees)
            {
                Console.WriteLine(em); //因为遍历对象的时候,编译器会默认调用ToString方法,所以我们需要重写ToString方法
            }
            Console.ReadKey();
        }
    }
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值