01-冒泡排序代码实现

冒泡排序代码实现及优化

一、算法描述

  1. 一次比较数组中相邻两元素的大小,若前者大于后者,则交换两个元素,两两都比较一遍称为一轮冒泡,结果是让最大的元素排至最后
  2. 重复以上步骤,直到整个数组 有序

算法实现---版本一

   /**
     * 实现冒泡排序的方法
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrder(int[] myInts){
        //外循环控制轮数,内循环控制次数
        for (int i = 0; i < myInts.length - 1; i++) {
            for (int j = 0; j < myInts.length - 1 - i; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                }
            }
        }
    }

算法实现---版本二

 /**
     * 优化方式一:如果当一轮中的所有元素都没有交换时,说明该数组已经有序
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrderVersion02(int[] myInts){
        //额外声明一个布尔变量来记录是否发生交换
        boolean swapped = false;
        //外循环控制轮数,内循环控制次数
        for (int i = 0; i < myInts.length - 1; i++) {
            for (int j = 0; j < myInts.length - 1 - i; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                    //如果交换了,就修改为true
                    swapped = true;
                }
            }
            //每一轮结束之后,判断是否数组已经有序
            if (!swapped) {
                break;
            }
        }
    }

算法实现---版本三

    /**
     * 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
     * 则下一轮的交换只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
     * 实现冒泡排序的方法
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrderVersion03(int[] myInts){
        //声明一个变量保存第一轮的需要的交换次数
        int first = myInts.length - 1;
        //声明一个变量保存每一轮最后交换元素的索引
        int last = 0;
        //外循环控制轮数,内循环控制次数
        while (true) {
            //每轮循环之前,需要设置 last为0,否则如果数组有序,而last的值还是上一轮循环的值,
           last = 0;
            for (int j = 0; j < first; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                    last = j;
                }
            }
            //每轮交换结束后设置下一轮需要交换的次数
            first = last;
            if (first == 0) {
                //数组已经有序,直接 退出
                break;
            }
        }
    }

交换数组中2个数的代码实现

  /**
     * 定义一个用于交换数组中2个元素的方法
     *
     * @param ints 整数数组
     * @param i    较大值的索引
     * @param j    较小值的索引
     */
    public static void swap(int[] ints, int i, int j) {
        //采用异或运算实现2个数的交换
        ints[i] = ints[i] ^ ints[j];
        ints[j] = ints[i] ^ ints[j];
        ints[i] = ints[i] ^ ints[j];
    }

算法实现---版本三导致死循环的示例


    /**
     * 错误演示,last设置不合理导致死循环
     *
     * 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
     * 则下一轮的教化只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
     * 实现冒泡排序的方法
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrderVersion04(int[] myInts){
        //声明一个变量保存第一轮的需要的交换次数
        int first = myInts.length - 1;
        //声明一个变量保存每一轮最后交换元素的索引
        int last = 0;
        //外循环控制轮数,内循环控制次数
        while (true) {
            //每轮循环之前,需要设置 last为0,否则如果某一轮结束后数组有序(不是在0位置),而last的值还是上一轮循环的值,
            //此时last就无法改变,导致无法退出循环
            //last = 0;
            for (int j = 0; j < first; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                    last = j;
                }
            }
            //每轮交换结束后设置下一轮需要交换的次数
            first = last;
            if (first == 0) {
                //数组已经有序,直接 退出
                break;
            }
        }
    }

完整代码如下

package org.example.test;

import java.util.Arrays;

/**
 * 冒泡排序
 *
 * @author JIA
 * @date 2022/10/07
 */
public class BubbleOrder {
    public static void main(String[] args) {
        //给定一个测试数组,以整数数组为例
        int[] myInts = new int[]{12,5, 3, 7, 2, 1, 9, 8, 4, 11};
        //测试排序方法
        //bubbleOrder(myInts);
        //bubbleOrderVersion02(myInts);
        bubbleOrderVersion04(myInts);
        System.out.println(Arrays.toString(myInts));
    }

    /**
     * 实现冒泡排序的方法
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrder(int[] myInts){
        //外循环控制轮数,内循环控制次数
        for (int i = 0; i < myInts.length - 1; i++) {
            for (int j = 0; j < myInts.length - 1 - i; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                }
            }
        }
    }

    /**
     * 优化方式一:如果当一轮中的所有元素都没有交换时,说明该数组已经有序
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrderVersion02(int[] myInts){
        //额外声明一个布尔变量来记录是否发生交换
        boolean swapped = false;
        //外循环控制轮数,内循环控制次数
        for (int i = 0; i < myInts.length - 1; i++) {
            for (int j = 0; j < myInts.length - 1 - i; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                    //如果交换了,就修改为true
                    swapped = true;
                }
            }
            //每一轮结束之后,判断是否数组已经有序
            if (!swapped) {
                break;
            }
        }
    }
    /**
     * 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
     * 则下一轮的教化只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
     * 实现冒泡排序的方法
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrderVersion03(int[] myInts){
        //声明一个变量保存第一轮的需要的交换次数
        int first = myInts.length - 1;
        //声明一个变量保存每一轮最后交换元素的索引
        int last = 0;
        //外循环控制轮数,内循环控制次数
        while (true) {
            //每轮循环之前,需要设置 last为0,否则如果数组有序,而last的值还是上一轮循环的值,
           last = 0;
            for (int j = 0; j < first; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                    last = j;
                }
            }
            //每轮交换结束后设置下一轮需要交换的次数
            first = last;
            if (first == 0) {
                //数组已经有序,直接 退出
                break;
            }
        }
    }

    /**
     * 错误演示,last设置不合理导致死循环
     *
     * 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
     * 则下一轮的教化只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
     * 实现冒泡排序的方法
     *
     * @param myInts 需要进行冒泡排序的数组
     */
    public static void bubbleOrderVersion04(int[] myInts){
        //声明一个变量保存第一轮的需要的交换次数
        int first = myInts.length - 1;
        //声明一个变量保存每一轮最后交换元素的索引
        int last = 0;
        //外循环控制轮数,内循环控制次数
        while (true) {
            //每轮循环之前,需要设置 last为0,否则如果某一轮结束后数组有序(不是在0位置),而last的值还是上一轮循环的值,
            //此时last就无法改变,导致无法退出循环
            //last = 0;
            for (int j = 0; j < first; j++) {
                if (myInts[j] > myInts[j + 1]) {
                    //交换2个元素的位置
                    swap(myInts, j, j + 1);
                    last = j;
                }
            }
            //每轮交换结束后设置下一轮需要交换的次数
            first = last;
            if (first == 0) {
                //数组已经有序,直接 退出
                break;
            }
        }
    }
    /**
     * 定义一个用于交换数组中2个元素的方法
     *
     * @param ints 整数数组
     * @param i    较大值的索引
     * @param j    较小值的索引
     */
    public static void swap(int[] ints, int i, int j) {
        //采用异或运算实现2个数的交换
        ints[i] = ints[i] ^ ints[j];
        ints[j] = ints[i] ^ ints[j];
        ints[i] = ints[i] ^ ints[j];
    }
}

总结

冒泡排序是一种非常稳定的排序方法,但是遇到一些特殊的数组,反而会减低效率,这个时候就要考虑适当的优化

posted @ 2022-10-07 21:19  书画三千里  阅读(97)  评论(0)    收藏  举报