IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 排序(十多种排序) -> 正文阅读

[数据结构与算法]排序(十多种排序)

8.1 排序的基本概念

排序定义

在这里插入图片描述

排序算法的评价指标

在这里插入图片描述

排序算法的分类

在这里插入图片描述

总结

在这里插入图片描述
https:/www.cs.usfca.edu/~galles/visualization/Algorithms.html

8.2-1 插入排序

插入排序举例

在这里插入图片描述

插入排序算法实现

插入排序一般实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

插入排序带哨兵实现

在这里插入图片描述

算法效率分析

空间复杂度
在这里插入图片描述
时间复杂度
在这里插入图片描述
在这里插入图片描述
下图:比如第一趟:查找70,对照着对待,A[2]=70<A[1]=80,对比关键字一次,A[0]=A[i]=70,移动元素一次,for循环,A[0]=70<A[1]=80,又对比关键字一次,A[2]=A[1]=80,又移动元素一次,最A[1]=A[0]=70,又移动元素一次。共对比关键字2次,移动元素3次
在这里插入图片描述
平均时间复杂度O(n2)
在这里插入图片描述

优化—折半插入排序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8.2-2 希尔排序

希尔排序示例

第一趟:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第二趟:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第三趟:
在这里插入图片描述
在这里插入图片描述

希尔建议设置每次将来增量缩小一半

在这里插入图片描述

算法实现

下图只是实现希尔排序的一种方法,但是这种方法并不是按照上面的思路:先分成多个子表,每个子表排完序再放回数组,更换d的大小,继续这样的操作。但下图的方法仍然能实现希尔排序。由于时间原因暂时没能实现上述思路的希尔排序的代码。
下图方法的思路是:逐步的遍历每个子表,在逐步遍历过程中使得每个子表都更有序一点,循环往复。
在这里插入图片描述
在这里插入图片描述
第一趟分别比较76和49,13和39,27和65,49和97.
第一趟结束时,第二趟开始时如下:
在这里插入图片描述
第二趟:d=4/2=2,从27开始比较,++i,顺次比较49和之前的13,比较76跟之前的27,38和之前的49,65和之前的76,97和之前38。
在这里插入图片描述
第二趟结束时,第三趟开始时如下:
在这里插入图片描述
第三趟结束时如下
在这里插入图片描述

算法性能分析

在这里插入图片描述
在这里插入图片描述
因为需要用增量d来快速的找到与之相邻的从属于同一个子表的元素,所以只有具有随机访问的特性才能完成这个事情。所以必须用顺序表。

8.3-1冒泡排序

在这里插入图片描述

算法实现

升序排列,从后往前冒泡,将小的值冒泡到前面。
当然也可以从前往后冒泡。
在这里插入图片描述
在这里插入图片描述

算法性能分析

在这里插入图片描述

冒泡排序适用于链表

在这里插入图片描述

8.3-2 快速排序

快速排序算法思想

在这里插入图片描述

快速排序代码

在这里插入图片描述

算法效率分析

时间复杂度

在这里插入图片描述
下面的分析是不严谨的,因为比较一次元素可能带来元素的移动,也可能不带来元素的移动,这里我们按照比较一次元素就按O(1)计算。那么比如下图这个初始序列,要比较每一个元素,所有我按O(n)处理。
在这里插入图片描述

空间复杂度

QuickSort()函数在执行时,不断地递归会占用多层递归工作栈,所以这里空间复杂度和递归层数有关。空间复杂度=O(递归层数)

在这里插入图片描述

把快速排序过程梳理成二叉树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最坏的情况

若给的序列是有序的,那么每次划分都很不均匀
在这里插入图片描述

比较好的情况

优化思路②随机选一个元素作为枢轴元素:因为是随机的,所以不太可能每次都选到最大的或者最小的,所以划分比较均匀。
在这里插入图片描述

实际应用中

在实际应用当中,快速排序算法的平均时间复杂度其实要接近于最好的时间复杂度,而不是接近最坏,所以在实际应用当中,快排这个算法是所有内部排序算法当中平均性能最优的排序算法。
在这里插入图片描述

稳定性

在这里插入图片描述
在这里插入图片描述
1比2小,转移到数组编号0的位置。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述

8.4-1简单选择排序

在这里插入图片描述
下图有两个49,当49是最小的时,我们优先将最前面的49移动到头部的位置使之有序。
在这里插入图片描述

算法性能分析

n个元素的简单选择排序需要n-1趟处理。
在这里插入图片描述

稳定性分析

在这里插入图片描述

8.4-2 堆排序

什么是堆?

在这里插入图片描述
回忆二叉树的顺序存储在这里插入图片描述
大根堆
在这里插入图片描述
小根堆
在这里插入图片描述

如何基于堆进行排序

在这里插入图片描述
建立大根堆
在这里插入图片描述
从n/2 的位置 8/2即4的位置开始逐个往前检查。
9不大于他的左孩子32,互换位置。
在这里插入图片描述
互换后符合大根堆
在这里插入图片描述
检查78,78小于右孩子87,互换位置。
在这里插入图片描述
交换位置后符合大根堆
在这里插入图片描述
检查17,17小于右孩子45,互换位置
在这里插入图片描述
交换位置后符合大根堆
在这里插入图片描述
检查53,53小于其右孩子87
在这里插入图片描述
交换位置后,53引起了其下层子树不符合大根堆要求,
在这里插入图片描述
采取同样的方式检查53,53小于其右孩子78,交换位置。
在这里插入图片描述
调整完成
在这里插入图片描述

建立大根堆的代码

在这里插入图片描述
这里我们直接快进到代码执行到53这个元素。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

基于大根堆进行排序

将87与待排序序列的最后一个元素9交换
在这里插入图片描述
87和09交换完成,87不需要再移动
在这里插入图片描述
将待排序元素序列再次调整为大根堆
在这里插入图片描述
小元素09下坠第一次
在这里插入图片描述
小元素09下坠第二次
在这里插入图片描述
经过调整后待排序元素序列再次构成一个“大根堆”
在这里插入图片描述
将78跟待排序序列的最后一个元素交换。
在这里插入图片描述
53被交换到第一个元素的位置
在这里插入图片描述
53下坠一次,由于78已经被排好序了,不在待排序序列中了,所以不用在比较53和78了,下图虚线的就不用再比较了。
在这里插入图片描述
经过调整后待排序元素序列再次构成一个“大根堆"
在这里插入图片描述
将65和待排序序列中的最后一个元素交换。
在这里插入图片描述
9被换到第一个位置,继续小元素下坠
在这里插入图片描述
在这里插入图片描述
将53与待排序序列中的最后一个元素交换,
在这里插入图片描述
将17进行下坠
在这里插入图片描述
17下坠一次,还没形成大根堆
在这里插入图片描述
17下坠第二次,形成大根堆
在这里插入图片描述
将45和17进行交换,
在这里插入图片描述
17下坠一次,形成大根堆
在这里插入图片描述
将来32和9交换,
在这里插入图片描述
9下坠一次形成大根堆
在这里插入图片描述
将17和待排序元素序列中的元素9交换,只剩下一个元素9,不用再调整。

在这里插入图片描述

基于大根堆进行排序(代码)

在这里插入图片描述
在这里插入图片描述

算法效率分析

在这里插入图片描述
下方有两个孩子,则“下坠”一层,需对比左右孩子各1次
在这里插入图片描述
下方只有1个孩子,则“下坠”一层,需对比左孩子1次。i<len说明没有右孩子。
在这里插入图片描述

时间复杂度1:建堆的过程(每个关键字都可能下坠)

第1层有1个结点,最多下坠(h-1)层,每个结点最多对比关键字不超过2(h-1)
第2层有2个结点,最多下坠(h-2)层,每个结点最多对比关键字不超过2(h-2),第二层最多对比关键字不超过22(h-2),
第h层不下坠,
第h-1层有2的h-2次方个结点,最多下坠1层,每个结点最多对比关键字不超过2,第二层最多对比关键字不超过2
2的h-2次方,
在这里插入图片描述
在这里插入图片描述

时间复杂度2:每一趟调整的过程(由于已经建完堆了,双亲结点大于孩子结点,所以将一个元素下坠,无需担心被调整上去的元素造成大根堆的破坏,只需要考虑下坠元素即可,而下坠元素最多下坠次数 不会超过树的高度h)

在这里插入图片描述

空间复杂度:只用到了几个 i 这样的变量,所以是常数级O(1)

在这里插入图片描述

稳定性分析

在这里插入图片描述
在这里插入图片描述
2杠和最后一个2交换,
在这里插入图片描述
未破坏大根堆,将第一个2和1交换,
在这里插入图片描述
还剩一个元素1,算法结束。结果显示是不稳定的。
在这里插入图片描述

8.4-3 堆的插入删除

插入

插入13

在这里插入图片描述
13和32比较一次,上升一层,
在这里插入图片描述
13和17比较一次,上升一层,17和9比较一次,17>9,无法上升,程序停止。共比较了3次关键字。
在这里插入图片描述

插入46

在这里插入图片描述

删除

在这里插入图片描述
删除13,
在这里插入图片描述
用堆底元素46替代被删除元素的位置。
在这里插入图片描述
46下坠第一次,比较左右孩子各一次
在这里插入图片描述
46下坠第二次,比较左右孩子各一次。以上共对比关键字次数4次
在这里插入图片描述

关键字对比次数

在这里插入图片描述

8.5-1 归并排序

什么是归并?

在这里插入图片描述
在这里插入图片描述

2路归并和4路归并

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现Merge函数

在这里插入图片描述
归并排序有稳定性
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码递归实现MergeSort

在这里插入图片描述

算法效率分析

第一次归并对比关键字次数3次,相当于n/2,是O(n)数量级。
第三次归并:每对比关键字一次,就能挑出一个当前还剩余的更小的元素。最多进行n-1次关键字的对比,就能完成一趟归并。
所以 不管是那一次的归并,都是O(n)的数量级的时间。
在这里插入图片描述

8.5-2 基数排序

基数排序示例

第一趟

在这里插入图片描述
在这里插入图片描述
靠近队头的连在前面,靠近队尾的连在后面。
在这里插入图片描述

第二趟

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第三趟

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

基数排序总体顺序

在这里插入图片描述

基数排序得到递减序列的过程

在这里插入图片描述

基数排序得到递增序列的过程

在这里插入图片描述

算法效率分析

每新增一个队列就是新增两个指针域的空间。
下图r就是10,代表0-9 10个辅助队列,
d就是关键字能被拆成几个部分。
每次分配其实就是从头到尾把链表元素扫一遍,有n个元素,扫一遍需要有O(n)的时间。
一次收集就是逐个的扫描这些队列,把这些队列上的元素都给拆下来,合成一条新链表。
在这里插入图片描述
收集一个队列只需O(1)的时间,如下图,在这里插入图片描述后,这一队列的全部元素就串到下面的链表中了,只需要O(1)的时间。
在这里插入图片描述

稳定性分析

在这里插入图片描述

8.7-1 外部排序

外部排序使用的是归并排序

磁盘的读/写以“块"为单位数据读入内存后才能被修改修改完了还要写回磁盘。
“归并排序”要求各个子序列有序,每次读入两个块的内容,进行内部排序后写回磁盘。所以先进行一次内部排序将各个初始归并块有序,后面才能进行归并排序。
若要进行k路归并排序,则需要在内存中分配k个输入缓冲区和1个输出缓冲区。
在这里插入图片描述

时间开销分析

读写次数是主要消耗时间的步骤。
“归并排序”要求各个子序列有序,所以先进行一次内部排序使初始归并块有序,然后才能进行归并排序。
在这里插入图片描述

两个优化方法

优化1:多路归并

若要进行k路归并排序,则需要在内存中分配k个输入缓冲区和1个输出缓冲区。
下图是4个输入缓冲区和1个输出缓冲区
在这里插入图片描述
在这里插入图片描述

优化2:减少初始归并段数量

在这里插入图片描述
每个初始归并段越长,初始归并段的个数r就越少,归并趟数就越少,读写磁盘的次数就越少。
在这里插入图片描述

总结

若要进行k路归并排序,则需要在内存中分配k个输入缓冲区和1个输出缓冲区
在这里插入图片描述

多路平衡归并

在这里插入图片描述
在这里插入图片描述

8.7-2 败者树

问题引入

8路平衡归并,从八个归并段中选出一个最小元素需要对比关键字7次,每次都要对比很多元素,造成时间的大量消耗。
在这里插入图片描述

败者树的构建

在这里插入图片描述

败者树在多路平衡归并中的应用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将归并段3的这个最小的元素1 弹出,进入归并序列。
在这里插入图片描述
从归并段3弹出一个元素填补空位置。
在这里插入图片描述
在这里插入图片描述
有了败者树,选出最小元素,只需对比关键字[log2(k)]次。
k路归并,就是叶子节点是k个。
下图树高4,要对比关键字3次,那么树高h,要对比关键字h-1次。
在这里插入图片描述

败者树的思路实现

在这里插入图片描述
对于k路归并,第一次构造败者树需要对比关键字k-1次,有了败者树,除了第一次构造败者树需要对比关键字k-1次外,其他的时候选出最小元素,只需对比关键字[log2(k)]次。
在这里插入图片描述
在这里插入图片描述

8.7-3 置换_选择排序

传统方法的初始归并段数量计算方法如下,可用“置换-选择排序”进步减少初始归并段数量

在这里插入图片描述

用于内部排序的内存工作区WA可容纳 l 个记录,则每个初始归并段也只能包含 l 个记录,若文件共有n个记录,则初始归并段的数量 r = n / l
在这里插入图片描述
用于内部排序的内存工作区WA可容纳 6 个记录,则每个初始归并段也只能包含 6 个记录。
在这里插入图片描述

可用“置换-选择排序”进步减少初始归并段数量(示例)

生成归并段的过程

在这里插入图片描述

生成归并段1

初始待排序文件FI在磁盘中,
初始待排序文件FO在磁盘中,
内存工作区WA在内存中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

生成归并段2

在这里插入图片描述
在这里插入图片描述
循环往复,
在这里插入图片描述

生成归并段3

在这里插入图片描述
在这里插入图片描述
循环往复,
在这里插入图片描述
算法结束。

8.7-4 最佳归并树

归并树的性质

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
构建哈夫曼树,首先要挑选权值最小的两个结点使之成为兄弟。
在这里插入图片描述

多路归并的情况

第一个归并,得到蓝色的数字,读或写的次数为51+38+32=121,
第二次归并,得到红色的数字,这次读或写的次数121,
两次一共读或写的次数为242。
在这里插入图片描述

多路归并的最佳排序树

在这里插入图片描述
每次都选择3个最小的进行归并。
在这里插入图片描述

不是多路归并的最佳排序树

在这里插入图片描述
下图注意:k叉归并的最佳归并树一定是严格k叉树,即树中只有度为k、度为0的结点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加虚段的数量

在这里插入图片描述
在这里插入图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:31:09  更:2022-08-19 19:32:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 18:49:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码