冒泡排序

冒泡排序

算法簡介

  冒泡排序(BubbleSort)算法:比較相鄰元素的大小,若是第一個元素大於第二個元素,則交換它們的位置,而後第二個元素與第三個元素比較,直到全部的元素比較完,冒泡出最小的元素。假設咱們有n各元素,那麼咱們就要進行 n-1 次冒泡,n-1 個最小的元素已經冒泡出來,所以,最後剩下的一個元素也就處於它應當處於的位置。算法

  本篇文章主要是對冒泡排序進行優化,使其避免沒必要要的比較,以及泛型的實現,共分四個版本。優化

先來看一張直觀的圖:spa

初版

  

static int FirstVersionBubbleSort(int[] array)
{
    int count = array.Length - 1;
    int number = 0;
    for (int i = 0; i < count; i++)
    {
        for (int j = 0; j < count - i; j++)
        {
            if (array[j] > array[j + 1])
            {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
            number++;
        }
    }
    return number;
}

外層循環用來控制冒泡的次數,內層循環用來比較相鄰元素的大小。number 用來記錄總共進行了幾回比較,爲後面的優化版本作對比。code

執行 Main():blog

int[] firstArray = { 2, 1, 3, 4 };

Console.WriteLine("總共比較的次數:{0}", FirstVersionBubbleSort(firstArray));
foreach (var item in firstArray)
{
    Console.Write(item.ToString().PadRight(2));
}

 

總共比較的次數:6
1 2 3 4

總共比較了6次,分別是:排序

第一次冒泡出 4:繼承

2-1:1 2 3 4string

2-3:1 2 3 4it

3-4 : 1 2 3 4io

第二次冒泡 3:

1-2 : 1 2 3 4

2-3 : 1 2 3 4

第三次冒泡 2:

1-2 : 1 2 3 4

看一下上面的過程,就很容想到,當整個數列已經排好序後咱們就沒有必要再作多餘的比較。用一個標誌量來表示上次是否內層循環是否有元素交換,若是有則進行下一次循環,不然退出,由於全部元素已經有序。

第二版

  

static int SecondVersionBubbleSort(int[] array)
{
    int count = array.Length;
    bool change;
    int number = 0;
    do
    {
        count--;
        change = false;
        for(int i = 0; i < count; i++)
        {
            if(array[i] > array[i + 1])
            {
                int temp = array[i];
                array[i] = array[i + 1];
                array[i + 1] = temp;
                change = true;
            }
            number++;
        }
    }while(change);
    return number;
}

執行Main():

int[] secondArray= { 2, 1, 3, 4 };

Console.WriteLine("\n總共比較的次數:{0}", SecondVersionBubbleSort(secondArray));
foreach (var item in secondArray)
{
    Console.Write(item.ToString().PadRight(2));
}
總共比較的次數:5
1 2 3 4

 

總共比較了5次,分別是:

第一次冒泡出 4:

2-1:1 2 3 4

2-3:1 2 3 4

3-4 : 1 2 3 4

此時 change 爲 true

第二次冒泡 3:

1-2 : 1 2 3 4

2-3 : 1 2 3 4

發現已經有序,change 爲 false, 結束冒泡。再繼續思考,事實上,第一次冒泡後,二、三、4 已經有序,所以下次循環徹底沒有必要再繼續對其比較;如今咱們增長一個位置變量來記錄每次冒泡的最後交換的位置,下次比較的此處就能夠了,避免對後面已經有序的元素重複進行比較。

static int ThirdVersionBubbleSort(int[] array)
{
    int count = array.Length - 1, index = 0;
    bool change;
    int number = 0;

    do
    {
        change = false;
        for (int i = 0; i < count; i++)
        {
            if (array[i] > array[i + 1])
            {
                int temp = array[i];
                array[i] = array[i + 1];
                array[i + 1] = temp;
                change = true;
                index = i;  // 記錄最後一次交換的位置
            }
            number++;
        }
        count = index;
    } while (change);
    return number;
}

執行 Main():

int[] thirdArray = { 2, 1, 3, 4 };

Console.WriteLine("\n總共比較的次數:{0}", ThirdVersionBubbleSort(thirdArray));
foreach (var item in thirdArray)
{
    Console.Write(item.ToString().PadRight(2));
}
總共比較的次數:3
1 2 3 4

有上面的結果,能夠看到,此次只進行了 3 次比較,分別以下:

總共比較了3次,分別是:

第一次冒泡出 4:

2-1:1 2 3 4

2-3:1 2 3 4

3-4 : 1 2 3 4

此時 index 爲 0, count 爲 0,結束冒泡。可見,這種方式,能夠大大下降比較的次數。

第四版

若是說繼承是爲咱們提供了代碼重用,那麼泛型則爲咱們提供了算法的重用。下面咱們將實現一個泛型版本的冒泡排序。

public static int FourthVersionBubbleSort<T>(List<T> list) where T:IComparable<T>
{
    int count = list.Count - 1, index = 0;
    bool change;
    int number = 0;

    do
    {
        change = false;
        for (int i = 0; i < count; i++)
        {
            if (list[i].CompareTo(list[i + 1]) > 0)
            {
                T temp = list[i];
                list[i] = list[i + 1];
                list[i + 1] = temp;
                change = true;
                index = i;  // 記錄最後一次交換的位置
            }
            number++;
        }
        count = index;
    } while (change);
    return number;
}

執行 Main():

List<string> stringList = new List<string> { "Banana", "Apple", "Orange" };
Console.WriteLine("總共比較的次數:{0}", FourthVersionBubbleSort(stringList));
foreach (var item in stringList)
{
    Console.Write(item.ToString().PadRight(10));
}
總共比較的次數:2
Apple     Banana    Orange

 

 結束語

  冒泡排序最優時間複雜度爲(即全部元素有序,只需遍歷一次便可) O(n),最差時間複雜度爲 O(n^2), 即當全部元素爲逆序時。 

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息