排序算法應該是所有學習編程語言的新手第一個接觸到的算法,本文主要介紹這些排序方法在C++中如何實現。
排序算法主要有:
- 選擇排序
- 冒泡排序
- 插入排序
- 快速排序
- 希爾排序
- 桶排序
以下逐一介紹這些排序方法。
1.選擇排序
這種排序方式比較容易理解,利用循環,每次找一個元素放在它最終的位置上,比如先找到最小的元素,放在首位,然后再剩下的元素中找到最小的,依此類推,最終從小到大排好。

1 #include <iostream> 2 #include <cstdlib> 3 #include <algorithm> 4 using namespace std; 5 6 int main() 7 { 8 int n, a[10001], k; 9 cin >> n; 10 for (int i = 0; i < n; i++) 11 { 12 cin >> a[i]; //輸入數據 13 } 14 15 for (int i = 0; i < n; i++) 16 { 17 k = i; // 設置這一次確定哪一位 18 for (int j = i; j < n; j++) //嵌套一個循環,找到最小的那一個 19 { 20 if (a[j] < a[k]) 21 { 22 k = j; 23 } 24 } 25 26 swap(a[i], a[k]); //把這次循環最小的(需要的)搞到前面來,也就是搞到它應該在的位置 27 } 28 29 for (int i = 0; i < n; i++) 30 { 31 cout << a[i] << ' '; //輸出數據 32 } 33 cout << endl; 34 35 system("pause"); 36 return 0; 37 }
2.冒泡排序
這是另一種常見的排序方式,通過對違反順序的相鄰元素進行調整以達成目標,假設需要從小到大進行排序,那么每次循環都會從頭開始比較相鄰兩個元素的大小,小的放在前面,大的放在后面,一輪結束后,最大的元素(泡)便被“冒”到了最后。每次循環都是如此。
在循環中可以加一個終止條件:如果一輪下來后沒有過調整次序,那么說明已經排序完畢,跳出循環即可。

1 #include <iostream> 2 #include <cstdlib> 3 #include <algorithm> 4 using namespace std; 5 6 int main() 7 { 8 int n, a[10001]; 9 bool flag; //用於記錄一次循環中有沒有發生過元素交換 10 11 cin >> n; 12 for (int i = 0; i < n; i++) 13 { 14 cin >> a[i]; //輸入數據 15 } 16 17 for (int i = 1; i < n; i++) //注意這個循環只有(n-1)次 18 { 19 flag = false; //一開始先設置flag為false 20 for (int j = 0 ; j < n - i; j++) 21 { 22 if (a[j] > a[j + 1]) 23 { 24 swap(a[j], a[j + 1]); //相鄰的進行比較,並調整 25 flag = true; 26 } 27 } 28 //cout << a[i] << ' '; 29 if (!flag) //若無調整,則跳出循環 30 break; 31 } 32 33 for (int i = 0; i < n; i++) 34 { 35 cout << a[i] << ' '; //輸出數據 36 } 37 cout << endl; 38 system("pause"); 39 return 0; 40 }
3.插入排序(直接插入排序)
插入排序,顧名思義,是將新的元素插入到原來已經排列好的一組數中。在具體實現時,可以將數組分為兩部分。第一部分是除最后一位的其它所有元素,並且給出一個空間,使得可以讓第二部分中的待插入元素有位置;第二部分是待插入的元素。第一部分排完序后,操作第二部分。
原理流程如下動圖所示(侵刪):
雖然插入排序和選擇排序的時間復雜度一樣,但是插入排序的第二重循環可以提前結束,不需要遍歷到開始位置。尤其是對於已經快要排列好的數組。

1 #include <iostream> 2 #include <cstdlib> 3 #include <algorithm> 4 using namespace std; 5 6 void insertSelectionSort(int arr[], int n) //這種排序不需要用swap交換語句,只需要復制即可 7 { 8 for (int i = 1; i < n; i++) //插入排序在進行時不需要考慮第一個數的情況,一個數,必然有序 9 { 10 int key = arr[i]; //取出待排序的數 11 int j; 12 for (j = i; j > 0 && arr[j - 1] > key; j--) //有兩個限制條件,第二個限制條件使得插入排序比選擇排序高效 13 arr[j] = arr[j - 1]; 14 15 arr[j] = key; 16 } 17 } 18 19 int main() 20 { 21 int n, a[10001]; 22 23 cin >> n; 24 for (int i = 0; i < n; i++) 25 { 26 cin >> a[i]; //輸入數據 27 } 28 29 insertSelectionSort(a, n); 30 31 for (int i = 0; i < n; i++) 32 { 33 cout << a[i] << ' '; //輸出數據 34 } 35 cout << endl; 36 37 system("pause"); 38 return 0; 39 }
4.快速排序
快速排序是一種相當高效的算法,主要采用的分治的思想方法。一次排序過后,確立一個樞軸,放在某個位置,讓左邊的數都小於它,右邊的數都大於它。
主要是搞清一輪探測到底要達成什么目的,上下的只需要遞歸即可。
取一左一右向中間慢慢移動,一旦發現有前大於后,就交換,知道兩者相碰,設置第一個數作為樞軸,開始遞歸。

1 #include <iostream> 2 #include <cstdlib> 3 #include <algorithm> 4 using namespace std; 5 6 void quickSort(int left, int right, int arr[]) 7 { 8 if(left >= right) 9 return; 10 11 int i, j, base; 12 i = left, j = right; 13 base = arr[left]; //取最左邊的數為基准數 14 while (i < j) 15 { 16 while (arr[j] >= base && i < j) 17 j--; 18 while (arr[i] <= base && i < j) 19 i++; 20 if(i < j) 21 swap(arr[i], arr[j]); 22 } 23 24 //基准數歸位 25 arr[left] = arr[i]; 26 arr[i] = base; 27 28 //一輪基本探測已結束 29 30 quickSort(left, i - 1, arr); //遞歸左邊 31 quickSort(i + 1, right, arr); //遞歸右邊 32 } 33 34 int main() 35 { 36 int n, a[10001]; 37 38 cin >> n; 39 for (int i = 0; i < n; i++) 40 { 41 cin >> a[i]; //輸入數據 42 } 43 44 quickSort(0, n - 1, a); 45 46 for (int i = 0; i < n; i++) 47 { 48 cout << a[i] << ' '; //輸出數據 49 } 50 cout << endl; 51 52 system("pause"); 53 return 0; 54 }
5.希爾排序
希爾排序是在不相鄰的元素之間進行交換等操作。
關鍵是增量gap的設置,每次一輪下來之后,gap都要相應地減小,本文給出的例子是變為原來的1/2。對於每一輪,內部都是用插入排序。直到gap最后一次是1時插入排序完,便得到了最終的結果。

1 #include <iostream> 2 #include <cstdlib> 3 #include <algorithm> 4 using namespace std; 5 6 const int Dgap = 2; 7 8 void shellSort(int arr[], int len) 9 { 10 int insertNumber = 0; 11 int gap = len / Dgap; //必須保證此時gap不小於1,否則無法進入while循環 12 while (gap >= 1) 13 { 14 for (int i = gap; i < len; i++) 15 { 16 insertNumber = arr[i]; 17 int j = i; 18 while (j >= gap && insertNumber < arr[j - gap]) 19 { 20 arr[j] = arr[j - gap]; 21 j -= gap; 22 } 23 arr[j] = insertNumber; 24 } 25 gap /= Dgap; 26 } 27 } 28 29 int main() 30 { 31 int n, a[10001]; 32 33 cin >> n; 34 for (int i = 0; i < n; i++) 35 { 36 cin >> a[i]; //輸入數據 37 } 38 39 shellSort(a, n); 40 41 for (int i = 0; i < n; i++) 42 { 43 cout << a[i] << ' '; //輸出數據 44 } 45 cout << endl; 46 47 system("pause"); 48 return 0; 49 }
6.桶排序
桶排序,顧名思義,我們需要放置桶,對於簡單的例子,可以按自然數依次放置,對於難以處理的大型數據,可以考慮“加大”桶放置的種類,使得一個區間內的都可以放進來,再對其中的各個元素進行排序。
下面給出比較簡單的一種情況的思路:先找出輸入數據中最大的數N,設置N+1個桶,遍歷輸入的數組,統計各個桶里裝了多少個,最后遍歷桶,得到排好序的數組。

1 #include <iostream> 2 #include <cstdlib> 3 #include <algorithm> 4 using namespace std; 5 6 int main() 7 { 8 int n, a[10001], bucket[10001], max = 0; 9 10 cin >> n; 11 for (int i = 0; i < n; i++) 12 { 13 cin >> a[i]; //輸入數據 14 } 15 16 for (int i = 0; i < n; i++) 17 { 18 max = (a[i] > max ? a[i] : max); //找到最大的元素 19 } 20 21 for (int i = 0; i < n; i++) 22 { 23 bucket[a[i]]++; //統計各個桶的情況 24 } 25 26 for (int i = 1; i <= max; i++) 27 { 28 if (bucket[i] == 0) 29 continue; 30 else 31 { 32 for (int j = 0; j < bucket[i]; j++) 33 cout << i << ' '; //輸出最后的數列 34 } 35 36 } 37 cout << endl; 38 39 system("pause"); 40 return 0; 41 }
以上便是6種常見的排序方法。