排序-冒泡排序 O(n^2)

347 阅读3分钟

1. 概述

老规矩,自己就不写总结和概述了,可以看百科的介绍,写的挺好:baike.baidu.com/item/%E5%86…

基本的流程如下:

  1. 第一轮:
    • arr[0] 与 arr[1] 比较,如果 arr[1] 大,互相交换;
    • ...
    • arr[i] 与 arr[i+1] 比较,如果 arr[i] 大,互相交换;
    • ...
    • arr[n-2] 与 arr[n-1] 比较,如果 arr[n-2] 大,互相交换;
    • 第一轮下来,0 ~ n-1 最大的数到了 arr[n-1]
  2. 第二轮:
    • arr[0] 与 arr[1] 比较,如果 arr[1] 大,互相交换;
    • ...
    • arr[i] 与 arr[i+1] 比较,如果 arr[i] 大,互相交换;
    • ...
    • arr[n-3] 与 arr[n-2] 比较,如果 arr[n-2] 大,互相交换
    • 第二轮下来,0 - n-2 最大的数到了 arr[n-2]
  3. 第三轮 ~ 第 n-1 轮
    • ...
  4. 第 n 轮
    • arr[0] 与 arr[0] 比较,

2. 代码实现

package com.omg.sort;

import java.util.Arrays;

/**
 * @description: 冒泡排序
 * 第一轮:
 *      arr[0] 与 arr[1] 比较,如果 arr[1] 大,互相交换;
 *      ...
 *      arr[i] 与 arr[i+1] 比较,如果 arr[i] 大,互相交换;
 *      ...
 *      arr[n-2] 与 arr[n-1] 比较,如果 arr[n-2] 大,互相交换;
 * 第一轮下来,0 ~ n-1 最大的数到了 arr[n-1]
 *
 * 第二轮:
 *     arr[0] 与 arr[1] 比较,如果 arr[1] 大,互相交换;
 *     ...
 *     arr[i] 与 arr[i+1] 比较,如果 arr[i] 大,互相交换;
 *     ...
 *     arr[n-3] 与 arr[n-2] 比较,如果 arr[n-2] 大,互相交换
 * 第二轮下来,0 - n-2 最大的数到了 arr[n-2]
 * ...
 *
 * 第 n 轮
 *    arr[0] 与 arr[0] 比较,
 */
public class Code02_BubbleSort {
    public static void bubbleSort(int[] arr){
        if (null == arr || arr.length <= 1){
            return;
        }

        for (int i = arr.length - 1; i > 0; i--){
            for (int j=0; j < i; j++){
                if (arr[j] > arr[j+1]){
                    swap(arr, j, j+1);
                }
            }
        }
    }

    public static void swap(int[] arr, int i, int j){
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }

    public static void comparator(int[] arr){
        Arrays.sort(arr);
    }

    /**
     * @description: 生成随机数组,用来测试排序,并与对数器比较结果
     * @param maxSize 数组的最大长度
     * @param maxValue 数组中元素的取值区间 [-maxValu, maxValu]
     */
    public static int[] generateRandomArray(int maxSize, int maxValue){
        int size = (int)(Math.random()*(maxSize+1));
        int[] arr = new int[size];
        for (int i=0; i<arr.length; i++){
            // 数据内元素第区间为 [-maxValue, maxValue]
            arr[i] = (int)(Math.random()*(maxValue+1)) - (int)(Math.random()*(maxValue+1));
        }
        return arr;
    }

    /**
     * @description: 数组拷贝,创建一个相同的数组,用于对数器排序比较
     */
    public static int[] copyArray(int[] arr){
        if (arr == null) {
            return null;
        }

        int[] res = new int[arr.length];
        for (int i=0; i<arr.length; i++){
            res[i] = arr[i];
        }

        return res;
    }

    /**
     * @description: 判断两个数组是否相同
     */
    public static boolean isEqual(int[] arr1, int[] arr2) {
        if (arr1 == arr2){
            return true;
        }

        if (arr1.length != arr2.length){
            return false;
        }

        if (arr1 != null && arr2 != null){
            for (int i=0; i<arr1.length; i++){
                if (arr1[i] != arr2[i]){
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * @description: 打印数组,如果排序结果和对数器的结果不一致可以打印出来,方便分析问题
     */
    public static void printArray(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }


    public static void main(String[] args) {
        // 测试次数
        int testTime = 50000;
        // 数组最大长度
        int maxSize = 100;
        // 数组内元素取值区间 [-100, 100]
        int maxValue = 100;
        boolean succeed = true;
        for (int i=0; i<testTime; i++){
            int[] arr1 = generateRandomArray(maxSize, maxValue);
            int[] arr2 = copyArray(arr1);
            bubbleSort(arr1);
            comparator(arr2);
            // 自己实现的选择排序结果与对数器结果比较,如果不一致 break 跳出循环
            if (!isEqual(arr1, arr2)){
                succeed = false;
                printArray(arr1);
                printArray(arr2);
                break;
            }
        }

        System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    }
}

3. 时间复杂度和空间复杂度

时间复杂度推导和选择排序一样,也是 O(n^2) 空间复杂度为 O(1)