淺談排序算法之冒泡排序(1)續

今天下午筆者在網上查閱算法時,無意間發現了一個算法,名曰“雞尾酒排序”。啥?沒聽過啊,點擊去一看,該算法是冒泡排序算法的一種改進。在每一次循環的時候,從當前剩下未排序的數組裏選擇最小值放在數組前面,最大值放在數組後面(這裏的前面與後面指的是在未排序部分)。因此,該算法本身外層迭代次數爲數組長度的一半。

例如,對於原始數組

14, 12, 18, 12, 1, 6, 18, 4, 0, 2, 0

第一次迭代後,原數組變更爲

0, 12, 14, 12, 1, 6, 18, 4, 0, 2, 18

即將最小值0和最大值18分別存放於數組首和數組尾。第二次迭代後,原數組變更爲

0, 0, 12, 12, 1, 6, 14, 4, 2, 18, 18

第三次迭代後,數組變更爲

0, 0, 1, 12, 2, 6, 12, 4, 14, 18, 18

由此可見,排序結果在預期之內。值得注意的是,這個算法雖然在外層循環的時候,其循環次數爲數組長度的一半,但是內層包含兩個循環,其最壞情況下的複雜度爲O(n^2)。但是若數組本身大部分內容已經有序,則迭代次數接近於O(n)。

代碼如下:

import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.Random;

/**
 * This class, {@code BidirectionalBubbleSort} is another version of
 * {@link org.vimist.pro.Algorithm.Sort.BubbleSort} and it's an illustration
 * of that algorithm.
 *
 * @author Mr.K
 */
public class BidirectionalBubbleSort {

    public static void main(String[] args) {
        int N = 15;
        int[] numbers = new int[N];
        Random random = new Random();
        for (int i = 0; i < N; i++) {
            numbers[i] = random.nextInt(2 * N);
        }
        System.out.println("待排序數組: " + Arrays.toString(numbers) + "\n");
        bidirectionalBubbleSort(numbers);
        System.out.println("\n已排序數組: " + Arrays.toString(numbers));
    }

    /**
     * Another version of {@link org.vimist.pro.Algorithm.Sort.BubbleSort#bubbleSort(int[])}, which
     * starts the sort bidirectionally. Thus the count of iteration is half of the length of specified
     * array.
     * <ul>
     *     <li>In each iteration, there exists two <em>For-Loops</em>. For the i-th iteration, the
     *     i-th minimum number will be put in the front of the specified array, and the i-th maximum
     *     number will be put in the back of specified array.</li>
     * </ul>
     * Be aware that the cost of time for this algorithm is O(n^2) in some worst cases. If most part of
     * the array is sorted, then the cost of time converge to O(n).
     *
     * @param arr specified array to be sorted
     */
    public static void bidirectionalBubbleSort(@NotNull int[] arr) {
        for (int i = 0; i < arr.length / 2; i++) {
            /**
             * Puts the minimum numbers to the front of specified array.
             */
            for (int j = arr.length - i - 1; j > i; j--) {
                if (arr[j - 1] > arr[j]) {
                    int temp = arr[j - 1] ^ arr[j];
                    arr[j - 1] = temp ^ arr[j - 1];
                    arr[j] = temp ^ arr[j];
                }
            }

            /**
             * Puts the maximum numbers to the back of specified array.
             */
            for (int j = i; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j] ^ arr[j + 1];
                    arr[j] = temp ^ arr[j];
                    arr[j + 1] = temp ^ arr[j + 1];
                }
            }
            System.out.println("第" + String.format("%2d", i + 1) + "次迭代後: " + Arrays.toString(arr));
        }
    }

}

運行結果如下:

待排序數組: [6, 27, 15, 21, 11, 15, 26, 16, 10, 6, 15, 22, 6, 24, 22]1次迭代後: [6, 6, 15, 21, 11, 15, 26, 16, 10, 6, 15, 22, 22, 24, 27]2次迭代後: [6, 6, 6, 15, 11, 15, 21, 16, 10, 15, 22, 22, 24, 26, 27]3次迭代後: [6, 6, 6, 10, 11, 15, 15, 16, 15, 21, 22, 22, 24, 26, 27]4次迭代後: [6, 6, 6, 10, 11, 15, 15, 15, 16, 21, 22, 22, 24, 26, 27]5次迭代後: [6, 6, 6, 10, 11, 15, 15, 15, 16, 21, 22, 22, 24, 26, 27]6次迭代後: [6, 6, 6, 10, 11, 15, 15, 15, 16, 21, 22, 22, 24, 26, 27]7次迭代後: [6, 6, 6, 10, 11, 15, 15, 15, 16, 21, 22, 22, 24, 26, 27]

已排序數組: [6, 6, 6, 10, 11, 15, 15, 15, 16, 21, 22, 22, 24, 26, 27]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章