1. 程式人生 > >C#實現氣泡排序之對泛型排序

C#實現氣泡排序之對泛型排序

在前面的文章中我們講述了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();

我們驚奇的發現結果依然是我們預期的: