堆排序与树的缘分
Created: March 9, 2022 7:14 PM
Introduction: 介绍堆排序与二叉树那斩不断的缘分
Source: 原创
Tags: 算法专栏
堆排序前传 - 树与二叉树
树
- 树是一种数据结构 比如:目录结构
- 树是一种可以递归定义的数据结构
- 树是由n个节点组成的集合:
- 如果n=0,那这是一棵空树;
- 如果n>0,那存在1个节点作为树的根节点,其他节点可以分为m个集合,每个集合本身又是一棵树。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mY0gA5NJ-1647415802999)(%E5%A0%86%E6%8E%92%E5%BA%8F%E4%B8%8E%E6%A0%91%E7%9A%84%E7%BC%98%E5%88%86%2078b12/Untitled.png)]
树的一些概念:
-
根节点、叶子节点
上图中,A就是整棵树的根节点,叶子节点就是不能分叉的节点,已经到了树的最末端了,上图中的叶子节点有B、C、H、I、P、Q、K、L、M、N;
-
树的深度(高度)
即树的层数,上图的树就有4层;
-
树的度
树的度是最大的节点的度,节点的度就是节点的分叉数;
-
孩子节点/父节点
举例说明:E是I的父节点,I是E的子节点;
-
子树
在整个树中取一部分出来,那部分即为子树。
二叉树
- 二叉树:度不超过2的树;
- 每个节点最多有两个孩子节点;
- 两个孩子节点被区分为左孩子节点和右孩子节点
- 满二叉树:一个二叉树,如果每一层的节点数都达到了最大值,则这个二叉树就是满二叉树;
- 完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的节点都集中在该层最左边的若干位置的二叉树。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qmZ7H61f-1647415803006)(%E5%A0%86%E6%8E%92%E5%BA%8F%E4%B8%8E%E6%A0%91%E7%9A%84%E7%BC%98%E5%88%86%2078b12/Untitled%201.png)]
如下图:(a)满二叉树 (b)完全二叉树 (c)和(d)非完全二叉树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n34rJXV3-1647415803007)(%E5%A0%86%E6%8E%92%E5%BA%8F%E4%B8%8E%E6%A0%91%E7%9A%84%E7%BC%98%E5%88%86%2078b12/Untitled%202.png)]
堆的前传 - 二叉树的存储方式
二叉树的储存方式(表示方式)
- 链式存储方式
- 顺序储存方式(一般适用于完全二叉树)
使用二叉树的顺序存储细节与规律
二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。因此,必须把二叉树的所有结点安排成为一个恰当的序列,结点在这个序列中的相互位置能反映出结点之间的逻辑关系,用编号的方法从树根起,自上层至下层,每层自左至右地给所有结点编号,缺点是有可能对存储空间造成极大的浪费,在最坏的情况下,一个深度为k且只有k个结点的右单支树需要2k-1个结点存储空间。
依据二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,树中结点的序号可以唯一地反映出结点之间的逻辑关系,这样既能够最大可能地节省存储空间,又可以利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。
对于一般的二叉树,如果仍按从上至下和从左到右的顺序将树中的结点顺序存储在一维数组中,则数组元素下标之间的关系不能够反映二叉树中结点之间的逻辑关系,只有增添一些并不存在的空结点,使之成为一棵完全二叉树的形式,然后再用一维数组顺序存储。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8aU7Bl8-1647415803008)(%E5%A0%86%E6%8E%92%E5%BA%8F%E4%B8%8E%E6%A0%91%E7%9A%84%E7%BC%98%E5%88%86%2078b12/Untitled%203.png)]
(a) 一棵二叉树 (b) 改造后的完全二叉树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lCvsjzXa-1647415803009)(%E5%A0%86%E6%8E%92%E5%BA%8F%E4%B8%8E%E6%A0%91%E7%9A%84%E7%BC%98%E5%88%86%2078b12/Untitled%204.png)]
(c) 改造后完全二叉树顺序存储状态
显然,这种存储对于需增加许多空结点才能将一棵二叉树改造成为一棵完全二叉树的存储时,会造成空间的大量浪费,不宜用顺序存储结构。
那完全二叉树顺序存储规律又是什么呢?以右图为例:
-
父节点和左孩子节点的编号下标有什么关系?
0-1 1-3 2-5 3-7 4-9
i → 2i+1
-
父节点和右孩子节点的编号下标有什么关系
0-2 1-4 2-6 3-8
i → 2i+2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VjbrsXp5-1647415803010)(%E5%A0%86%E6%8E%92%E5%BA%8F%E4%B8%8E%E6%A0%91%E7%9A%84%E7%BC%98%E5%88%86%2078b12/Untitled%205.png)]
相关参考
清华大学博士讲解Python数据结构与算法:https://www.bilibili.com/video/BV1uA411N7c5?p=20
二叉树的存储方式【顺序储存(数组)、链式存储、邻接表存储等】:https://blog.csdn.net/qq_21989927/article/details/108666433