数据结构与算法第九章
排序算法稳定性:若元素\(i,j满足key_i=key_j,i<j\),排序后\(i在j前面\),则称此排序算法稳定。
内排序,外排序:内排序指排序期间数据元素全部存放在内存的排序。
直接插入排序
第\(i-1\)趟:插入第\(i\)个元素时,前\(i-1\)个元素已排好序,将其排序码与前面元素的排序码从后往前顺次比较,进行插入,并移动已排序好的元素。
最好情况:每趟比较1次,移动0次。
最坏情况:比较次数与元素移动次数均为\(O(n^2)\)
是稳定排序算法。
折半插入排序
在插入\(V_i\)时,采取折半搜索寻找插入位置。能优化比较次数为\(O(n\log n)\),但移动次数最差仍可达到\(O(n^2)\)
希尔排序
(1)选取\(Gap\),将序列分为\(\displaystyle Gap\)组,每一组中包括\(a_i,a_{i+gap},\cdots,a_{i+j\cdot gap},i\in[1,gap],i+j\cdot gap\le n\)
(2)对组间元素进行插入排序。完成后\(Gap=Gap/2\)
(3)重复操作(2),直到当前操作完成且\(Gap=1\)
算法时间复杂度为\(O(n^{1.25})(n^{1.25}\sim 1.6n^{1.25})\),不稳定排序算法。
快速排序
(1)任取待排序元素序列某元素为基准,按其排序码大小,将整个元素序列划分为左右两个子序列,左侧排序码小于等于基准元素排序码,右侧则大于
(2)基准元素应当排在其中间,即确定了最终安放位置
(3)对两个子序列重复进行(1)
快速排序算法时间复杂度取决于递归树高度
算法最优时间复杂度\(O(n\log n)\),最差时间复杂度\(O(n^2)\)
选择排序
(1)在未排序元素中选出排序码最小的元素
(2)若不是此未排序元素序列的第一个,将二者交换,重复(1)
时间复杂度为\(O(n^2)\)
锦标赛排序
(1)将\(n\)个元素的排序码作为叶节点,两两比较得到父亲结点,最后将形成一共有\(2n-1\)个结点的完全二叉树,称此为胜者树。
(2)输出root
(3)再沿胜者路径到达叶结点,即此元素本身结点,将其清空(置为INF或-INF),再向上比较得到新胜者树,回到(2)
胜者树高度为\(\lceil \log_2n\rceil\),构建胜者树:\(O(n)\),更新胜者树与输出结果:\(O(n\log n)\),总时间复杂度\(O(n\log n)\)
是稳定的排序算法,需要使用较多额外存储:\(O(n)\)
堆排序
(1)根据初始数据,利用堆调整算法siftdown形成初始堆
(2)输出堆顶,将堆顶元素与待排序元素最后一位进行交换,此时为堆中第\(n\)号元素
(3)再对前\(n-1\)个元素进行siftdown操作,回到(2)
需要升序排序则构建最大堆。
算法时间复杂度为\(O(n\log n)\),空间复杂度为\(O(1)\),是不稳定排序算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
| 排序方法 | 最好比较次数 | 最差比较次数 | 最好移动次数 | 最差移动次数 | 稳定性 | 最好附加存储 | 最差附加存储 |
|---|---|---|---|---|---|---|---|
| 直接插入排序 | \(O(n)\) | \(O(n^2)\) | 0 | \(O(n^2)\) | Y | 1 | 1 |
| 折半插入排序 | \(O(n\log n)\) | \(O(n\log n)\) | 0 | \(O(n^2)\) | Y | 1 | 1 |
| 冒泡排序 | \(O(n)\) | \(O(n^2)\) | 0 | \(O(n^2)\) | Y | 1 | 1 |
| 快速排序 | \(O(n\log n)\) | \(O(n^2)\) | 小于\(O(n\log n)\) | \(O(n^2)\) | N | \(O(n\log n)\) | \(O(n)\) |
| 简单选择排序 | \(O(n^2)\) | \(O(n^2)\) | 0 | \(O(n)\) | N | 1 | 1 |
| 锦标赛排序 | \(O(n\log n)\) | \(O(n\log n)\) | \(O(n\log n)\) | \(O(n\log n)\) | Y | \(O(n)\) | \(O(n)\) |
| 堆排序 | \(O(n\log n)\) | \(O(n\log n)\) | \(O(n\log n)\) | \(O(n\log n)\) | N | 1 | 1 |
| 归并排序 | \(O(n\log n)\) | \(O(n\log n)\) | \(O(n\log n)\) | \(O(n\log n)\) | Y | \(O(n)\) | \(O(n)\) |