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

来源:互联网 发布:数控会编程能拿多少钱 编辑:程序博客网 时间:2024/05/16 03:57

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

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

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

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();        }    }
原创粉丝点击