排序算法应该是所有学习编程语言的新手第一个接触到的算法,本文主要介绍这些排序方法在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种常见的排序方法。