程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 經典四講貫通C++排序之三 交換排序(1)

經典四講貫通C++排序之三 交換排序(1)

編輯:C++入門知識

我們都知道C++排序方法中,有四種常用方法插入排序希爾排序交換排序以及選擇排序。在前面兩篇文章中,我們介紹了C++兩種排序方法——插入排序和希爾排序,這篇文章我們介紹C++排序的第三種方法——交換排序。本系列文章統一 測試程序

交換排序

基本思想是:兩兩比較待排序記錄的關鍵碼,如果發生逆序,則交換之,直到所有對象都排好為止。

起泡排序

起泡排序是比較相鄰的兩個記錄,逆序則交換。這樣的做法導致小的關鍵碼一層層的浮上來,因此得名。51cto的論壇曾經討論過“冒泡”和“起泡”是不是一個東西,看來這是翻譯惹的禍,英文名都是Bubble Sort,具體寫的時候可以正著排,也可以倒著排。(嚴版是從後往前排,殷版是從前往後排,好在兩本書都翻譯為“起泡排序”,不然就正像某些人得出的結論——一個是從後往前排,一個是從前往後排)

  1. template <class T>  
  2. void BubbleSort(T a[], int N, int& KCN, int& RMN)  
  3. {  
  4. KCN = 0; RMN = 0; bool exchange = true;  
  5. for (int i = 1; i < N && exchange; i++)  
  6. for (int j = N - 1; j >= i; j--)  
  7. {  
  8. exchange = false;  
  9. if (++KCN && a[j - 1] > a[j]) { swap(a[j - 1], a[j]); exchange = true; RMN += 3; }  
  10. }  

需要注意的是,不要寫成下面這個樣子,雖然結果是對的:

  1. template <class T>  
  2. void BubbleSort2(T a[], int N)  
  3. {  
  4. for (int i = 0; i < N; i++)  
  5. for (int j = 1; j < N - i; j++)  
  6. if (a[j - 1] > a[j]) swap(a[j - 1], a[j]);  

測試結果:

  1. Sort ascending N=10000 TimeSpared: 0ms  
  2. KCN=9999 KCN/N=0.9999 KCN/N^2=9.999e-005 KCN/NlogN=0.07525  
  3. RMN=0 RMN/N=0 RMN/N^2=0 RMN/NlogN=0  
  4. Sort randomness N=10000 TimeSpared: 1161ms  
  5. KCN=45409094 KCN/N=4540.91 KCN/N^2=0.454091 KCN/NlogN=341.737  
  6. RMN=71526984 RMN/N=7152.7 RMN/N^2=0.71527 RMN/NlogN=538.294  
  7. Sort descending N=10000 TimeSpared: 1022ms  
  8. KCN=49995000 KCN/N=4999.5 KCN/N^2=0.49995 KCN/NlogN=376.25  
  9. RMN=149985000 RMN/N=14998.5 RMN/N^2=1.49985 RMN/NlogN=1128.75 

可以看出,效率非常的差,還不如直插排序,真不知道為什麼人們對此津津樂道,難道是為了理解快速排序?另外還有一個有趣的現象,雖然逆序的KCN和RMN都比亂序的多,但是逆序花的時間卻比亂序少,從這裡可以看到CPU流水線的作用,這裡可以給我們一個信號,一個真正好的算法需要充分利用硬件的特性。增多記錄數目(N=1000000)時,可以看出,在完全有序的情況下,起泡比直插要好一些,因為此時不需要移動記錄。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved