1. 程式人生 > >氣泡排序——C#實現

氣泡排序——C#實現

       一 演算法描述

       氣泡排序演算法(Bubble Sort)是一種流行但低效的排序演算法。它的原理是反覆比較待排序陣列中所有相鄰的兩個資料,使他們按照升序(或降序)排列。當待排序陣列中所有相鄰資料都比較過一次之後,待排序陣列中最小(或最大)的資料會被逐步交換到第一位,就像氣泡從水底慢慢升到水面一樣,故名“氣泡排序演算法”。

       二 演算法實現

       1 用於整數陣列的升序排序

        public static void BubbleSort(int[] array)
        {
            bool hasExchagend = false;
            for (int i = 0; i < array.Length - 1; i++)
            {
                hasExchagend = false;
                for (int j = array.Length - 1; j > i; j--)
                {
                    if (array[j] < array[j - 1])
                    {
                        Exchange(ref array[j], ref array[j - 1]);
                        hasExchagend = true;
                    }
                }
                if(!hasExchagend)
                {
                    return;
                }
            }
        }

       2 用於整數陣列的降序排序
        public static void BubbleDesSort(int[] array)
        {
            bool hasExchagend = false;
            for (int i = 0; i < array.Length - 1; i++)
            {
                hasExchagend = false;
                for (int j = array.Length - 1; j > i; j--)
                {
                    if (array[j] > array[j - 1])
                    {
                        Exchange(ref array[j], ref array[j - 1]);
                        hasExchagend = true;
                    }

                }
                if (!hasExchagend)
                {
                    return;
                }

            }

        }

       3 泛型版本

        public static void BubbleSort<T>(T[] array, Comparison<T> comparison)
        {
            bool hasExchagend = false;
            for (int i = 0; i < array.Length - 1; i++)
            {
                for (int j = array.Length - 1; j > i; j--)
                {
                    hasExchagend = false;
                    if (comparison(array[j - 1], array[j]) > 0)
                    {
                        Exchange<T>(ref array[j], ref array[j - 1]);
                        hasExchagend = true;
                    }
                }

                if (!hasExchagend)
                {
                    return;
                }

            }

        }
 

      輔助方法

        private static void Exchange(ref int x, ref int y)
        {
            int temp = x;
            x = y;
            y = temp;
        }

        private static void Exchange<T>(ref T x, ref T y)
        {
            T temp = x;
            x = y;
            y = temp;
        }

       三 演算法分析

       1 此演算法中程式碼為2層巢狀迴圈,外層迴圈執行(n-1)次,內層迴圈平均執行n/2次,故在不考慮程式碼中return語句的情況下,時間複雜度為O(n^2)。注意到程式碼中hasExchanged的作用,在開始一輪“冒泡”的時候,hasExchanged置為false,當在完成某一輪“冒泡”後,若hasExchanged仍然為false,則說明本輪冒泡沒有進行元素交換,因此原本的待排序陣列已經是有序的了,則此時方法直接終止執行並返回。

       因此,冒泡演算法的最壞情況的時間複雜度為O(n^2),最佳情況下的時間複雜度為O(n).

       2 氣泡排序也是一種原址排序演算法,所以其空間複雜度為O(1)。

       3 氣泡排序演算法是穩定的。氣泡排序演算法只涉及到相鄰兩個資料的比較,如果相鄰兩個數的值相等,並不會發生交換。故,排序前後,相同值的相對位置不會改變。

       四 執行結果

       在氣泡排序演算法中,可根據相鄰元素的比較次數來估算。

       在演算法的泛型實現版本中,通過在委託傳入的比較方法里加入計數語句,則能很容易的得到比較語句執行的次數。

private static int AscComparison(int x, int y)    
{    
    count++;   
    if (x > y)    
    {    
        return 1;    
    }    
    else if (x == y)    
    {    
        return 0;    
    }    
    else    
    {    
        return -1;    
    }    
} 

       為了測試該演算法的平均執行情況,通過對10000個隨機陣列進行排序取平均:
static void Main(string[] args)    
{    
    for (int i = 0; i < 10000; i++)    
    {    
        //在1-100內產生10個隨機數    
        int[] randomIntArray = DataCreator.CreateRandomIntArray(1, 100, 10);    
        Sort.BubbleSort(randomIntArray, AscComparison);    
        PrintAarry(randomIntArray);    
    }    
    int averageCount = count / 10000;    
    Console.WriteLine(averageCount);    
} 

       測試結果:

       n = 10,  averageCount = 32 = 0.32* 10 ^2; 
       n = 100,   averageCount = 3330= 0.33 * 100 ^ 2;
       n = 1000, averageCount = 333600 = 0.33 * 1000^2;

       可見,冒泡演算法的平均時間複雜度也是θ(n^2)