排序演算法(二)雞尾酒排序演算法(雙向冒泡)
1、我們知道,在氣泡排序演算法中,每一次冒泡的過程就是一次求最值的過程,也就是說一次冒泡只能確定一個數的位置。所以氣泡排序需要冒泡n-1次(n為待排序資料的個數),現在我們可以這樣想:如果一次冒泡的過程中,同時確定首尾兩個最值,這樣是否可以實現呢!
2、如前所述的排序方法實際上是基於氣泡排序演算法的,也就是一種雙向的氣泡排序演算法,也稱雞尾酒排序演算法。
3、下面以一組數{1, 5, 0, 2, 4, 3}為例,通過與普通冒泡演算法比較說明該演算法:
普通冒泡演算法:
(1)大值右移(注:通過交換相鄰的元素實現移動):{1, 0, 2, 4, 3, 5},此時資料5的位置確定了;
(2)現在對{1, 0, 2, 4, 3}進行排序,大值右移
(3)現在對{1, 0, 2, 3}進行排序,,大值右移:{1, 0, 2, 3},此時資料3的位置確定了;
(4)現在對{1, 0, 2,}進行排序,,大值右移:{1, 0, 2},此時資料2的位置確定了;
(5)現在對{1, 0}進行排序,,大值右移:{0, 1},此時資料1的位置確定了;
經過如上5步(即5次冒泡)後,這組數就實現了升序。
下面是雙向冒泡演算法的實現:
(1)大值向右移(注:同樣通過交換相鄰的元素實現移動):{1, 0, 2, 4, 3, 5},此時資料5的位置確定了;
(2)現在對{1, 0, 2, 4, 3}反向排序,小值左移:{0, 1, 2, 3, 4},現在我們看到實際上這組數已經排好序了。
注:上述兩步是在一次內迴圈中完成的,也就是在一次冒泡過程中先將最大值交換到最右邊,再將最小值交換到最左邊,一次確定兩個數的位置。
4、下面是實現程式碼:
#define swap(x, y) (x = (x) + (y), y = (x) - (y), x = (x) - (y))
|
void CocktailSort1( int * a, int n)
{
for ( int i = 0; i < n - 1; i++)
{
for ( int j = i; j < n - 1 - i; j++) {
if (a[j] > a[j + 1])
{
swap(a[j], a[j + 1]);
}
}
for ( int j = n - 1 - i - 1; j > i; j--)
{
if (a[j] < a[j - 1])
{
swap(a[j], a[j - 1]);
}
}
}
}
|
5、就上例來說,顯然雙向氣泡排序與普通氣泡排序法相比,減少了交換次數;當然該演算法也可以有普通冒泡演算法類似的優化:
void CocktailSort1( int * a, int n)
{
bool bFlag = true ;
for ( int i = 0; i < n - 1; i++)
{
bFlag = true ;
for ( int j = i; j < n - 1 - i; j++)
{
if
|