要求

  • 能够用自己语言描述冒泡排序算法
  • 能够手写冒泡排序代码
  • 了解一些冒泡排序的优化手段

    算法描述

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

    算法实现

    1. public static void bubble(int[] a) {
    2. for (int j = 0; j < a.length - 1; j++) {//一共会经历多少次冒泡
    3. // 一轮冒泡
    4. boolean swapped = false; // 是否发生了交换
    5. for (int i = 0; i < a.length - 1 - j; i++) {//每次遍历会经过多少次比较交换
    6. System.out.println("比较次数" + i);
    7. if (a[i] > a[i + 1]) {
    8. Utils.swap(a, i, i + 1);
    9. swapped = true;
    10. }
    11. }
    12. System.out.println("第" + j + "轮冒泡"
    13. + Arrays.toString(a));
    14. if (!swapped) {
    15. break;
    16. }
    17. }
    18. }
  • 优化点1:每经过一轮冒泡,内层循环就可以减少一次
  • 优化点2:如果某一轮冒泡没有发生交换,则表示所有数据有序,可以结束外层循环

    进一步优化

    1. public static void bubble_v2(int[] a) {
    2. int n = a.length - 1;
    3. while (true) {
    4. int last = 0; // 表示最后一次交换索引位置
    5. for (int i = 0; i < n; i++) {
    6. System.out.println("比较次数" + i);
    7. if (a[i] > a[i + 1]) {
    8. Utils.swap(a, i, i + 1);
    9. last = i;
    10. }
    11. }
    12. n = last;
    13. System.out.println("第轮冒泡"
    14. + Arrays.toString(a));
    15. if (n == 0) {
    16. break;
    17. }
    18. }
    19. }
    每轮冒泡时,最后一次交换索引可以作为下一轮冒泡的比较次数,如果这个值为零,表示整个数组有序,直接退出外层循环即可。