package com.example.sort.bubbling; import java.util.Scanner; /** * 9 6 1 3 5 * 6 9 1 3 5 * 6 1 9 3 5 * 6 1 3 9 5 * 6 1 3 5 9 * 第一轮结束 9 从第一位 转移到了最后一位, * 6 1 3 5 9 * 1 6 3 5 9 * 1 3 6 5 9 * 1 3 5 6 9 * 第二轮结束 9不参与排序,6 从第一位转移到最后一位 * 1 3 5 6 9 * 1 3 5 6 9 * 1 3 5 6 9 * 第三轮结束,6 9 不参与排序 * 1 3 5 6 9 * 1 3 5 6 9 * 第四轮结束 5 6 9不参与排序 * 1 3 5 6 9 * 第五轮结束 3 5 6 9 不参与移动排序 * https://blog.csdn.net/hansionz/article/details/80822494 */ public class BubblingSort { public static void main(String[] args) throws Exception { Scanner cin = new Scanner(System.in); int n = cin.nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = cin.nextInt(); } System.out.println("开始排序"); System.out.println("排序结果:"); // for (int i : sort1(arr)) { // System.out.print(i + " "); // } // for (int i : sort2(arr)) { // System.out.print(i + " "); // } for (int i : sort3(arr)) { System.out.print(i + " "); } } /** * 优化1 使用flag 辅助 可达到最佳O(n)时间复杂度 * * @param arr * @return */ public static int[] sort1(int[] arr) { for (int i = 0, len = arr.length - 1, flag = 0; i < len; i++) { for (int j = 0; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j + 1]; arr[j + 1] = arr[j]; arr[j] = temp; flag = 1; } } if (flag == 0) { // 如果比较数组就是排序好的,那就不用继续排序 return arr; } } return arr; } /** * 使用服务k记录最后移位的位置 * * @param arr * @return */ public static int[] sort2(int[] arr) { int pos = 0;// 记录最后一次交换的位置 for (int i = 0, len = arr.length - 1, k = arr.length - 1, flag = 0; i < len; i++) { // k 第一次赋值只用了一次 for (int j = 0; j < k; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j + 1]; arr[j + 1] = arr[j]; arr[j] = temp; flag = 1; // 标记进行过至少一次的交换元素 pos = j; } } if (flag == 0) { // 如果比较数组就是排序好的,那就不用继续排序 return arr; } k = pos; } return arr; } /** * 一次排序决定两个值,,正向扫描找到最大值放到最后,反向扫描找到最小值放到最前面 * * @param arr * @return */ public static int[] sort3(int[] arr) { int i = 0; int j = 0; int n = 0;//同时找最大最小值需要连个下标遍历 int flag = 0; int pos = 0;//用来记录最后一次交换的位置 int k = arr.length - 1; for (i = 0; i < arr.length - 1; i++) {// 确定排序趟数 pos = 0; flag = 0; // 正向寻找最大值 for (j = n; j < k; j++) { if (arr[j] > arr[j + 1]) { int tep = arr[j + 1]; arr[j + 1] = arr[j]; arr[j] = tep; flag = 1; // 标记进行过至少一次的交换元素 pos = j; // 交换元素,记录最后一次交换的位置 } } if (flag == 0) { // 如果比较数组就是排序好的,那就不用继续排序 return arr; } k = pos;// 下次比较到记录位置即可 // 反向寻找最小值 for (j = k; j > n; j--) { int tep = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = tep; flag = 1; } n++; if (flag == 0) { // 如果比较数组就是排序好的,那就不用继续排序 return arr; } } return arr; } }