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

冒泡排序:
就是按索引逐次比较相邻的两个元素,如果大于/小于(取决于需要升序排还是降序排),则置换,否则不做改变
这样一轮下来,比较了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

public class BubbleSort {
  public static void main(String[] args) {
    int len = 10;
    int[] ary = new int[len];
    Random random = new Random();
    for (int j = 0; j < len; j++) {
      ary[j] = random.nextInt(1000);
    } 

    System.out.println("-------排序前------");
    for (int j = 0; j < ary.length; j++) {
      System.out.print(ary[j] + " ");
    }
    /*
     * 升序, Asc1和Asc2优化了内部循环的比较次数,比较好
     * 总的比较次数:
     *   Asc1、Asc2:(1+n-1)/2*(n-1) ==> n/2*(n-1) ==> n*(n-1)/2 ==>(n^2-n)/2
     *   Asc: n^2-n
     */
//   orderAsc(ary);
//   orderAsc2(ary);
    orderAsc1(ary); 

    //降序,只需要把判断大小于 置换一下 

  } 

  static void orderAsc(int[] ary) {
    int count = 0;//比较次数
    int len = ary.length;
    for (int j = 0; j < len; j++) {//外层固定循环次数
      for (int k = 0; k < len - 1; k++) {//内层固定循环次数
        if (ary[k] > ary[k + 1]) {
          ary[k] = ary[k + 1] + (ary[k + 1] = ary[k]) * 0;//一步交换
          /* 交换两个变量值
           * a=a+b
           * b=a-b
           * a=a-b
           */
        }
        count++;
      }
    }
    System.out.println("\n-----orderAsc升序排序后------次数:" + count);
    for (int j = 0; j < len; j++) {
      System.out.print(ary[j] + " ");
    }
  } 

  static void orderAsc1(int[] ary) {
    int count = 0;//比较次数
    int len = ary.length;
    for (int j = 0; j < len; j++) {//外层固定循环次数
      for (int k = len - 1; k > j; k--) {//内层从多到少递减比较次数
        if (ary[k] < ary[k - 1]) {
          ary[k] = ary[k - 1] + (ary[k - 1] = ary[k]) * 0;//一步交换
        }
        count++;
      }
    }
    System.out.println("\n-----orderAsc1升序排序后------次数:" + count);
    for (int j = 0; j < len; j++) {
      System.out.print(ary[j] + " ");
    }
  } 

  static void orderAsc2(int[] ary) {
    int count = 0;//比较次数
    int len = ary.length;
    for (int j = len - 1; j > 0; j--) {//外层固定循环次数
      /*
       * k < j; 总的比较次数=(n^2-n)/2
       */
      for (int k = 0; k < j; k++) {//内层从多到少递减比较次数
        if (ary[k] > ary[k + 1]) {
          ary[k] = ary[k + 1] + (ary[k + 1] = ary[k]) * 0;//一步交换
        }
        count++;
      }
    }
    System.out.println("\n-----orderAsc2升序排序后------次数:" + count);
    for (int j = 0; j < len; j++) {
      System.out.print(ary[j] + " ");
    }
  }
}

打印

-------排序前------
898 7 862 286 879 660 433 724 316 737
-----orderAsc1升序排序后------次数:45
7 286 316 433 660 724 737 862 879 898

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

public class Bubble_CocktailSort {
  public static void main(String[] args) {
    int len = 10;
    int[] ary = new int[len];
    Random random = new Random();
    for (int j = 0; j < len; j++) {
      ary[j] = random.nextInt(1000);
    }
    /*
     * 交换次数最小也是1次,最大也是(n^2-n)/2次
     */
//   ary=new int[]{10,9,8,7,6,5,4,3,2,1}; //测试交换次数
//   ary=new int[]{1,2,3,4,5,6,7,8,10,9}; //测试交换次数
    System.out.println("-------排序前------");
    for (int j = 0; j < ary.length; j++) {
      System.out.print(ary[j] + " ");
    } 

    orderAsc1(ary);
//   orderAsc2(ary); 

    //降序,只需要把判断大小于 置换一下 

  } 

  static void orderAsc1(int[] ary) {
    int compareCount = 0;//比较次数
    int changeCount = 0;//交换次数
    int len = ary.length;
    int left = 0, right = len -1, tl, tr;
    while (left < right) {//外层固定循环次数
      tl = left + 1;
      tr = right - 1;
      for (int k = left; k < right; k++) {//内层从多到少递减比较次数, 从左向右
        if (ary[k] > ary[k + 1]) {//前大于后, 置换
          ary[k] = ary[k + 1] + (ary[k + 1] = ary[k]) * 0;//一步交换
          changeCount++;
          tr = k; //一轮中最后一比较的时候,将k所在索引赋给tr, tr表示以后比较的结束索引值, 从左向右比后,k表示左边的索引
        }
        compareCount++;
      }
      right = tr;
      for (int k = right; k > left; k--) {//内层从多到少递减比较次数, 从右向左
        if (ary[k] < ary[k - 1]) {//后小于前 置换
          ary[k] = ary[k - 1] + (ary[k - 1] = ary[k]) * 0;//一步交换
          changeCount++;
          tl = k; //一轮中最后一比较的时候,将k所在索引赋给tl, tl表示以后比较的开始索引值, 从向右向左比后,k表示右边的索引
        }
        compareCount++;
      }
      left = tl;
    }
    System.out.println("\n-----orderAsc1升序排序后------比较次数:" + compareCount + ", 交换次数:" + changeCount);
    for (int j = 0; j < len; j++) {
      System.out.print(ary[j] + " ");
    }
  } 

  //跟orderAsc1的思路没有区别
  static void orderAsc2(int[] ary) {
    int compareCount = 0;//比较次数
    int changeCount = 0;//交换次数
    int len = ary.length;
    int l = 0, r = len -1, tl, tr;
    for (; l < r; ) {//外层固定循环次数
      tl = l + 1;
      tr = r - 1;
      /*
       * 从左向右比,将大的移到后面
       */
      for (int k = l; k < r; k++) {
        if (ary[k] > ary[k + 1]) {
          int temp = ary[k] + ary[k + 1];
          ary[k + 1] = temp - ary[k + 1];
          ary[k] = temp - ary[k + 1];
          changeCount++;
          tr = k;
        }
        compareCount++;
      }
      r = tr;
      /*
       * 从右向左比,将小的移到前面
       */
      for (int k = r; k > l; k--) {
        if (ary[k] < ary[k - 1]) {
          int temp = ary[k] + ary[k - 1];
          ary[k - 1] = temp - ary[k - 1];
          ary[k] = temp - ary[k - 1];
          changeCount++;
          tl = k;
        }
        compareCount++;
      }
      l = tl;
    }
    System.out.println("\n-----orderAsc2升序排序后------比较次数:" + compareCount + ", 交换次数:" + changeCount);
    for (int j = 0; j < len; j++) {
      System.out.print(ary[j] + " ");
    }
  }
}

打印

-------排序前------
783 173 53 955 697 839 201 899 680 677
-----orderAsc1升序排序后------比较次数:34, 交换次数:22
53 173 201 677 680 697 783 839 899 955
(0)

相关推荐

  • 用java实现冒泡排序算法

    冒泡排序的算法分析与改进 交换排序的基本思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止. 应用交换排序基本思想的主要排序方法有:冒泡排序和快速排序. 复制代码 代码如下: public class BubbleSort implements SortUtil.Sort{ public void sort(int[] data) { int temp; for(int i=0;i<data.length;i++){ for(int j=data.le

  • 深入Java冒泡排序与选择排序的区别详解

    冒泡排序它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.代码如下: 复制代码 代码如下: public class nums {     public static void main(String[] args){         int []nums = {5,4,3,2,1};         for(int i = 0; i < nums.length; i++){        

  • Java中的数组排序方式(快速排序、冒泡排序、选择排序)

    1.使用JavaApi文档中的Arrays类中的sort()进行快速排序 复制代码 代码如下: import java.util.Arrays; public class TestOne{ public static void main(String [] args){ int [] array={2,0,1,4,5,8}; Arrays.sort(array);//调用Arrays的静态方法Sort进行排序,升序排列 for(int show:array){ System.out.printl

  • java冒泡排序算法代码

    复制代码 代码如下: /** * 原理: * 进行n次循环,每次循环从后往前对相邻两个元素进行比较,小的往前,大的往后 *  * 时间复杂度: * 平均情况:O(n^2) * 最好情况:O(n) * 最坏情况:O(n^2) * * 稳定性:稳定 **/public class 冒泡排序 { public int[] bubbleSort(int[] a, int n) {        for (int i = 0; i < n; i++) {            int flag = 0; 

  • 冒泡排序算法原理及JAVA实现代码

    冒泡排序法:关键字较小的记录好比气泡逐趟上浮,关键字较大的记录好比石块下沉,每趟有一块最大的石块沉底. 算法本质:(最大值是关键点,肯定放到最后了,如此循环)每次都从第一位向后滚动比较,使最大值沉底,最小值上升一次,最后一位向前推进(即最后一位刚确定的最大值不再参加比较,比较次数减1) 复杂度: 时间复杂度 O(n2) ,空间复杂度O(1) JAVA源代码(成功运行,需要Date类) 复制代码 代码如下: public static void bubbleSort(Date[] days) { 

  • Java经典算法汇总之冒泡排序

    原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后.重复第一趟步骤,直至全部排序完成. 举例说明:要排序数组:int[]arr={6,3,8,2,9,1}; 第一趟排序: 第一次排序:6和3比较,6大于3,交换位置:368291 第二次排序:6和8比较,6小于8,不交换位置:36

  • 冒泡排序的原理及java代码实现

    概述 冒泡排序是一种简单的排序算法.它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的开始. 简单点说,就是: 冒泡排序是將比較大的數字沉在数组的后面(可以理解为下面),较小的浮在前面(上面). 直观释义图: 步骤 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元

  • java数组排序示例(冒泡排序、快速排序、希尔排序、选择排序)

    快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现. 冒泡法是运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来. 选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组. 插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序. 复制代码 代码如下: package com.firewolf.sort; public class MySort { /**  * @param args  */ public s

  • java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述

    算法是在有限步骤内求解某一问题所使用的一组定义明确的规则.通俗点说,就是计算机解题的过程.在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法.前者是推理实现的算法,后者是操作实现的算法. 一个算法应该具有以下五个重要的特征: 1.有穷性: 一个算法必须保证执行有限步之后结束: 2.确切性: 算法的每一步骤必须有确切的定义: 3.输入:一个算法有0个或多个输入,以刻画运算对象的初始情况: 4.输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果.没有输出的算法是毫无意义的:

  • Java实现冒泡排序算法及对其的简单优化示例

    原理 冒泡排序大概是所有程序员都会用的算法,也是最熟悉的算法之一. 它的思路并不复杂: 设现在要给数组arr[]排序,它有n个元素. 1.如果n=1:显然不用排了.(实际上这个讨论似乎没什么必要) 2.如果n>1: (1)我们从第一个元素开始,把每两个相邻元素进行比较,如果前面的元素比后面的大,那么在最后的结果里面前者肯定排在后面.所以,我们把这两个元素交换.然后进行下两个相邻的元素的比较.如此直到最后一对元素比较完毕,则第一轮排序完成.可以肯定,最后一个元素一定是数组中最大的(因为每次都把相对

随机推荐