温故而知新 -> 数据结构 ->树 -> 二叉树 -> 顺序存储
注:本篇博客是在 温故而知新 -> 数据结构 ->树 -> 二叉树 的基础上,对二叉树的顺序存储进行进一步的解释!
顺序存储
本篇博客将具体说明二叉树顺序存储的相关知识,其将按照以下几个方面进行分步叙述!
1. 顺序结构
普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储,即如下图
现实中我们通常把 堆(一种二叉树) 使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。
2. 堆
2.1 概念
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1}
,把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:
则称为 小堆 (或 大堆)。将根节点最大的堆叫做 最大堆 或 大根堆,根节点最小的堆叫做 最小堆 或 小根堆。
2.2 性质与案例
- 堆中某个节点的值总是不大于或不小于其父节点的值;
- 堆总是一棵完全二叉树。
案例图示如下
2.3 实现
2.3.1 堆向下调整算法
给出如下一个数组,逻辑上看做一颗 完全二叉树。通过从根节点开始 向下调整算法 可以把它调整成一个小堆。向下调整算法有一个 前提:左右子树必须是一个堆,才能调整。
比如,int data[] = {20,2,9,3,6,10,13,4,5,7}
经调整后,结果为 data[] = {2,3,9,5,6,10,13,4,20,7}
而 向上调整算法 则是从叶子节点逐步向上进行调整!
2.3.2 堆的创建
给出一个数组,这个数组逻辑上可以看做一颗完全二叉树,但是还不是一个堆,通过算法,把它构建成一个堆。根节点左右子树不是堆。
这里从倒数的第一个非叶子节点的子树开始调整,一直调整到根节点的树,就可以调整成堆。
比如给出一个小根堆 int data[] = {1,2,7,4,5,8}
,将其转换为大根堆,具体操作如下图
最后的结果为 data[] = {8,5,7,4,2,1}
2.3.3 堆插入操作
堆的插入操作采用 向上调整算法 ,直到满足堆!
比如向 int data[] = {88,77,66,55,44,33,22,11,10,1}
中插入 99,则具体如下
最后的结果如下 data[] = {99,88,66,55,77,33,22,11,10,1,44}
2.3.4 堆的删除
删除堆是 删除堆顶的数据,主要通过向下调整。先将堆顶的数据和最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。
如删除上述堆的堆顶元素,如下
2.3.5 堆的排序
将一组数据按照要求进行排序,比如将下述的大堆转换为小堆,其初始数据为 int data[] = {20,19,8,16,10,5}
,具体排序过程如图,由于步骤较多,且原理简单,此处不再用语言进行赘述,若有不清,多多揣摩下图
转换后的结果为 data[] = {5,8,10,16,19,20}
2.3.6 程序实现
为防止本篇博客内容较长,此部分内容将在专门的博客中进行详细叙述!
关于本次的实现,提供了两种方法:
- 温故而知新 -> 数据结构 -> 二叉树 -> 顺序存储 ->程序实现1_利用结构体
- 温故而知新 -> 数据结构 -> 二叉树 -> 顺序存储 ->程序实现2_利用类
以上为本篇博客内容,若有问题请在评论区留言
侵权删~