C#实现冒泡排序之对泛型排序

来源:互联网 发布:火星15洲际导弹 知乎 编辑:程序博客网 时间:2024/06/06 18:42

在前面的文章中我们讲述了C#如何实现冒泡排序!那么有没有想过如何实现对任意的数据类型进行冒泡排序呢?这里我们将就此问题进行解答!首先我们了解到冒泡排序的本质就是升序或者降序排列一个数组的元素!我们首先去举个例子来感受一下冒泡排序,像整型数组就是这样排序:

       /// <summary>         /// 整型数组的冒泡排序         /// </summary>         /// <param name="arr"></param>         public static void BobbleSort(int[] arr)         {             for (int i = 0; i < arr.Length-1; i++)             {                 for (int j = 0; j < arr.Length-1-i; j++)                 {                     if (arr[j] < arr[j + 1])                     {                         int temp = arr[j];                         arr[j] = arr[j + 1];                         arr[j + 1] = temp;                     }                 }             }         }  

字符串数组的冒泡排序就是:

        /// <summary>        /// 字符串数组的冒泡排序        /// </summary>        /// <param name="arr"></param>        public static void BobbleSortStr(string[] arr)        {            for (int i = 0; i < arr.Length - 1; i++)            {                for (int j = 0; j < arr.Length - 1 - i; j++)                {                    if (arr[j].Length < arr[j + 1].Length)                    {                        string temp = arr[j];                        arr[j] = arr[j + 1];                        arr[j + 1] = temp;                    }                }            }        }

通过这两个冒泡排序的观察我们不难发现,这两个排序的不同之处只有在数据交换的条件判断时不同,其他的地方一模一样.我们不妨考虑把这个地方提取出来根据数据不同传递不同的条件!此时我们可以考虑把这个条件写成一个方法来进行传递,给他一个返回值的结果就可以了,那么就需要考虑需要什么类型的返回值?我们观察条件得知需要比较来交换变量的用途,既然考量的是比较的结果,很容易想到连个数比较大小无外乎三种情况,大于0,小于0,等于0。这里我们把可以把等于0并入其中的一种情况! 此时确定了返回值类型,我们还需要比较的方法,聪明的你是否想到了委托就可以满足这里的需求呢!
public delegate int DelCompare<T>(T t1,T t2);//传入两个参数来作比较 

然后修改刚才的代码:

        /// <summary>          /// 冒泡排序          /// </summary>          /// <param name="arr"></param>          public static void BobbleSort<T>(T[] arr,DelCompare<T> del)          {              for (int i = 0; i < arr.Length-1; i++)              {                  for (int j = 0; j < arr.Length-1-i; j++)                  {                      if (del(arr[j], arr[j + 1]) < 0)                      {                          T temp = arr[j];                          arr[j] = arr[j + 1];                          arr[j + 1] = temp;                      }                  }              }          }  
不妨也把打印的方法也写一个泛型的打印:
        /// <summary>          /// 打印数组的元素          /// </summary>          /// <typeparam name="T"></typeparam>          /// <param name="arr"></param>          public static void Print<T>(T[] arr)          {              for (int i = 0; i < arr.Length; i++)              {                  Console.Write(arr[i]+" ");              }              Console.WriteLine();          } 

好了,我们此时测试一下,让我们一起来见证奇迹: 

        void Main(string[] args)          {              int[] nums = { 1, 3, 54, 5, 6, 45, 6, 7, 8, 8, 34, 67, 8, 9 };              Print<int>(nums);              BobbleSOrt<int>(nums, (int t1, int t2) => {                  return t1 - t2;              });              Print<int>(nums);                Console.ReadKey();          }  

结果是我们预期的:


这样示范你觉得还不够那么我们不妨这样测试一下,写一个这样的自定义类:

    public class Person    {        //一些属性        public string Name { get; set; }        public int Age { get; set; }        public int MathScore { get; set; }        public int ChineseScore { get; set; }        public int EnglishScore { get; set; }        public Person()        {        }        public Person(string name, int age, int mathScore, int chineseScore, int englishScore)        {            this.Name = name;            this.Age = age;            this.MathScore = mathScore;            this.ChineseScore = chineseScore;            this.EnglishScore = englishScore;        }        public override string ToString()        {            return string.Format("{0} {1} {2} {3} {4} {5}", this.Name, this.Age, this.ChineseScore, this.MathScore, this.EnglishScore, (this.ChineseScore + this.MathScore + this.EnglishScore));        }    }


接着初始化一个Person类的数组:

            Person[] pArr = new Person[10];            Random range = new Random();            for (int i = 0; i < pArr.Length; i++)            {                int rAge = range.Next(10, 15);                int rChineseScore = range.Next(0, 101);                int rMathScore = range.Next(0, 101);                int rEnglishScore = range.Next(0, 101);                pArr[i] = new Person("张三_" + i, rAge, rMathScore, rChineseScore, rEnglishScore);            }

再次测试一下结果(这次按总成绩来排名):

            Print<Person>(pArr);            BobbleSort<Person>(pArr, (Person p1, Person p2) =>            {                return p1.ChineseScore + p1.MathScore + p1.EnglishScore - p2.ChineseScore - p2.MathScore - p2.EnglishScore;            });            Print<Person>(pArr);            Console.ReadKey();

我们惊奇的发现结果依然是我们预期的:


0 0