一:冒泡排序的思想
(1)冒泡排序是交换排序的一种,另一种交换排序是快速排序;
(2)冒泡排序算法的基本思想是:假设待排序表长为n,从后往前(从右往左)(或从前往后(从左往右))两两比较相邻元素的值,若为逆序(即arr[j-1]>arr[j]),则交换它们,直到序列比较完,这称之为一趟冒泡排序,结果是将最小的元素交换到待排序序列的第一个位置(最小的元素如气泡一般逐渐往上“漂浮”直至“水面”,这就是冒泡排序名字的由来)。下一趟冒泡时,前一趟确定的最小元素不再参与比较,待排序序列减少一个元素,每趟冒泡的结果把序列中的最小元素放到了序列的最终位置上,...,这样最多经过n-1趟冒泡就能把所有的元素排好序;
(3)冒泡排序的伪代码如下所示(王道数据结构版本):
1 void bubbleSort(ElemType A[],int n){ 2 // 用冒泡排序法将序列A中的元素按从小到大排列 3 for(int=0;i<n-1;i++){ 4 flag = false; // 表示本趟冒泡是否发生交换的标志 5 for(j=n-1;j>i;j--){ // 一趟冒泡的过程 6 if(A[j-1].key > A[j].key){ // 若为逆序 7 swap(A[j-1],A[j]); // 交换 8 flag = true; 9 } 10 } 11 if(falg = false){ 12 break; // 本趟遍历后没有发生交换,说明表已经有序,直接跳出循环 13 } 14 } 15 }
(4)冒泡排序性能总结:
(4.1)空间效率:空间复杂度为O(1);
(4.2) 时间效率:最好时间复杂度O(n), 最坏时间复杂度O(n2), 平均时间复杂度O(n2);
(4.3) 稳定性:是稳定的排序方法。
(5)常见代码实现
(5.1)从小到大排序,从左往右比较(从前往后比较),不考虑性能优化问题
1 package cn.sun.it.thread; 2 3 import java.util.Arrays; 4 import java.util.Scanner; 5 6 public class BubbleSort_V1 { 7 8 public static void main(String[] args) { 9 // 10 1 35 61 89 36 55 10 // 9,8,7,6,5,4,3,2,1 11 Scanner sc = new Scanner(System.in); 12 System.out.println("请输入若干个整数,以逗号分隔:"); 13 String strNumbers = sc.nextLine(); 14 String[] tempNums = strNumbers.split(","); 15 int[] arr = new int[tempNums.length]; 16 for (int i = 0; i < arr.length; i++) { 17 arr[i] = Integer.valueOf(tempNums[i]); 18 } 19 System.out.println("->排序前:" + Arrays.toString(arr)); 20 bubbleSort_v1(arr); 21 System.out.println("->排序后:" + Arrays.toString(arr)); 22 23 } 24 25 // 从小到大排序,从左往右比较(从前往后比较),不考虑性能优化问题 26 public static void bubbleSort_v1(int[] arr){ 27 for(int i=0;i<arr.length-1;i++){ 28 for(int j=0;j<arr.length-1-i;j++){ 29 if(arr[j]>arr[j+1]){ 30 int temp = arr[j]; 31 arr[j] = arr[j+1]; 32 arr[j+1] = temp; 33 } 34 System.out.println("第"+(i+1)+"趟,第"+(j+1)+"次排序结果为:"+Arrays.toString(arr)); 35 } 36 System.out.println("*第"+(i+1)+"趟排序结果为:"+Arrays.toString(arr)); 37 } 38 } 39 40 }
输出结果:
(5.2)从小到大排序,从右往左比较(从后往前比较),不考虑性能优化问题
1 package cn.sun.it.thread; 2 3 import java.util.Arrays; 4 import java.util.Scanner; 5 6 public class BubbleSort_V2 { 7 8 public static void main(String[] args) { 9 // 10 1 35 61 89 36 55 10 // 7,6,5,4,3,2,1 11 Scanner sc = new Scanner(System.in); 12 System.out.println("请输入若干个整数,以逗号分隔:"); 13 String strNumbers = sc.nextLine(); 14 String[] tempNums = strNumbers.split(","); 15 int[] arr = new int[tempNums.length]; 16 for (int i = 0; i < arr.length; i++) { 17 arr[i] = Integer.valueOf(tempNums[i]); 18 } 19 System.out.println("->排序前:" + Arrays.toString(arr)); 20 bubbleSort_v2(arr); 21 System.out.println("->排序后:" + Arrays.toString(arr)); 22 23 } 24 25 // 从小到大排序,从右往左比较(从后往前比较),不考虑性能优化问题 26 public static void bubbleSort_v2(int[] arr) { 27 for (int i = 0; i < arr.length - 1; i++) { 28 int count = 0; 29 for (int j = arr.length - 1; j > i; j--) { 30 if (arr[j] < arr[j - 1]) { 31 int temp = arr[j - 1]; 32 arr[j - 1] = arr[j]; 33 arr[j] = temp; 34 35 } 36 System.out.println("第" + (i + 1) + "趟,第" + (++count) + "次排序结果为:" + Arrays.toString(arr)); 37 } 38 System.out.println("*第" + (i + 1) + "趟排序结果为:" + Arrays.toString(arr)); 39 } 40 } 41 42 }
输出结果:
(5.3)从小到大排序,从左往右比较(从前往后比较),考虑性能优化问题
1 package cn.sun.it.thread; 2 3 import java.util.Arrays; 4 import java.util.Scanner; 5 6 public class BubbleSort_V3 { 7 8 public static void main(String[] args) { 9 // 10,1,35,61,89,36,55 10 // 7,6,5,4,3,2,1 11 Scanner sc = new Scanner(System.in); 12 System.out.println("请输入若干个整数,以逗号分隔:"); 13 String strNumbers = sc.nextLine(); 14 String[] tempNums = strNumbers.split(","); 15 int[] arr = new int[tempNums.length]; 16 for (int i = 0; i < arr.length; i++) { 17 arr[i] = Integer.valueOf(tempNums[i]); 18 } 19 System.out.println("->排序前:" + Arrays.toString(arr)); 20 bubbleSort_v3(arr); 21 System.out.println("->排序后:" + Arrays.toString(arr)); 22 23 } 24 25 // 从小到大排序,从左往右比较(从前往后比较),考虑性能优化问题 26 public static void bubbleSort_v3(int[] arr) { 27 int temp = 0; 28 boolean flag = false; 29 for (int i = 0; i < arr.length - 1; i++) { 30 for (int j = 0; j < arr.length - 1 - i; j++) { 31 if (arr[j] > arr[j + 1]) { 32 temp = arr[j]; 33 arr[j] = arr[j + 1]; 34 arr[j + 1] = temp; 35 flag = true; 36 } 37 System.out.println("第" + (i + 1) + "趟,第" + (j + 1) + "次排序结果为:" + Arrays.toString(arr)); 38 } 39 System.out.println("第" + (i + 1) + "趟排序结果为:" + Arrays.toString(arr)); 40 if (!flag) { 41 break; 42 } else { 43 flag = false; 44 } 45 } 46 } 47 }
输出结果:
(5.4)从小到大排序,从右往左比较(从后往前比较),考虑性能优化问题
1 package cn.sun.it.thread; 2 3 import java.util.Arrays; 4 import java.util.Scanner; 5 6 public class BubbleSort_V4 { 7 8 public static void main(String[] args) { 9 // 10,1,35,61,89,36,55 10 // 7,6,5,4,3,2,1 11 Scanner sc = new Scanner(System.in); 12 System.out.println("请输入若干个整数,以逗号分隔:"); 13 String strNumbers = sc.nextLine(); 14 String[] tempNums = strNumbers.split(","); 15 int[] arr = new int[tempNums.length]; 16 for (int i = 0; i < arr.length; i++) { 17 arr[i] = Integer.valueOf(tempNums[i]); 18 } 19 System.out.println("->排序前:" + Arrays.toString(arr)); 20 bubbleSort_v4(arr); 21 System.out.println("->排序后:" + Arrays.toString(arr)); 22 23 } 24 25 // 从小到大排序,从右往左比较(从后往前比较),考虑性能优化问题 26 public static void bubbleSort_v4(int[] arr) { 27 int temp = 0; 28 boolean flag = false; 29 for (int i = 0; i < arr.length - 1; i++) { 30 int count = 0; 31 for (int j = arr.length - 1; j > i; j--) { 32 if (arr[j] < arr[j - 1]) { 33 temp = arr[j]; 34 arr[j] = arr[j - 1]; 35 arr[j - 1] = temp; 36 flag = true; 37 } 38 System.out.println("第" + (i + 1) + "趟,第" + (++count) + "次排序结果为:" + Arrays.toString(arr)); 39 } 40 System.out.println("第" + (i + 1) + "趟排序结果为:" + Arrays.toString(arr)); 41 if (!flag) { 42 break; 43 } else { 44 flag = false; 45 } 46 } 47 } 48 }
输出结果: