排序算法是最基本最常用的算法,不同的排序算法在不同的场景或应用中会有不同的表现,我们需要对各种排序算法熟练才能将它们应用到实际当中,才能更好地发挥它们的优势 。今天,来总结下各种排序算法 。
下面这个表格总结了各种排序算法的复杂度与稳定性:

文章插图
各种排序算法复杂度比较.png
冒泡排序冒泡排序可谓是最经典的排序算法了,它是基于比较的排序算法,时间复杂度为O(n^2),其优点是实现简单,n较小时性能较好 。
- 算法原理
- 相邻的数据进行两两比较,小数放在前面,大数放在后面,这样一趟下来,最小的数就被排在了第一位,第二趟也是如此,如此类推,直到所有的数据排序完成
- c++代码实现
void bubble_sort(int arr[], int len){ for (int i = 0; i < len - 1; i++) { for (int j = len - 1; j > i; j--) { if (arr[j] < arr[j - 1]) { int temp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = temp; } } }}选择排序
- 算法原理
- 先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾 。以此类推,直到所有元素均排序完毕 。
- c++代码实现
void select_sort(int arr[], int len){ for (int i = 0; i < len; i++) { int index = i; for (int j = i + 1; j < len; j++) { if (arr[j] < arr[index]) index = j; } if (index != i) { int temp = arr[i]; arr[i] = arr[index]; arr[index] = temp;} }}插入排序
- 算法原理
- 将数据分为两部分,有序部分与无序部分,一开始有序部分包含第1个元素,依次将无序的元素插入到有序部分,直到所有元素有序 。插入排序又分为直接插入排序、二分插入排序、链表插入等,这里只讨论直接插入排序 。它是稳定的排序算法,时间复杂度为O(n^2)
- c++代码实现
void insert_sort(int arr[], int len){ for (int i = 1; i < len; i ++) { int j = i - 1; int k = arr[i]; while (j > -1 && k < arr[j] ) { arr[j + 1] = arr[j]; j --; } arr[j + 1] = k; }}快速排序
- 算法原理
- 快速排序是目前在实践中非常高效的一种排序算法,它不是稳定的排序算法,平均时间复杂度为O(nlogn),最差情况下复杂度为O(n^2) 。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 。
- c++代码实现
void quick_sort(int arr[], int left, int right){ if (left < right) { int i = left, j = right, target = arr[left]; while (i < j) { while (i < j && arr[j] > target) j--; if (i < j) arr[i++] = arr[j]; while (i < j && arr[i] < target) i++; if (i < j) arr[j] = arr[i]; } arr[i] = target; quick_sort(arr, left, i - 1); quick_sort(arr, i + 1, right); }}归并排序
- 算法原理
- 归并排序具体工作原理如下(假设序列共有n个元素):
- 将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素
- 将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
- 重复步骤2,直到所有元素排序完毕
- 归并排序是稳定的排序算法,其时间复杂度为O(nlogn),如果是使用链表的实现的话,空间复杂度可以达到O(1),但如果是使用数组来存储数据的话,在归并的过程中,需要临时空间来存储归并好的数据,所以空间复杂度为O(n)
- c++代码实现
void merge(int arr[], int temp_arr[], int start_index, int mid_index, int end_index){ int i = start_index, j = mid_index + 1; int k = 0; while (i < mid_index + 1 && j < end_index + 1) { if (arr[i] > arr[j]) temp_arr[k++] = arr[j++]; else temp_arr[k++] = arr[i++]; } while (i < mid_index + 1) { temp_arr[k++] = arr[i++]; } while (j < end_index + 1) temp_arr[k++] = arr[j++]; for (i = 0, j = start_index; j < end_index + 1; i ++, j ++) arr[j] = temp_arr[i];}void merge_sort(int arr[], int temp_arr[], int start_index, int end_index){ if (start_index < end_index) { int mid_index = (start_index + end_index) / 2; merge_sort(arr, temp_arr, start_index, mid_index); merge_sort(arr, temp_arr, mid_index + 1, end_index); merge(arr, temp_arr, start_index, mid_index, end_index); }}堆排序二叉堆
二叉堆是完全二叉树或者近似完全二叉树,满足两个特性
- 父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值
推荐阅读
-
LG电子|LG关闭手机业务一周年!老外点评:真正的创新者 太遗憾了
-
-
#徐丽婷讲趣事#现在事业如日中天,她17年前靠给李咏砸金蛋为生,
-
-
-
ACG次元饭|火影忍者:高招木叶丸细节爆料,技能召唤猿魔棒,可能有几个
-
吃姜的好处和坏处都有哪些?我把姜切丝炒菜吃,每次炒菜都放很多姜在里面,吃了有好处吗?
-
社会热点访谈|数万士兵面临绝境,现在撤兵还来得及!印军唯一退路突然被切断
-
-
陕汽X6000上市、奔驰Actros要国产,重卡圈大事件盘点
-
如果让你一天除睡觉外的时间中有两个小时不看手机,你会有怎么样的感受,反正我已经难受死了……
-
数据|秦淮数据正式登陆纳斯达克 获近20倍超额认购
-
数据库迁移:从 SQL Server 到 PostgreSQL
-
-
上官婉儿:真正有魅力的女人,能征服男人,更能征服女人
-
快科技 Z Flip不要贴膜:否则保修失效,三星提示Galaxy
-
中国新闻网|安倍将视察灾区,日本熊本县等地暴雨致70人死亡
-
「球星工厂」却说出惊人言论:2万人去看球没问题,德国名宿自曝曾感染新冠
-
节目|Yamy风波后做客直播节目 “胜利在望”疑似回应解约纠纷
-