From fb409031df86d904598abb1b79fbccd32c1888ad Mon Sep 17 00:00:00 2001 From: Didnelpsun <2675350965@qq.com> Date: Thu, 22 Sep 2022 23:03:15 +0800 Subject: [PATCH] Update 9-sort.md --- Data-Structrue/9-sort.md | 57 +++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/Data-Structrue/9-sort.md b/Data-Structrue/9-sort.md index 27edd60..51ef3ec 100644 --- a/Data-Structrue/9-sort.md +++ b/Data-Structrue/9-sort.md @@ -398,6 +398,9 @@ $n$个元素二路归并排序,归并一共要$\log_2n$趟,每次归并时 基数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。 ++ 只能对整数进行排序。 ++ 元素的移动次数与关键字的初始排列次序无关。 + #### 基数的定义 假设长度为$n$的线性表中每个结点$a_j$的关键字由$d$元组$(k_j^{d-1},k_j^{d-2},\cdots,k_j^1,k_j^0)$组成,其中$0\geqslant k_j^i\geqslant r-1\,(0\geqslant i\geqslant d-1)$,其中$r$就是基数。 @@ -473,16 +476,18 @@ $n$个元素二路归并排序,归并一共要$\log_2n$趟,每次归并时 指在排序期间元素全部存放在内存中的排序。除了分配排序,其他的内部排序往往要经过比较和移动。 -算法种类|最好时间复杂度|平均时间复杂度|最好时间复杂度|空间复杂度|是否稳定 -:-----:|:------------:|:----------:|:------------:|:-------:|:------: -直接插入排序|$O(n)$|$O(n^2)$|$O(n^2)$|$O(1)$|是 -冒泡排序|$O(n)$|$O(n^2)$|$O(n^2)$|$O(1)$|是 -简单选择排序|$O(n^2)$|$O(n^2)$|$O(n^2)$|$O(1)$|否 -希尔排序|$?$|$?$|$?$|$O(1)$|否 -快速排序|$O(n\log_2n)$|$O(n\log_2n)$|$O(n^2)$|$O(\log_2n)$|否 -堆排序|$O(n\log_2n)$|$O(n\log_2n)$|$O(n\log_2n)$|$O(1)$|否 -二路归并排序|$O(n\log_2n)$|$O(n\log_2n)$|$O(n\log_2n)$|$O(n)$|是 -基数排序|$O(d(n+r))$|$O(d(n+r))$|$O(d(n+r))$|$O(r)$|是 +算法种类|最好时间复杂度|平均时间复杂度|最好时间复杂度|空间复杂度|是否稳定|趟数 +:------:|:------------:|:------------:|:------------:|:--------:|:------:|:--: +直接插入排序|$O(n)$|$O(n^2)$|$O(n^2)$|$O(1)$|是|$n-1$ +希尔排序|$?$|$?$|$?$|$O(1)$|否|$s$ +简单选择排序|$O(n^2)$|$O(n^2)$|$O(n^2)$|$O(1)$|否|$n-1$ +快速排序|$O(n\log_2n)$|$O(n\log_2n)$|$O(n^2)$|$O(\log_2n)$|否|初始序列 +冒泡排序|$O(n)$|$O(n^2)$|$O(n^2)$|$O(1)$|是|初始序列 +堆排序|$O(n\log_2n)$|$O(n\log_2n)$|$O(n\log_2n)$|$O(1)$|否|初始序列 +二路归并排序|$O(n\log_2n)$|$O(n\log_2n)$|$O(n\log_2n)$|$O(n)$|是|$\log_2n$ +基数排序|$O(d(n+r))$|$O(d(n+r))$|$O(d(n+r))$|$O(r)$|是|$r$ + ++ 每趟排序结束都至少能够确定一个元素最终位置的方法:选择、交换。(插入和归并则不行) ## 外部排序 @@ -544,29 +549,51 @@ $k$路平衡归并:最多只能有$k$个段归并为一个,需要一个输 27 12 1 17 2 9 11 4 ``` -传统方法从$k$个归并段选出一个最大或最小元素需要对比关键字$k-1$次,而使用$k$路归并的败者树只需要对比关键字$\lceil\log_2k\rceil$次(败者树层数)。 +传统方法从$k$个归并段选出一个最大或最小元素需要对比关键字$k-1$次,而使用$k$路归并的败者树只需要对比关键字$\lceil\log_2k\rceil$次(败者树层数,不包括成功结点)。 + +构建败者树还是需要$n-1$次对比。 ### 置换选择排序 +如果内存工作区只能容纳$l$个记录,则初始归并段也只能包含$l$条记录,若文件共有$n$条记录,则初始归并段的数量为$r=\lceil n/l\rceil$。 + 用于构建更长的初始归并段,从而减少归并次数。 假设初始始待排文件为$FI$,初始归并段输出文件为$FO$,内存工作区为$WA$,$FO$和$WA$的初始状态为空,$WA$可容纳$w$个记录。置换选择算法的步骤如下: -1. 从$FI$输入$w$个记录到工作区$WA$。 +1. 从$FI$输入$w$记录到工作区$WA$。 2. 从$WA$中选出其中关键字取最小值的记录,记为$MINIMAX$记录。 3. 将$MINIMAX$记录输出到$FO$中去。 4. 若$FI$不空,则从$FI$输入下一个记录到$WA$中。 5. 从$WA$中所有关键字比$MINIMAX$记录的关键字大的记录中选出最小关键字记录,作为新的$MINIMAX$记录。 -6. 重复步骤三到五,直至在$WA$中选不出新的$MINIMAX$记录为止,由此得到一个初始归并段,输出一个归并段的结束标志到$FO$中去。准备输出新的归并段。 +6. 重复步骤三到五,如果新输入到$FI$的关键字小于$MINIMAX$的值,则驻留在$WA$中,直至在$WA$中填满选不出新的$MINIMAX$记录为止,由此得到一个初始归并段,输出一个归并段的结束标志到$FO$中去。准备输出新的归并段。 7. 重复步骤二到六,直至$WA$为空。由此得到全部初始归并段。 此时输出的初始归并段可以超过$WA$,且初始归并段长度是不一定相等的。 -如$FI$:$4,6,9,7,13,11,14,22,30,2,3,19,20,17,23,5,36,12,18,21,39$,$WA$长度为$3$,$FO$为$4,6,7,9,11,13,14,16,22,30$、$2,3,10,17,19,20,23,36$、$1,5,12,18,21,39$。 +如$FI$:$4,6,9,7,13,11,14,22,30,2,3,19,20,17,1,23,5,36,12,18,21,39$,$WA$长度为$3$,$FO$为$4,6,7,9,11,13,14,16,22,30$、$2,3,10,17,19,20,23,36$、$1,5,12,18,21,39$。 + +^表示中断当前归并段,下一个$FI$开启新的归并段;√表示该$WA$值超过$MINIMAX$值,不能输出到当前$FO$归并段中,只能等待输出到下一个归并段。 + +FI|4|6|9|7|13|11|14|22|30|2|3|19||20 +:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-: +WA1|4|4|4|7|7|11|11|22|22|22|3√|3√|3|3 +WA2||6|6|6|13|13|13|13|30|30|30|19√|19|19 +WA3|||9|9|9|9|14|14|14|2√|2√|2√|2|20 +MINIMAX|||4|6|7|9|11|13|14|22|30|30|2|3 +FO|||4|6|7|9|11|13|14|22|30|^|2|3 + +FI|17|1|23|5|36|12||18|21|39|||| +:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-: +WA1|17|1√|1√|1√|1√|1√|1|18|18|18 +WA2|19|19|23|23|36|12√|12|12|12|39|39|39 +WA3|20|20|20|5√|5√|5√|5|5|21|21|21 +MINIMAX|17|19|20|23|36|36|1|5|12|18|21|39 +FO|17|19|20|23|36|^|1|5|12|18|21|39|^ ### 最佳归并树 -因为每个归并段的长度不同,所以归并的次序比较重要。 +因为现实中的每个归并段的长度不同,所以归并的次序比较重要。 #### 最佳归并树的衡量