冒泡排序——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[] array, Comparison 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(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(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)

你可能感兴趣的:(算法,c#,排序算法,算法,c#,冒泡排序)