冒泡排序——C#实现

来源:互联网 发布:图片热点 js 编辑:程序博客网 时间:2024/06/08 16:43


       一 算法描述

       冒泡排序算法(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)