• java 冒泡排序


    **算法描述**

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

    根据描述,第一轮冒泡代码:数组共有8个元素,需要比较7次

    1. public static void main(String[] args) {
    2. int[] a = {5, 9, 7, 4, 1, 3, 2, 8};
    3. // 一轮冒泡
    4. for (int i = 0; i < a.length - 1; i++) {
    5. System.out.println("比较次数:" + i);
    6. if (a[i] > a[i + 1]) {
    7. swap(a, i, i + 1);
    8. }
    9. }
    10. System.out.println("第一轮:" + Arrays.toString(a));
    11. }
    12. public static void swap(int[] a, int i, int j) {
    13. int t = a[i];
    14. a[i] = a[j];
    15. a[j] = t;
    16. }
    17. 控制台输出:
    18. 比较次数0
    19. 比较次数1
    20. 比较次数2
    21. 比较次数3
    22. 比较次数4
    23. 比较次数5
    24. 比较次数6
    25. 第一轮:[5, 7, 4, 1, 3, 2, 8, 9]

    外层加上比较轮数

    1. public static void main(String[] args) {
    2. int[] a = {5, 9, 7, 4, 1, 3, 2, 8};
    3. for (int k=0;k-1;k++) {
    4. System.out.println("第" + k + "轮冒泡");
    5. // 冒泡
    6. for (int i = 0; i < a.length - 1; i++) {
    7. System.out.println("比较次数:" + i);
    8. if (a[i] > a[i + 1]) {
    9. swap(a, i, i + 1);
    10. }
    11. }
    12. System.out.println("第"+ k +"轮:" + Arrays.toString(a));
    13. }
    14. }
    15. public static void swap(int[] a, int i, int j) {
    16. int t = a[i];
    17. a[i] = a[j];
    18. a[j] = t;
    19. }
    20. 控制台输出:
    21. 0轮冒泡
    22. 比较次数:0
    23. 比较次数:1
    24. 比较次数:2
    25. 比较次数:3
    26. 比较次数:4
    27. 比较次数:5
    28. 比较次数:6
    29. 0轮:[5, 7, 4, 1, 3, 2, 8, 9]
    30. 1轮冒泡
    31. 比较次数:0
    32. 比较次数:1
    33. 比较次数:2
    34. 比较次数:3
    35. 比较次数:4
    36. 比较次数:5
    37. 比较次数:6
    38. 1轮:[5, 4, 1, 3, 2, 7, 8, 9]
    39. 2轮冒泡
    40. 比较次数:0
    41. 比较次数:1
    42. 比较次数:2
    43. 比较次数:3
    44. 比较次数:4
    45. 比较次数:5
    46. 比较次数:6
    47. 2轮:[4, 1, 3, 2, 5, 7, 8, 9]
    48. 3轮冒泡
    49. 比较次数:0
    50. 比较次数:1
    51. 比较次数:2
    52. 比较次数:3
    53. 比较次数:4
    54. 比较次数:5
    55. 比较次数:6
    56. 3轮:[1, 3, 2, 4, 5, 7, 8, 9]
    57. 4轮冒泡
    58. 比较次数:0
    59. 比较次数:1
    60. 比较次数:2
    61. 比较次数:3
    62. 比较次数:4
    63. 比较次数:5
    64. 比较次数:6
    65. 4轮:[1, 2, 3, 4, 5, 7, 8, 9]
    66. 5轮冒泡
    67. 比较次数:0
    68. 比较次数:1
    69. 比较次数:2
    70. 比较次数:3
    71. 比较次数:4
    72. 比较次数:5
    73. 比较次数:6
    74. 5轮:[1, 2, 3, 4, 5, 7, 8, 9]
    75. 6轮冒泡
    76. 比较次数:0
    77. 比较次数:1
    78. 比较次数:2
    79. 比较次数:3
    80. 比较次数:4
    81. 比较次数:5
    82. 比较次数:6
    83. 6轮:[1, 2, 3, 4, 5, 7, 8, 9]

    排序优化1

    发现每轮冒泡的比较次数都是7次,实际上,第一轮冒泡排序后,9到了最右侧,第二轮冒泡排序只需要比较6次,第三轮冒泡再少1次,只需比较5次。。。

    改进一下代码,随着比较轮数的增加,每轮比较次数减少

    1. public static void main(String[] args) {
    2. int[] a = {5, 9, 7, 4, 1, 3, 2, 8};
    3. for (int k=0;k-1;k++) {
    4. System.out.println("第" + k + "轮冒泡");
    5. // 冒泡
    6. for (int i = 0; i < a.length - 1 - k; i++) {
    7. System.out.println("比较次数:" + i);
    8. if (a[i] > a[i + 1]) {
    9. swap(a, i, i + 1);
    10. }
    11. }
    12. System.out.println("第"+ k +"轮:" + Arrays.toString(a));
    13. }
    14. }
    15. public static void swap(int[] a, int i, int j) {
    16. int t = a[i];
    17. a[i] = a[j];
    18. a[j] = t;
    19. }
    20. 控制台输出:
    21. 0轮冒泡
    22. 比较次数:0
    23. 比较次数:1
    24. 比较次数:2
    25. 比较次数:3
    26. 比较次数:4
    27. 比较次数:5
    28. 比较次数:6
    29. 0轮:[5, 7, 4, 1, 3, 2, 8, 9]
    30. 1轮冒泡
    31. 比较次数:0
    32. 比较次数:1
    33. 比较次数:2
    34. 比较次数:3
    35. 比较次数:4
    36. 比较次数:5
    37. 1轮:[5, 4, 1, 3, 2, 7, 8, 9]
    38. 2轮冒泡
    39. 比较次数:0
    40. 比较次数:1
    41. 比较次数:2
    42. 比较次数:3
    43. 比较次数:4
    44. 2轮:[4, 1, 3, 2, 5, 7, 8, 9]
    45. 3轮冒泡
    46. 比较次数:0
    47. 比较次数:1
    48. 比较次数:2
    49. 比较次数:3
    50. 3轮:[1, 3, 2, 4, 5, 7, 8, 9]
    51. 4轮冒泡
    52. 比较次数:0
    53. 比较次数:1
    54. 比较次数:2
    55. 4轮:[1, 2, 3, 4, 5, 7, 8, 9]
    56. 5轮冒泡
    57. 比较次数:0
    58. 比较次数:1
    59. 5轮:[1, 2, 3, 4, 5, 7, 8, 9]
    60. 6轮冒泡
    61. 比较次数:0
    62. 6轮:[1, 2, 3, 4, 5, 7, 8, 9]

    查看控制台输出,在第4轮冒泡排序后,数组已经有序了,就没有必要再进行第5、第6轮排序,

    如何减少不必要的冒泡次数?

    当某一轮的冒泡排序没有发生交换,那就说明,整个数组已经有序了

    改进代码

    1. public static void main(String[] args) {
    2. int[] a = {5, 9, 7, 4, 1, 3, 2, 8};
    3. for (int k=0;k-1;k++) {
    4. System.out.println("第" + k + "轮冒泡");
    5. // 冒泡
    6. boolean swapped = false; // 是否发生了交换
    7. for (int i = 0; i < a.length - 1 - k; i++) {
    8. System.out.println("比较次数:" + i);
    9. if (a[i] > a[i + 1]) {
    10. swap(a, i, i + 1);
    11. swapped = true;
    12. }
    13. }
    14. System.out.println("第"+ k +"轮:" + Arrays.toString(a));
    15. if (!swapped) {
    16. break;
    17. }
    18. }
    19. }
    20. public static void swap(int[] a, int i, int j) {
    21. int t = a[i];
    22. a[i] = a[j];
    23. a[j] = t;
    24. }
    25. 控制台输出:
    26. 0轮冒泡
    27. 比较次数:0
    28. 比较次数:1
    29. 比较次数:2
    30. 比较次数:3
    31. 比较次数:4
    32. 比较次数:5
    33. 比较次数:6
    34. 0轮:[5, 7, 4, 1, 3, 2, 8, 9]
    35. 1轮冒泡
    36. 比较次数:0
    37. 比较次数:1
    38. 比较次数:2
    39. 比较次数:3
    40. 比较次数:4
    41. 比较次数:5
    42. 1轮:[5, 4, 1, 3, 2, 7, 8, 9]
    43. 2轮冒泡
    44. 比较次数:0
    45. 比较次数:1
    46. 比较次数:2
    47. 比较次数:3
    48. 比较次数:4
    49. 2轮:[4, 1, 3, 2, 5, 7, 8, 9]
    50. 3轮冒泡
    51. 比较次数:0
    52. 比较次数:1
    53. 比较次数:2
    54. 比较次数:3
    55. 3轮:[1, 3, 2, 4, 5, 7, 8, 9]
    56. 4轮冒泡
    57. 比较次数:0
    58. 比较次数:1
    59. 比较次数:2
    60. 4轮:[1, 2, 3, 4, 5, 7, 8, 9]
    61. 5轮冒泡
    62. 比较次数:0
    63. 比较次数:1
    64. 5轮:[1, 2, 3, 4, 5, 7, 8, 9]

    查看控制台,发现少了第6轮冒泡;在第4轮的时候,3、2交换位置,在第5轮的时候,发现没有进行交换,退出循环

    换个有序数组,效果更明显

    1. public static void main(String[] args) {
    2. int[] a = {1, 2, 3, 4, 5, 7, 8, 9};
    3. for (int k=0;k-1;k++) {
    4. System.out.println("第" + k + "轮冒泡");
    5. // 冒泡
    6. boolean swapped = false; // 是否发生了交换
    7. for (int i = 0; i < a.length - 1 - k; i++) {
    8. System.out.println("比较次数:" + i);
    9. if (a[i] > a[i + 1]) {
    10. swap(a, i, i + 1);
    11. swapped = true;
    12. }
    13. }
    14. System.out.println("第"+ k +"轮:" + Arrays.toString(a));
    15. if (!swapped) {
    16. break;
    17. }
    18. }
    19. }
    20. public static void swap(int[] a, int i, int j) {
    21. int t = a[i];
    22. a[i] = a[j];
    23. a[j] = t;
    24. }
    25. 控制台输出:
    26. 0轮冒泡
    27. 比较次数:0
    28. 比较次数:1
    29. 比较次数:2
    30. 比较次数:3
    31. 比较次数:4
    32. 比较次数:5
    33. 比较次数:6
    34. 0轮:[1, 2, 3, 4, 5, 7, 8, 9]

    查看控制台,比较了7次,但是未发生交换,对于有序数组,经过一轮冒泡即可确定其为有序数组

    * 优化点1:每经过一轮冒泡,内层循环就可以减少一次
    * 优化点2:如果某一轮冒泡没有发生交换,则表示所有数据有序,可以结束外层循环

    排序优化2

    记录下来,每轮比较,最后一次交换位置的数组索引

    1. public static void main(String[] args) {
    2. int[] a = {5, 9, 7, 4, 1, 3, 2, 8};
    3. int n = a.length - 1;
    4. for (int k = 0; k < a.length - 1; k++) {
    5. System.out.println("第" + k + "轮冒泡");
    6. int last = 0; // 表示最后一次交换索引位置
    7. for (int i = 0; i < n; i++) {
    8. System.out.println("比较次数" + i);
    9. if (a[i] > a[i + 1]) {
    10. swap(a, i, i + 1);
    11. last = i;
    12. }
    13. }
    14. n = last;
    15. System.out.println("第" + k + "轮冒泡" + Arrays.toString(a));
    16. if (n == 0) {
    17. break;
    18. }
    19. }
    20. }
    21. public static void swap(int[] a, int i, int j) {
    22. int t = a[i];
    23. a[i] = a[j];
    24. a[j] = t;
    25. }
    26. 控制台输出:
    27. 0轮冒泡
    28. 比较次数0
    29. 比较次数1
    30. 比较次数2
    31. 比较次数3
    32. 比较次数4
    33. 比较次数5
    34. 比较次数6
    35. 0轮冒泡[5, 7, 4, 1, 3, 2, 8, 9]
    36. 1轮冒泡
    37. 比较次数0
    38. 比较次数1
    39. 比较次数2
    40. 比较次数3
    41. 比较次数4
    42. 比较次数5
    43. 1轮冒泡[5, 4, 1, 3, 2, 7, 8, 9]
    44. 2轮冒泡
    45. 比较次数0
    46. 比较次数1
    47. 比较次数2
    48. 比较次数3
    49. 2轮冒泡[4, 1, 3, 2, 5, 7, 8, 9]
    50. 3轮冒泡
    51. 比较次数0
    52. 比较次数1
    53. 比较次数2
    54. 3轮冒泡[1, 3, 2, 4, 5, 7, 8, 9]
    55. 4轮冒泡
    56. 比较次数0
    57. 比较次数1
    58. 4轮冒泡[1, 2, 3, 4, 5, 7, 8, 9]
    59. 5轮冒泡
    60. 比较次数0
    61. 5轮冒泡[1, 2, 3, 4, 5, 7, 8, 9]

    * 优化点:每轮冒泡时,最后一次交换索引可以作为下一轮冒泡的比较次数,如果这个值为零,表示整个数组有序,直接退出外层循环即可

  • 相关阅读:
    echarts 设置 折线图
    Pytest框架中fixture功能详解
    如何按照洁净区不同等级选择不同流量的粒子计数器设备?
    “创能源之新、享绿色未来” 数境“三星堆杯”能源装备智能化绿色化创新大赛启动...
    磁场发生器EM1电磁铁的主要技术参数
    matlab 电机仿真平台GUI
    学习react 笔记一
    vue优化之如何管理系统变量
    微服务学习第十一节
    vue结合openlayers根据返回的经纬度坐标完成锚地标记、绘制多边形区域
  • 原文地址:https://blog.csdn.net/hfaflanf/article/details/125987394