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、最后,复制一些冒泡排序的基本知识:
时间复杂度
 
 
  
  和记录移动次数 
 
 
  
  均达到最小值: 
  
  

  ,     

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

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

   趟排序。每趟排序要进行     

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

 
   

 
   

 
   

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










