1. 程式人生 > >插入、選擇、冒泡、梳排序性能比較

插入、選擇、冒泡、梳排序性能比較

數值 min 程序 ack 間隙 per end str ber

雖然標題中的排序算法往往被認為是低效率的算法.但並不意味著這些算法完全沒有可取之處。本次不再探討這些算法的基本原理,僅僅比較算法的性能,並貼出實現這些算法的源代碼:

還是先肝代碼吧(手動狗頭):

# include"iostream"
# include "vector"
# include "ctime"
# include "cstdlib" 
using namespace std;
void insert_sort(vector<int> & );
void ChooseSort(vector<int> &);
void BubbleSort(vector<int> &); void CombSort(vector<int> & ); int main() { const int MAX_NUMBER = 3000;//生成的隨機數的個數 const int MIN_VALUE = 1; //隨機數值的下界 const int MAX_VALUE = 20000;//隨機數值的上界 vector<int> a; a.reserve(MAX_NUMBER);//預先分配內存你,預防叠代器的失效。否則內存搬移,叠代器容易失效
// 采用控制臺輸入的方式 //int temp; //while (cin >> temp) //{ // a.push_back(temp); // if (cin.get() == ‘\n‘) //註意這種用法,用的很多。 // { // break; // } //} //采用隨機數生成法。 srand((unsigned)time(NULL));//根據時鐘生成不同的種子,保證每次運行程序產生不同的隨機數 for (int i = 1; i <= MAX_NUMBER; i++) {
int temp; temp = (rand() % (MAX_VALUE - MIN_VALUE + 1)) + MIN_VALUE;//生成[MIN_VALUE,MAX_VALUE]之間的整數隨機數 a.push_back(temp); } //cout << "The initial order: "; 數據量太大,不適合輸出 //vector<int>::iterator ia = a.begin(); //for (; ia != a.end(); ia++) //{ // cout << *ia << " "; //} //cout << endl; vector<int> b(a); vector<int> c(a); vector<int> d(a); //show the initial order of the vector //cout << "The initial order before Sorting : "; //vector<int> ::iterator ia = a.begin(); //for (; ia != a.end(); ia++) //{ //cout << *ia << " "; //} //cout << endl; // 插入排序測試 clock_t start, finish; double runtime; start = clock(); insert_sort(a); finish = clock(); runtime = (double)(finish - start) / CLOCKS_PER_SEC; cout << "The time of Insert Sort algorithm is:" << runtime << "s" << endl; // 選擇排序測試 start = clock(); ChooseSort(b); finish = clock(); runtime = (double)(finish - start) / CLOCKS_PER_SEC; cout << "The time of Choose Sort algorithm is:" << runtime << "s" << endl; // 冒泡排序測試 start = clock(); BubbleSort(c); finish = clock(); runtime = (double)(finish - start) / CLOCKS_PER_SEC; cout << "The time of Bubble Sort algorithm is:" << runtime << "s" << endl; // 梳排序測試 start = clock(); CombSort(d); finish = clock(); runtime = (double)(finish - start) / CLOCKS_PER_SEC; cout << "The time of Comb Sort algorithm is:" << runtime << "s" << endl; //cout << "The new order after Comb Sorting : "; //vector<int> ::iterator id = d.begin(); //for (; id != d.end(); id++) //{ // cout << *id << " "; //} //cout << endl; system("pause"); return 0; } //插入排序 void insert_sort( vector<int> & sort_a) ///註意,采用vector<int> 是可以作為參數進行傳遞的,那麽是否可以作為返回類型使用呢? { int a_size ,temp; a_size = sort_a.size(); for (int i = 1,j; i < a_size; i++)//註意,將j放在這裏聲明,不要放在下一個循環中聲明,否則會造成多次聲明?(但是作用域沒變,多次聲明應該被禁止,所以沒有多次聲明?) { temp = sort_a[i]; for (j = i; (j > 0) && (sort_a[j - 1] > temp); j--)//這裏先後順序的差別,導致了數組的越界, { sort_a[j] = sort_a[j-1]; } sort_a[j] = temp; } //return sort_a;//說明可以將vector<int> 本身作為函數的返回值使用,但是需要清楚的是:返回的時候,內存實際上發生了局部變量復制,所以是否考慮返回引用??? } //選擇排序 void ChooseSort(vector<int> & sort_a) { int a_size,MinNum; a_size = sort_a.size(); for (int i = 0, j; i < a_size; i++) { int Loc = i; MinNum = sort_a[i];//本質是隨機叠代器的使用 //temp = sort_a[i]; for (j = i+1; j < a_size; j++) { if (sort_a[j] < MinNum) { MinNum = sort_a[j]; Loc = j; } } //sort_a[i] = MinNum;//用於交換,但是本身自帶的函數可以實現 //sort_a[Loc] = temp; if (i != Loc) { swap(sort_a[i], sort_a[Loc]);//vector自帶的東西 } } } //冒泡排序 void BubbleSort(vector<int> & sort_a) { int a_size; a_size = sort_a.size(); for (int j = 0; j < a_size-1; j++) { for (int i = 0; i < a_size - 1-j; i++) { if (sort_a[i]>sort_a[i + 1]) swap(sort_a[i], sort_a[i + 1]); } } } //梳排序 void CombSort(vector<int> & sort_a) { int step,j,k; step = sort_a.size(); while ((step = int(step / 1.3)) >0) { for (j = sort_a.size() - 1; j >= step; j--) { k = j - step; if (sort_a[j] < sort_a[k]) { swap(sort_a[j], sort_a[k]); } } } }

補充:由於之前對梳排序未做任何的說明,在此簡要的說明一下梳排序:梳排序的本質仍然是冒泡排序,差異在於,梳排序的冒泡對象並不是相鄰元素,而是距離為step的元素,而step是一個變量(右大變小),即“梳子”間隙逐漸變小。而梳排序叠代的終止條件是:當step變成1,即退化為傳統的冒泡後,執行一次,則得到正確的順序

在此,我們給出上述四種排序的測試結果:

不同排序算法性能比較
5000 10000 15000 20000
插入 0.839s 3.427 7.716s 13.648s
選擇 0.667s 2.276 5.321s 9.208s
冒泡 2.320s 9.177 20.823s 36.542s
0.016s 0.042 0.057s 0.079s

上述表格中的(5000,10000,....表示數據規模,程序中隨機生成的隨機數,我們可以看到,測試結果表明:按照速度而言,算法的時間性能上:梳>>選擇>插入>冒泡(>表示優於);(冒泡辣雞實錘(開個玩笑)),即算法性能上,梳排序的性能要遠遠高於其他的方式。我們通過觀察算法執行時間,梳狀排序時間復雜度並不是O(n2),似乎比這個時間復雜度要低,實際上也的確如此。而對於插入,選擇,冒泡而言,盡管時間復雜度都是O(n2),但是畢竟還是有所差異,當數據更莫更大的時候,這種差異將會更加明顯,但是無疑,冒泡排序時間復雜度真的高,冒泡排序的最好,最差,平均時間復雜度都是相同的,都是O(n2)。

疑問:在學習梳排序的時候,見有描述稱其為不穩定的算法,不知為何不穩定,望高手能予指點,謝謝!!

插入、選擇、冒泡、梳排序性能比較