`

浅谈java中的冒泡排序法

阅读更多

冒泡排序法

 

冒泡排序法其实就是交换排序的一种,即两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。

 

冒泡排序的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复以上过程,直至最终完成排序。由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。(如附件图1)

 

 冒泡排序的基本思想:

将被排序的记录数组 R[1..n] 假定为垂直排列,每个记录 R[i] 看做是重量为 R[i].key 的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组 R 。凡扫描到违反本原则的轻气泡,就使其向上“漂浮”。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
  (1) 初始, R[1..n] 为无序区。
  (2) 第一趟扫描,从无序区底部向上依次比较相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。即依次比较 (R[n],R[n-1])  (R[n-1],R[n-2])  …  (R[2],R[1]); 对于每对气泡 (R[j+1],R[j]),  R[j+1].key<R[j].key, 则交换 R[j+1]  R[j] 的内容。
  第一趟扫描完毕时,最轻的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置 R[1] 上。
  (3) 第二趟扫描,扫描 R[2..n]。扫描完毕时,次轻的气泡飘浮到 R[2] 的位置上 …… 最后,经过 n-1 趟扫描可得到有序区 R[1..n]
  注意:第 i 趟扫描时, R[1..i-1]  R[i..n] 分别为当前的有序区和无序区。扫描仍是从无序区底部向上直至该区顶部。扫描完毕时,该区中最轻气泡漂浮到顶部位置 R[i] 上,结果是 R[1..i] 变为新的有序区。 (如附件图2)

                   

因为每一趟排序都使有序区增加了一个气泡,在经过 n-1 趟排序之后,有序区中就有 n-1 个气泡,而无序区中气泡的重量总是大于等于有序区中气泡的重量,所以整个冒泡排序过程至多需要进行 n-1 趟排序。
  若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足轻者在上,重者在下的原则,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个交换标志exchange, 在每趟排序开始前,先将其置为0。若排序过程中发生了交换,则将其置为1。各趟排序结束时检查 exchange, 若未曾发生过交换则终止算法,不再进行下趟排序。

 

package com.itttop.sort;

 

public class BubbleSort {

 

    public static void main(String[] args) {

 

       int[] R = new int[11];// R(1..10) 是待排序的文件,采用自下向上扫描,对R 做冒泡排序

       int i, j;

       System.out.println("排序前的数列为:\n");

       for (i = 1; i < R.length; i++) {

           R[i] = (int) (Math.random() * 100);

           System.out.print(R[i] + "\t");

       }

       int exchange; // 交换标志

       for (i = 1; i < R.length; i++) // 最多做11-1=10 趟排序

       {

           exchange = 0;// 本趟排序开始前,交换标志为0

           for (j = 9; j >= i; j--)

           {

              // 对当前无序区R[i..10] 自下向上扫描

              if (R[j + 1] < R[j])// 交换记录

              {

                  R[0] = R[j + 1]; // R[0] 用于交换,仅做暂存单元

                  R[j + 1] = R[j];

                  R[j] = R[0];

                  exchange = 1; // 发生了交换,故将交换标志置1

              }

           }

           if (exchange == 0)// 本趟排序未发生交换,提前终止算法

           {

              break;

           }

       }

       System.out.println("\n" + "排序后的数列为:\n");

 

       for (int k = 1; k < R.length; k++) {

           System.out.print(R[k] + "\t");

       }

    }

} 

 

测试效果如下:

    排序前的数列为:

          16   67  19  83  40  29  92  26  19  64 
             排序后的数列为:

          16  19   19  26  29  40  64  67  83  92 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics