排序(二):冒泡排序法

一. 基本思想
    通过从左到右不断交换逆序的相邻元素,在一轮的交换之后,可以让未排序的元素上浮到右侧。在一轮循环中,如果没有发生交换,就说明数组已经是有序的,此时可以直接退出。

二. 代码实现

  • 版本一
/**
 - <br>冒泡排序</br>
 */
public class BubbleSort {

    /**
     * 外层循环控制比较的轮数,内层循环进行依次相邻元素的比较
     * 在第一轮比较中,最大的元素冒泡到了最后的位置;
     * 在第二轮比较中,第二大的元素冒泡到了倒数第二个位置;
     * 依此类推。
     * @param arr
     */
    public static void sort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
    }
	
    private static void swap(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}
  • 版本二
/**
 * <br>冒泡排序</br>
 */
public class BubbleSort2 {

        public static void sort(int[] arr) {
        int n = arr.length;
        boolean swap;
        do {
            /**
            * 这里的swap主要考虑的 如果数组是近乎有序的,
            * 那么在某轮比较后,没有产生swap操作,即剩下的
            * 未排序的元素已经是有序的了,就不用再比较了。
            */
            swap = false;
            for (int i = 0; i < n - 1; i++) {
                if (arr[i] > arr[i + 1]) {
                    swap(arr, i, i + 1);
                    swap = true;
                }
            }
            /**
             *  每一趟Bubble Sort都将最大的元素放在了最后的位置
             *  所以下一次排序, 最后的元素可以不再考虑
             */
            n--;
        } while (swap);
    }
    
    private static void swap(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}
/**
 * <br>冒泡排序优化</br>
 */
public class BubbleSort3 {

    /**
     * 按照之前升序排列,每轮循环将剩下元素中最大的元素调到最后.
     * 考虑这样的情况:假设在前面未排序的元素中,后面靠近尾端的元素已经是有序的了,
     * 但是之前的做法还是会每次把这些元素包括进去遍历.
     * 例如:原始一组数据: 3,6,2,4,5
     * 第一轮排序后:3,2,4,5,6
     * 按照之前的思想:接下来的一轮回会在剩下的未排序序列 3,2,4,5中找出最大的元素调到最后,
     * 但是4,5本身是有序的,他们在上一轮的遍历中并没有交换位置,所以我们完全可以依据上一轮的遍历设置个记录
     * 最后交换顺序的指针,然后只需要遍历这个指针之前的元素.
     *
     * @param arr
     */
    public static void sort(int[] arr) {
        int n = arr.length;
        int lastSwapIndex;
        do {
            //重置,清零
            lastSwapIndex = 0;
            for (int i = 0; i < n - 1; i++) {
                if (arr[i] > arr[i+1]){
                    swap(arr,i,i+1);
                    // 记录最后一次的交换位置,在此之后的元素在下一轮扫描中均不考虑,注意这里的临界点
                    lastSwapIndex = i+1;
                }
            }
            n = lastSwapIndex;
        } while (lastSwapIndex > 0);
    }

    private static void swap(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值