在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

Java实现冒泡排序与双向冒泡排序算法的代码示例

2016-7-29 15:41| 发布者: zhangjf| 查看: 547| 评论: 0

摘要: 冒泡排序: 就是按索引逐次比较相邻的两个元素,如果大于/小于(取决于需要升序排还是降序排),则置换,否则不做改变 这样一轮下来,比较了n-1次,n等于元素的个数;n-2, n-3 ... 一直到最后一轮,比较了1次 所以比 ...

冒泡排序:
就是按索引逐次比较相邻的两个元素,如果大于/小于(取决于需要升序排还是降序排),则置换,否则不做改变
这样一轮下来,比较了n-1次,n等于元素的个数;n-2, n-3 ... 一直到最后一轮,比较了1次
所以比较次数为递减:从n-1 到 1
那么总的比较次数为:1+2+3+...+(n-1), 以等差公式计算:(1+n-1)/2*(n-1) ==> n/2*(n-1) ==> (n^2-n) * 0.5
用大O表示算法的时间复杂度:O(n^2) , 忽略了系数0.5和常数-n

  1. public class BubbleSort {
  2. public static void main(String[] args) {
  3. int len = 10;
  4. int[] ary = new int[len];
  5. Random random = new Random();
  6. for (int j = 0; j < len; j++) {
  7. ary[j] = random.nextInt(1000);
  8. }
  9. System.out.println("-------排序前------");
  10. for (int j = 0; j < ary.length; j++) {
  11. System.out.print(ary[j] + " ");
  12. }
  13. /*
  14. * 升序, Asc1和Asc2优化了内部循环的比较次数,比较好
  15. * 总的比较次数:
  16. * Asc1、Asc2:(1+n-1)/2*(n-1) ==> n/2*(n-1) ==> n*(n-1)/2 ==>(n^2-n)/2
  17. * Asc: n^2-n
  18. */
  19. // orderAsc(ary);
  20. // orderAsc2(ary);
  21. orderAsc1(ary);
  22. //降序,只需要把判断大小于 置换一下
  23. }
  24. static void orderAsc(int[] ary) {
  25. int count = 0;//比较次数
  26. int len = ary.length;
  27. for (int j = 0; j < len; j++) {//外层固定循环次数
  28. for (int k = 0; k < len - 1; k++) {//内层固定循环次数
  29. if (ary[k] > ary[k + 1]) {
  30. ary[k] = ary[k + 1] + (ary[k + 1] = ary[k]) * 0;//一步交换
  31. /* 交换两个变量值
  32. * a=a+b
  33. * b=a-b
  34. * a=a-b
  35. */
  36. }
  37. count++;
  38. }
  39. }
  40. System.out.println("n-----orderAsc升序排序后------次数:" + count);
  41. for (int j = 0; j < len; j++) {
  42. System.out.print(ary[j] + " ");
  43. }
  44. }
  45. static void orderAsc1(int[] ary) {
  46. int count = 0;//比较次数
  47. int len = ary.length;
  48. for (int j = 0; j < len; j++) {//外层固定循环次数
  49. for (int k = len - 1; k > j; k--) {//内层从多到少递减比较次数
  50. if (ary[k] < ary[k - 1]) {
  51. ary[k] = ary[k - 1] + (ary[k - 1] = ary[k]) * 0;//一步交换
  52. }
  53. count++;
  54. }
  55. }
  56. System.out.println("n-----orderAsc1升序排序后------次数:" + count);
  57. for (int j = 0; j < len; j++) {
  58. System.out.print(ary[j] + " ");
  59. }
  60. }
  61. static void orderAsc2(int[] ary) {
  62. int count = 0;//比较次数
  63. int len = ary.length;
  64. for (int j = len - 1; j > 0; j--) {//外层固定循环次数
  65. /*
  66. * k < j; 总的比较次数=(n^2-n)/2
  67. */
  68. for (int k = 0; k < j; k++) {//内层从多到少递减比较次数
  69. if (ary[k] > ary[k + 1]) {
  70. ary[k] = ary[k + 1] + (ary[k + 1] = ary[k]) * 0;//一步交换
  71. }
  72. count++;
  73. }
  74. }
  75. System.out.println("n-----orderAsc2升序排序后------次数:" + count);
  76. for (int j = 0; j < len; j++) {
  77. System.out.print(ary[j] + " ");
  78. }
  79. }
  80. }
复制代码

打印

  1. -------排序前------
  2. 898 7 862 286 879 660 433 724 316 737
  3. -----orderAsc1升序排序后------次数:45
  4. 7 286 316 433 660 724 737 862 879 898
复制代码

双向冒泡排序
冒泡排序_鸡尾酒排序、就是双向冒泡排序。
此算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序,外层比较左右边界l 内层一个循环从左向右比,取高值置后;一个循环从右向左,取低值置前;
效率上,O(N^2), 不比普通的冒泡快

  1. public class Bubble_CocktailSort {
  2. public static void main(String[] args) {
  3. int len = 10;
  4. int[] ary = new int[len];
  5. Random random = new Random();
  6. for (int j = 0; j < len; j++) {
  7. ary[j] = random.nextInt(1000);
  8. }
  9. /*
  10. * 交换次数最小也是1次,最大也是(n^2-n)/2次
  11. */
  12. // ary=new int[]{10,9,8,7,6,5,4,3,2,1}; //测试交换次数
  13. // ary=new int[]{1,2,3,4,5,6,7,8,10,9}; //测试交换次数
  14. System.out.println("-------排序前------");
  15. for (int j = 0; j < ary.length; j++) {
  16. System.out.print(ary[j] + " ");
  17. }
  18. orderAsc1(ary);
  19. // orderAsc2(ary);
  20. //降序,只需要把判断大小于 置换一下
  21. }
  22. static void orderAsc1(int[] ary) {
  23. int compareCount = 0;//比较次数
  24. int changeCount = 0;//交换次数
  25. int len = ary.length;
  26. int left = 0, right = len -1, tl, tr;
  27. while (left < right) {//外层固定循环次数
  28. tl = left + 1;
  29. tr = right - 1;
  30. for (int k = left; k < right; k++) {//内层从多到少递减比较次数, 从左向右
  31. if (ary[k] > ary[k + 1]) {//前大于后, 置换
  32. ary[k] = ary[k + 1] + (ary[k + 1] = ary[k]) * 0;//一步交换
  33. changeCount++;
  34. tr = k; //一轮中最后一比较的时候,将k所在索引赋给tr, tr表示以后比较的结束索引值, 从左向右比后,k表示左边的索引
  35. }
  36. compareCount++;
  37. }
  38. right = tr;
  39. for (int k = right; k > left; k--) {//内层从多到少递减比较次数, 从右向左
  40. if (ary[k] < ary[k - 1]) {//后小于前 置换
  41. ary[k] = ary[k - 1] + (ary[k - 1] = ary[k]) * 0;//一步交换
  42. changeCount++;
  43. tl = k; //一轮中最后一比较的时候,将k所在索引赋给tl, tl表示以后比较的开始索引值, 从向右向左比后,k表示右边的索引
  44. }
  45. compareCount++;
  46. }
  47. left = tl;
  48. }
  49. System.out.println("n-----orderAsc1升序排序后------比较次数:" + compareCount + ", 交换次数:" + changeCount);
  50. for (int j = 0; j < len; j++) {
  51. System.out.print(ary[j] + " ");
  52. }
  53. }
  54. //跟orderAsc1的思路没有区别
  55. static void orderAsc2(int[] ary) {
  56. int compareCount = 0;//比较次数
  57. int changeCount = 0;//交换次数
  58. int len = ary.length;
  59. int l = 0, r = len -1, tl, tr;
  60. for (; l < r; ) {//外层固定循环次数
  61. tl = l + 1;
  62. tr = r - 1;
  63. /*
  64. * 从左向右比,将大的移到后面
  65. */
  66. for (int k = l; k < r; k++) {
  67. if (ary[k] > ary[k + 1]) {
  68. int temp = ary[k] + ary[k + 1];
  69. ary[k + 1] = temp - ary[k + 1];
  70. ary[k] = temp - ary[k + 1];
  71. changeCount++;
  72. tr = k;
  73. }
  74. compareCount++;
  75. }
  76. r = tr;
  77. /*
  78. * 从右向左比,将小的移到前面
  79. */
  80. for (int k = r; k > l; k--) {
  81. if (ary[k] < ary[k - 1]) {
  82. int temp = ary[k] + ary[k - 1];
  83. ary[k - 1] = temp - ary[k - 1];
  84. ary[k] = temp - ary[k - 1];
  85. changeCount++;
  86. tl = k;
  87. }
  88. compareCount++;
  89. }
  90. l = tl;
  91. }
  92. System.out.println("n-----orderAsc2升序排序后------比较次数:" + compareCount + ", 交换次数:" + changeCount);
  93. for (int j = 0; j < len; j++) {
  94. System.out.print(ary[j] + " ");
  95. }
  96. }
  97. }
复制代码

打印

  1. -------排序前------
  2. 783 173 53 955 697 839 201 899 680 677
  3. -----orderAsc1升序排序后------比较次数:34, 交换次数:22
  4. 53 173 201 677 680 697 783 839 899 955
复制代码

最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-5-6 12:44

Copyright 2015-2025 djqfx

返回顶部