插入排序
| 1.直接插入排序 | 2.折半插入排序 | 3.希尔排序 |
思想 | 比较\插入 每次从无序表中通过比较取出第一个元素,把它插入到有序表的合适位置,插入过程中会产生移动,使有序表仍然有序。(产生的是一个局部的有序序列) | 因为已有序列已经有序,我们不用逐个比较哦,可以通过折半查找,确定位置,然后移动元素腾位子,再进行插入排序 | 1.插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。 2.但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。 |
| 例: 原有序表:(9 15 23 28 37) 20 找插入位置 : (9 15 ^ 23 28 37) 20 新有序表: (9 15 20 23 28 37) |
| 以步长为下标间隔序列为子列,对子列进行直接插入排序, 步长i+1=int(步长i/2) |
空间复杂度 | 仅借助常数个空间的就地排序,O(1) | O(1) | O(1) |
时间复杂度 | O(n²) | 虽然查找次数降低,但是移动次数还是没变,O(n²) | O(n^(1.3—2) |
最好情况 | 已经有序了,只需要比较一次而不需要移动,共n个元素,算法比较n次, 比较的复杂度为O(n); 移动的复杂度为O(1); 则直接插入排序最好情况的复杂度为O(n); | 比较次数约为O(nlog2n): n个元素*树高log2n | 最好情况O(n*log2n) |
最坏的情况 | 有序了,但是与要求序相逆,则第n个元素比较n-1次,第n-1个比较n-2次,……第2个比较1次,第1个符合不用比较,共比较1+2+…+n=(1+n)n/2, 比较的复杂度为O(n²); |
|
|
稳定性 | 稳定 | 稳定 | 不稳定 |
适用性 | 顺序储存/顺序储存 | 需要进行折半随机查找,故仅适合顺序储存,不适合链式 | 需要以步长为界随机查找,故仅顺序储存 |
交换排序
| 1.冒泡排序 | 2.快速排序(递归的,借助栈) |
思想 | 通过比较并且交换,每进行一趟,将确定一个max或者min,放置于其最终位置上.(产生的是一个全局的有序序列) | 选取第一个(严)pivot为基准,通过一趟排序将pivot确定其最终位置,并以此位置为界,将序列划分为两个子序列; 每个子序再次pivot…子序列再再pivot… |
| 例: 原表:(9 125 23 20 37) 目的,升序 第一趟:(9 23 20 37 125) 第二趟:(9 23 20 37 125) 第三趟:(9 20 23 37 125) 第四趟:(9 20 23 37 125) 第五趟:(9 20 23 37 125) |
|
空间复杂度 | O(1) | O(log2n) |
时间复杂度 | O(n²) | O(n²) |
最好情况 | O(n) 已经有序了,比较过后不用交换 | O(nlog2n) 选取的pivot恰为中分元素(平衡划分); |
最坏的情况 | 有序了,但是与要求序相逆; 比较次数n(n-1)/2; 移动次数3n(n-1)/2; O(n²); | O(n²)基本有(逆)序时最坏 ps越有序直接插入排序越好哦~ |
稳定性 | 稳定 | 不稳定 |
适用性 | 顺序储存/链式储存 | 顺序储存 |
选择排序
| 1.简单选择排序 | 2.堆排序 |
思想:选择最值排 | 需要升序:从序列1~n选择一个min与第一个交换位子,最小值就选好啦;从序列2~n选出一个min,交换位置,第二小就选好啦; ……就排序好啦 | 此乃树形选择法;分为小根堆:根节点为小值;大根堆:大值. 顺序储存的树结构; 自下而上检验根与孩子的关系,如果不满足则交换根与孩子的位置;交换后,检验换后子树的关系,不满足则继续调整; |
|
| 插入或者删除节点,也需要检验并重新调整 |
空间复杂度 | O(1) | O(1) |
时间复杂度 | O(n²) 元素间比较次数与序列状态无关,每个元素都要被比较,逃不掉!n(n-1)/2次,故O(n²) | O(nlog2n) 建堆是O(n)n个元素建立; 调整是n-1次,每次调整为O(h)=O(log2n) 则最好最坏平均情况都是O(nlog2n) |
最好情况 | O(n) 已经有序了,比较过后不用交换,移动0次 | O(nlog2n) 选取的pivot恰为中分元素(平衡划分); |
最坏的情况 |
| O(nlog2n) 基本有(逆)序时最坏 ps越有序直接插入排序越好哦~ |
稳定性 | 不稳定 | 不稳定 |
适用性 | 顺序储存(需要进行交换) | 顺序储存 |
稳定性口诀:插\泡\归\基->稳
|
|