浅谈排序算法之冒泡排序(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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值