From ec1de8e8abd7968f8db3f0e4ec2323291c08cc6b Mon Sep 17 00:00:00 2001 From: Didnelpsun <2675350965@qq.com> Date: Sun, 3 Oct 2021 23:17:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data-Structrue/10-sort-ex.md | 46 ++++++++++++++++++++++++++++++++++++ Data-Structrue/10-sort.md | 18 +++++++++----- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/Data-Structrue/10-sort-ex.md b/Data-Structrue/10-sort-ex.md index 5a337c2..456cb10 100644 --- a/Data-Structrue/10-sort-ex.md +++ b/Data-Structrue/10-sort-ex.md @@ -41,3 +41,49 @@ $C.$每次划分后,先处理较短的分区可以减少递归次数 $D.$递归次数与每次划分后得到的分区的处理顺序无关 解:$D$。递归次数与各元素的初始排列有关。若每次划分后分区比较平衡,则递归次数少;若分区才平衡,递归次数多。递归次数与处理顺序是没有关系的。 + +## 选择排序 + +### 简单选择排序 + +**例题** 设线性表中每个元素有两个数据项$k_1$和$k_2$,现对线性表按以下规则进行排序:先看数据项$k_1$,$k_1$值小的元素在前,大的元素在后;在$k_1$值相同的情况下,再看$k_2$,$k_2$值小的在前,大的元素在后。满足这种要求的排序方法是()。 + +$A.$先按$k_1$进行直接插入排序,再按$k_2$进行简单选择排序 + +$B.$先按$k_2$进行直接插入排序,再按$k_1$进行简单选择排序 + +$C.$先按$k_1$进行简单选择排序,再按$k_2$进行直接插入排序 + +$D.$先按$k_2$进行简单选择排序,再按$k_1$进行直接插入排序 + +解:$D$。首先应确定$k_1$、$k_2$的排序顺序,若先排$k_1$再排$k_2$,则排序结果不符合题意,排除选项$A$、$C$。再考虑算法的稳定性,当$k_1$排好序后,再对$k_2$排序,若对$k_2$排序采用的算法是不稳定的,则对于$k_1$相同而$k_2$不同的元素可能会改变相对次序,从而不一定能满足题干中的条件“在$k_1$值相同的情况下,$k_2$值小的元素在前,大的元素在后”。直接插入排序算法是稳定的,而简单选择排序算法是不稳定的,故只能选$D$。 + +### 堆排序 + +**例题** 对关键码序列$\{23,17,72,60,25,8,68,71,52\}$进行堆排序,输出两个最小关键码后的剩余堆是()。 + +$A.\{23,72,60,25,68,71,52\}$ + +$B.\{23,25,52,60,71,72,68\}$ + +$C.\{71,25,23,52,60,72,68\}$ + +$D.\{23,25,68,52,60,72,71\}$ + +解:$D$。筛选法初始建堆为$\{8,17,23,52,25,72,68,71,60\}$,输出$8$后重建的堆为$\{17,25,23,52,60,72,68,71\}$,输出$17$后重建的堆为$\{23,25,68,52,60,72,71\}$。 + +## 归并排序 + +**例题** 下列排序方法中,排序过程中比较次数的数量级与序列初始状态无关的是()。 + +$A.$归并排序 + +$B.$插入排序 + +$c.$快速排序 + +$D.$冒泡排序 + +解:$D$。选择排序和归并排序都与序列初始状态无关。 + + \ No newline at end of file diff --git a/Data-Structrue/10-sort.md b/Data-Structrue/10-sort.md index 827cd1c..8ce099f 100644 --- a/Data-Structrue/10-sort.md +++ b/Data-Structrue/10-sort.md @@ -196,11 +196,15 @@ #### 堆排序的过程 -1. 每一趟将堆顶元素加入子序列(堆顶元素与待排序序列中的最后一个元素交换)。此时后面的这个元素就排序好了。 +每次将未排序记录中选择最值加入已排序序列末尾再调整。 + +1. 每一趟将堆顶元素加入子序列(堆顶元素与待排序序列中的最后一个元素交换)。此时后面的这个元素就排序好了。最右下的元素作为堆顶元素。 2. 此时待排序序列已经不是堆了(堆顶被换成最小或最大的元素),需要将其再次调整为堆(小元素或大元素不断下坠)。 3. 重复步骤一二。 4. 直到$n-1$趟处理后得到有序序列。基于大根堆的堆排序会得到递增序列,而基于小根堆的堆排序会得到递减序列。 +调整堆从右边即序列末尾开始。 + #### 堆排序的性能 堆排序的存储就是它本身,不需要额外的存储空间,要么只需要一个用于交换或临时存放元素的辅助空间。所以空间复杂度为$O(1)$。 @@ -217,11 +221,11 @@ #### 堆的插入 -新元素放到表尾,并与其$\lfloor\dfrac{i}{2}\rfloor$的父结点进行对比,若新元素比父元素更大(大根堆)或更小(小根堆),则二者互换,并保持上升,直到无法上升为止。 +新元素放到表尾,并与其$\lfloor\dfrac{i}{2}\rfloor$的父结点进行对比,若新元素比父元素更大(大根堆)或更小(小根堆),则二者互换,并保持上升,直到无法上升为止。时间复杂度为树高$O(\log_2n)$。 #### 堆的删除 -被删除的元素用堆底元素代替,然后让这个元素不断下坠,直到无法下坠为止。 +被删除的元素用堆底元素代替,然后让这个元素不断下坠,直到无法下坠为止。时间复杂度为树高$O(\log_2n)$。 ## 归并排序 @@ -255,7 +259,7 @@ $n$个元素二路归并排序,归并一共要$\log_2n$趟,每次归并时 ### 基数排序 -计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。 +基数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。 #### 基数的定义 @@ -263,6 +267,8 @@ $n$个元素二路归并排序,归并一共要$\log_2n$趟,每次归并时 #### 基数排序的过程 +有最高位优先$MSD$和最低位优先$LSD$两种方法。 + 若是要得到递减序列: 1. 初始化:设置$r$个空辅助队列$Q_{r-1},Q_{r-2},\cdots,Q_0$。 @@ -276,13 +282,13 @@ $n$个元素二路归并排序,归并一共要$\log_2n$趟,每次归并时 需要$r$个辅助队列,所以空间复杂度为$O(r)$。 -一趟分配$O(n)$,一趟收集$O(r)$,一共有$d$趟分配收集,所以总的时间复杂度为$O(d(n+r))$。 +一趟分配$O(n)$,一趟收集$O(r)$,一共有$d$趟分配收集,所以总的时间复杂度为$O(d(n+r))$。与序列初始状态无关。 基数排序是稳定的。 #### 基数排序的应用 -对于一般的整数排序是可以按位排序的,也可以处理一些实际问题,如根据人的年龄排序,需要从年月日三个维度分别设置年份的队列、月份的队列(1到12)、日的队列(1到31)。 +对于一般的整数排序是可以按位排序的,也可以处理一些实际问题,如根据人的年龄排序,需要从年月日三个维度分别设置年份的队列、月份的队列($1$到$12$)、日的队列($1$到$31$)。 所以基数排序擅长解决的问题: