排序方式 | 算法思想 | 时间复杂度 | 空间复杂度 | |
插入排序 | 直接插入排序 | 每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中(将前面已排好序列中大于当前的全部右移)直到全部记录插入完成。 (若有序则只比较一次,就跳出循环) | O(n^2) | O(1) |
折半插入排序 | 先用折半查找找到应插入的位置,再移动元素。 | |||
希尔排序 | 希尔排序:先将待排序表分割成若干形如 L[i,i +d, i + 2id, i + kd]的“特殊”子表(每间隔d的关键字成一组),对各个子表分别进行直接插入排序。缩小增量d,重复上述过程,直到d=1为止。 | O(n^1.3) O(n^2)最坏 | ||
交换排序 | 冒泡排序 | 从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即A[i-1]>A[i]),则交换它们,直到序列比较完。称这样过程为“一趟”冒泡排序(设置flag,若本趟遍历没有发生交换则说明已经有序) | O(n^2) | |
快速排序 | 基于分治法:在待排序表L[1..n]中任取一个元素pivot作为枢轴(或基准,通常取首元素),通过一趟排序将待排序表划分为独立的两部分 | O(n*递归层数) (与划分是否对称有关) | O(递归层数) 二叉树高度 | |
选择排序 | 简单选择排序 | 每一趟在待排序元素中选取关键字最小的元素加入有序子序列(遍历时不断更新找到当前最小元素,最后交换这趟的最小元素和有序子表的下一个元素) | O(n^2) | O(1) |
堆排序 | 1、建立大/小根堆(根≥左右):把所有非终端结点(在顺序存储的完全二叉树中,非终端结点编号 2、排序:每一趟输出堆顶元素加入有序子序列,将待排序序列中的最后一个元素(堆底元素)送入堆顶(长度减一)并将待排序列再次向下调整保持大/小根堆。 | 调整: O(h)=O(log2n) 总: O(nlog2n) | ||
归并排序 | 分解:将含有n个元素的待排序表分成n/2个元素的子表,采用2路归并算法对两个子表递归地进行排序(归并树) 归并:把两个或多个已经有序的序列(通过比较每个序列当前第一个元素较小者传入总表)合并成一个,只剩一个子表未合并时,可以将该表中剩余元素全部加到总表。(利用辅助数组) 合并:合并两个已排序的子表得到排序结果。 | O(nlog2n) | O(n) | |
基数排序 | 分配:按当前分配标准的取值范围,按顺序分配成辅助队列r个,插入队尾。 搜集:按顺序进行搜集,依次出队。 以下一位为标准继续分配搜集(按关键自位权重递增的次序,对d个关键字位分配搜集)(注意下一位分配时,应当保证上一位排序的稳定性) | O(r) | O(n(r+d)) |
排序方式 | 比较次数与初始状态有关吗 | 是否稳定 | 特点 | |
插入排序 | 直接插入排序 | √ | √ | 1、适用于基本有序和数据量不大的序列 2、每趟排序元素不一定放到其最终位置上 |
折半插入排序 | × | |||
希尔排序 | √ | × | 适用于规模较大的排序 | |
交换排序 | 冒泡排序 | √ | √ | 适用于已经基本有序的序列 |
快速排序 | √ | × | 1、形如树 2、尽量选择可以把数据中分的枢轴元素。 3、快速排序是所有内部排序算法中平均性能最优的排序算法,但不稳定 4、每趟排序元素会放到其最终位置上 | |
选择排序 | 简单选择排序 | × | × | 适用于n较小的序列 |
堆排序 | × | × | 效率较高 | |
归并排序 | × | √ | 1、基于分治思想 2、稳定且效率较高(通常先用直接插入排序求得两个较长子序列,然后两两归并) 3、无论初始序列如何,事件复杂度不变 | |
基数排序 | √ | 适用于: ②每组关键字的取值范围不大,即r较小 |
1111111111WEQH