1. 概述
老规矩,自己就不写总结和概述了,可以看百科的介绍,写的挺好:baike.baidu.com/item/%E5%86…
基本的流程如下:
- 第一轮:
- 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-1 轮
- ...
- 第 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)