氣泡排序——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)