1、本篇介绍一些优化冒泡排序的方法。


2、一次冒泡的过程其实就是一次确定最值的过程,这个过程中会发生若干次值的交换,反过来想:如果再一次冒泡的过程中完全没有进行过交换操作,那么这一组数据已经是有序的了。当然,这是针对交换相邻元素的标准冒泡算法来说的。


3、根据第2条,优化算法如下:


      //************************************ 
     
 
      // 参数a:数组首地址 
     
 
      // 参数n:数组大小 
     
 
      //************************************ 
     
 
      void  
      BubbleSort1( 
      int 
      * a,  
      int  
      n) 
     
 
      { 
     
 
           
      bool  
      bFlag =  
      true 
      ; 
     
 
           
      for  
      ( 
      int  
      i = 0; i < n - 1; i++) 
     
 
           
      { 
     
 
               
      bFlag =  
      true 
      ; 
     
 
               
      for  
      ( 
      int  
      j = 0; j < n - 1 - i; j++)   
     
 
               
      { 
     
 
                   
      if  
      (a[j] > a[j + 1])     
      // 升序 
     
 
                   
      { 
     
 
                       
      swap(a[j], a[j + 1]); 
     
 
                       
      bFlag =  
      false 
      ; 
     
 
                   
      } 
     
 
               
      } 
     

         
     
 
               
      if  
      (bFlag) 
     
 
               
      { 
     
 
                   
      break 
      ; 
     
 
               
      } 
     

         
     
 
           
      } 
     
 
      } 
     

         
     
 
      void  
      BubbleSort2( 
      int 
      * a,  
      int  
      n) 
     
 
      { 
     
 
           
      bool  
      bFlag =  
      true 
      ; 
     
 
           
      for  
      ( 
      int  
      i = 0; i < n - 1; i++) 
     
 
           
      { 
     
 
               
      bFlag =  
      true 
      ; 
     
 
               
      for  
      ( 
      int  
      j = n - 1; j > i; --j)     
     
 
               
      { 
     
 
                   
      if  
      (a[j] < a[j - 1])     
      // 升序 
     
 
                   
      { 
     
 
                       
      swap(a[j], a[j - 1]); 
     
 
                       
      bFlag =  
      false 
      ; 
     
 
                   
      } 
     
 
               
      } 
     

         
     
 
               
      if  
      (bFlag) 
     
 
               
      { 
     
 
                   
      break 
      ; 
     
 
               
      } 
     
 
           
      } 
     
 
      } 
     

=


4、二次优化,通过记录最后的交换位置,以减少交换次数:


      //************************************ 
     
 
      // 参数a:数组首地址 
     
 
      // 参数n:数组大小 
     
 
      //************************************ 
     
 
      void  
      BubbleSort1( 
      int 
      * a,  
      int  
      n) 
     
 
      { 
     
 
           
      bool  
      bFlag =  
      true 
      ; 
     
 
           
      int  
      nIndex; 
     
 
           
      int  
      nSwap = n - 1; 
     

         
     
 
           
      for  
      ( 
      int  
      i = 0; i < n - 1; i++) 
     
 
           
      { 
     
 
               
      bFlag =  
      true 
      ; 
     
 
               
      nIndex = nSwap; 
     

         
     
 
               
      for  
      ( 
      int  
      j = 0; j < nIndex; j++)  
     
 
               
      { 
     
 
                   
      if  
      (a[j] > a[j + 1])     
      // 升序 
     
 
                   
      { 
     
 
                       
      swap(a[j], a[j + 1]); 
     
 
                       
      bFlag =  
      false 
      ; 
     
 
                       
      nSwap = j; 
     
 
                   
      } 
     
 
               
      } 
     
 
                
     
 
               
      if  
      (bFlag) 
     
 
               
      { 
     
 
                   
      break 
      ; 
     
 
               
      } 
     

         
     
 
           
      } 
     
 
      } 
     

         
     
 
      void  
      BubbleSort2( 
      int 
      * a,  
      int  
      n) 
     
 
      { 
     
 
           
      bool  
      bFlag =  
      true 
      ; 
     
 
           
      int  
      nIndex; 
     
 
           
      int  
      nSwap = 0; 
     

         
     
 
           
      for  
      ( 
      int  
      i = 0; i < n - 1; i++) 
     
 
           
      { 
     
 
               
      bFlag =  
      true 
      ; 
     
 
               
      nIndex = nSwap; 
     

         
     
 
               
      for  
      ( 
      int  
      j = n - 1; j > nIndex; --j)    
     
 
               
      { 
     
 
                   
      if  
      (a[j] < a[j - 1])     
      // 升序 
     
 
                   
      { 
     
 
                       
      swap(a[j], a[j - 1]); 
     
 
                       
      bFlag =  
      false 
      ; 
     
 
                       
      nSwap = j; 
     
 
                   
      } 
     
 
               
      } 
     

         
     
 
               
      if  
      (bFlag) 
     
 
               
      { 
     
 
                   
      break 
      ; 
     
 
               
      } 
     
 
           
      } 
     
 
      } 
=


5、附上一个产生随机数的例子:

 #include "stdafx.h" 
     
 
      #include <iostream> 
     
 
      #include <ctime> 
     
 
      using  
      namespace  
      std; 
     

         
     
 
      int  
      _tmain( 
      int  
      argc, _TCHAR* argv[]) 
     
 
      { 
     
 
           
      // 待排序数的个数 
     
 
           
      const  
      int  
      nCount = 1000; 
     

         
     
 
           
      // 待排序的数 
     
 
           
      int  
      nNum[nCount] = {0}; 
     

         
     
 
           
      // 产生随机数 
     
 
           
      srand 
      ( (unsigned)  
      time 
      (NULL)); 
     
 
           
      for  
      ( 
      int  
      i = 0; i < nCount; i++) 
     
 
           
      { 
     
 
               
      nNum[i] =  
      rand 
      (); 
     
 
           
      } 
     

         
     
 
           
      getchar 
      (); 
     
 
           
      return  
      0; 
     
 
      } 
=


6、最后,复制一些冒泡排序的基本知识:


时间复杂度


排序算法(一)冒泡排序算法3_i++

 和记录移动次数


排序算法(一)冒泡排序算法3_排序算法_02

 均达到最小值:



排序算法(一)冒泡排序算法3_i++_03

 ,

排序算法(一)冒泡排序算法3_排序算法_04


所以,冒泡排序最好的 时间复杂度


排序算法(一)冒泡排序算法3_i++_05

 。

  若初始文件是反序的,需要进行

排序算法(一)冒泡排序算法3_升序_06

 趟排序。每趟排序要进行

排序算法(一)冒泡排序算法3_冒泡排序_07

 次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:


排序算法(一)冒泡排序算法3_冒泡排序_08



排序算法(一)冒泡排序算法3_升序_09



排序算法(一)冒泡排序算法3_升序_10



排序算法(一)冒泡排序算法3_升序_10



算法稳定性


冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。