(1.3.4)交换排序:冒泡排序

来源:互联网 发布:骤风租赁软件 编辑:程序博客网 时间:2024/06/09 17:28

交换排序:两两比较待排序记录的关键码,若是逆序,则交换,直到无逆序。其中最简单的交换排序是:冒泡排序。

冒泡排序(Bubble Sort,也叫起泡排序):不断地比较相邻的记录,若是不满足排序要求,则交换。

交换时,可从前向后,也可从后向前。看一个从前向后的排序过程:

原序列 12  3   45  33  6

下标   0   1   2   3   4

第一趟:

       3   12  45  33  6  (3,12交换)

       3   12  45  33  6  (12,45不用交换)

       3   12  33  45  6  (45,33交换)

       3   12  33  6   45 (45,6交换)

第二趟:

       3   12  33  6  45  (3,12不用交换)

       3   12  33  6  45  (12,33不用交换)

       3   12  6   33 45  (33,6交换)

第三趟:

       3   12  6   33 45  (3,12不用交换)

       3   6   12  33 45  (12,6交换)

第四趟:

       3   6   12  33 45  (3,6不用交换)

结束。以上过程非常之详尽,相信你一定懂了。

代码一:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. void BubbleSort10(int a[], int n)  //从左向右   
  2. {  
  3.     if (a && n > 1)  
  4.     {  
  5.         int i,j;  
  6.         for (i = 1; i < n; i++)     //最多只需进行n-1趟排序    
  7.         for (j = 0; j < n - i ; j++)  
  8.         {  
  9.             if (a[j] > a[j+1])  
  10.             Swap(a[j], a[j+1]);  
  11.         }   
  12.     }  
  13. }  
  14. void BubbleSort11(int a[], int n)  //从右向左   
  15. {  
  16.     if (a && n > 1)  
  17.     {  
  18.         int i,j;  
  19.         for (i = 1; i < n; i++)   
  20.         for (j = n - 1; j>=i; j--)  
  21.         {  
  22.             if (a[j - 1] > a[j])  
  23.             Swap(a[j - 1], a[j]);  
  24.         }         
  25.     }  
  26. }  


继续思考:若是在某一趟排序中,无元素交换,是不是表明已全部有序了呢?

是的!既然如此,下一趟排序就不用进行了。

针对代码一,给出优化的代码二:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. void BubbleSort20(int a[], int n)  //从左向右   
  2. {  
  3.     if (a && n > 1)  
  4.     {  
  5.         int i,j = n-1;  
  6.         bool flag = true;  
  7.         while(flag)  
  8.         {  
  9.             flag = false;  
  10.             for (i = 0; i < j; i++)  
  11.             if (a[i] > a[i+1])  
  12.             {  
  13.                 Swap(a[i], a[i+1]);  
  14.                 flag = true;  
  15.             }  
  16.             j--;   
  17.         }  
  18.     }  
  19. }  
  20. void BubbleSort21(int a[], int n)  //从右向左   
  21. {  
  22.     if (a && n > 1)  
  23.     {  
  24.         int i,j = 1;  
  25.         bool flag = true;  
  26.         while(flag)  
  27.         {  
  28.             flag = false;  
  29.             for (i = n - 1; i >= j; i--)  
  30.             if (a[i - 1] > a[i])  
  31.             {  
  32.                 Swap(a[i - 1], a[i]);  
  33.                 flag = true;  
  34.             }  
  35.             j++;   
  36.         }  
  37.     }  
  38. }  

再思考:下一趟排序向右(或向左)的最远位置,只是简单的减一吗?可否更高效?

有的,记录上一趟排序时交换元素的最远距离,下一趟排序最远只到这个位置。

针对代码二,给出优化的代码三:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. void BubbleSort30(int a[], int n)  //从左向右   
  2. {  
  3.     if (a && n > 1)  
  4.     {  
  5.         int i,k,j = n-1;  
  6.         bool flag = true;  
  7.         while(flag)  
  8.         {  
  9.             flag = false;  
  10.             k = 0;  
  11.             for (i = 0; i < j; i++)  
  12.             {  
  13.                 if (a[i] > a[i+1])  
  14.                 {  
  15.                     Swap(a[i], a[i+1]);  
  16.                     flag = true;  
  17.                     k = i;  
  18.                 }  
  19.             }  
  20.             if (k == 0)  
  21.                 break;  
  22.             j = k;   
  23.         }  
  24.     }   
  25. }  
  26. void BubbleSort31(int a[], int n)   //从右向左   
  27. {  
  28.     if (a && n > 1)  
  29.     {  
  30.         int i,k,j = 1;  
  31.         bool flag = true;  
  32.         while(flag)  
  33.         {  
  34.             flag = false;  
  35.             k = n - 1;  
  36.             for (i = n - 1; i >= j; i--)  
  37.             {  
  38.                 if (a[i - 1] > a[i])  
  39.                 {  
  40.                     Swap(a[i - 1], a[i]);  
  41.                     flag = true;  
  42.                     k = i;  
  43.                 }  
  44.             }  
  45.             if (k == n - 1)  
  46.                 break;  
  47.             j = k;   
  48.         }  
  49.     }   
  50. }  

交换方法的代码是这样:

[cpp] view plaincopy
  1. void Swap(int &a, int &b)  
  2. {  
  3.     if(a!=b)  
  4.     {  
  5.         a^=b;  
  6.         b^=a;  
  7.         a^=b;  
  8.     }  
  9. }  

测试走起……


小结:

冒泡排序是稳定的,但不高效。时间复杂度是O(n^2)。

0 0