排序算法总结
1.冒泡排序
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
算法描述
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成。

void bubble(vector<int> &nums){
int len=nums.size();
bool swap;
for(int i=0;i<len;i++){
swap =false;//优化:如果一趟排序中没有交换位置,则说明元素已经有序
for(int j=1;j<len-i;j++){
if(nums[j-1]>nums[j]){
int temp = nums[j];
nums[j] = nums[j-1];
nums[j-1]=temp;
swap=true;
}
}
if(!swap){
break;
}
}
}
稳定性
在相邻元素相等时,它们并不会交换位置,所以,冒泡排序是稳定排序。
适用场景
冒泡排序思路简单,代码也简单,特别适合小数据的排序。但是,由于算法复杂度较高,在数据量大的时候不适合使用。
代码优化(上面代码已经优化了)
在数据完全有序的时候展现出最优时间复杂度,为O(n)。其他情况下,几乎总是O(n2)O( n^2 )O(n2)。因此,算法在数据基本有序的情况下,性能最好。
要使算法在最佳情况下有O(n)复杂度,需要做一些改进,增加一个swap的标志,当前一轮没有进行交换时,说明数组已经有序,没有必要再进行下一轮的循环了,直接退出。
2.选择排序
选择排序是一种简单直观的排序算法,它也是一种交换排序算法,和冒泡排序有一定的相似度,可以认为选择排序是冒泡排序的一种改进。
算法描述
- 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
- 从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
- 重复第二步,直到所有元素均排序完毕。

void selectSort(vector<int> &arr){
for(int i=0;i<arr.size();i++){
int minIndex = i;
for(int j=i+1;j<arr.size();j++){
if(arr[minIndex]>arr[j]){
minIndex = j;
}
}
if(minIndex!=i){
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex]=temp;
}
}
}
稳定性
用数组实现的选择排序是不稳定的,用链表实现的选择排序是稳定的。
不过,一般提到排序算法时,大家往往会默认是数组实现,所以选择排序是不稳定的。
选择排序为啥不是稳定性排序呢,举个例子:数组 6、7、6、2、8,在对其进行第一遍循环的时候,会将第一个位置的6与后面的2进行交换。此时,就已经将两个6的相对前后位置改变了。因此选择排序不是稳定性排序算法。
适用场景
选择排序实现也比较简单,并且由于在各种情况下复杂度波动小,因此一般是优于冒泡排序的。在所有的完全交换排序中,选择排序也是比较不错的一种算法。但是,由于固有的O(n2)O(n^2)O(n2)复杂度,选择排序在海量数据面前显得力不从心。因此,它适用于简单数据排序。
3.插入排序
插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法描述
- 把待排序的数组分成已排序和未排序两部分,初始的时候把第一个元素认为是已排好序的。
- 从第二个元素开始,在已排好序的子数组中寻找到该元素合适的位置并插入该位置。
- 重复上述过程直到最后一个元素被插入有序子数组中。

void InsertionSort(int *a,int len)
{
for(int i=1;i<len;i++){
int key = a[i];
int j=i-1;
for(;j>=0&&a[j]>key;j--)
{
a[j+1]=a[j];
}
nums[j+1]=key;
}
}
/*
void InsertSort(vector<int> &vec) {
for (int i = 1; i < vec.size(); i++) {
int j = i - 1;
int key = vec[i];
for (; j >= 0 && vec[j] > key; j--) {
vec[j + 1] = vec[j];
}
vec[j + 1] = key;
}
}*/
稳定性
由于只需要找到不大于当前数的位置而并不需要交换,因此,直接插入排序是稳定的排序方法。
适用场景
插入排序由于O(n2)O( n^2 )O(n2)的复杂度,在数组较大的时候不适用。但是,在数据比较少的时候,是一个不错的选择,一般做为快速排序的扩充。
4.归并排序
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
算法描述



被折叠的 条评论
为什么被折叠?



