快速上手 C++ 数据结构与算法
王健伟
《C++ 新经典》系列作者,资深 C++ 讲师
3224 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
结束语 (1讲)
快速上手 C++ 数据结构与算法
15
15
1.0x
00:00/00:00
登录|注册

12|二叉树:如何存储二叉树?

你好,我是王健伟。
聊过了二叉树的遍历问题,终于要开始写程序了,所以今天就来聊聊存储二叉树的几种方法。
二叉树的存储一般有两种方式,一种是基于数组的顺序存储方式,一种是链式存储方式。它们有什么不同呢?

顺序存储方式

顺序存储方式是用一段连续的内存单元(数组)依次从上到下、从左到右存储二叉树各个节点元素。
假设我们存储的是一棵完全二叉树,如果把根节点存储在数组中下标 i = 1 的位置,那么根据之前讲解的二叉树编号规律(二叉树性质 6),左子节点就存储在下标 2 * i = 2 的位置,右子节点就存储在 2 * i + 1 = 3 的位置。这样就可以通过下标把整棵树串起来。
因为节点编号从 1 开始,所以数组中下标为 0 的位置可以空出来不用,让数组下标和节点编号保持一致。虽然这样浪费了一个存储空间,不过这点你可以自由决定。
参考下图 1。
图1 存储完全二叉树节点时所对应的数组下标示意图
不难看到,数组的下标可以体现出节点的存储位置。换句话说,数组的下标能够体现出节点之间的逻辑关系(父子、兄弟)
但如果存储的不是一棵完全二叉树,而是普通二叉树,那么存储的时候,也需要将其按照完全二叉树的方式来编号存储,这样肯定会浪费较多的数组存储空间。
参考下图 2。
图2 存储普通二叉树节点时所对应的数组下标示意图
图 2 中虚线表示的节点表示不存在的节点,但在存储时却要给其留出位置。可以看到,下标 6、8 的数组空间都被浪费掉了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了二叉树的存储方式和常用操作,包括顺序存储和链式存储,以及相关的代码实现。通过详细的代码示例,读者可以快速了解二叉树的存储方式和常用操作的实现方法。文章还介绍了如何利用扩展二叉树的前序遍历序列来创建一棵二叉树,以及深度优先遍历和广度优先遍历的实现。此外,还包括计算节点个数、求二叉树的高度、查找节点、查找节点的父节点以及树的拷贝等常用操作的实现。这些内容为读者提供了深入学习和应用二叉树的基础知识和实用技能。 文章还介绍了非递归方式实现前序、中序和后序遍历的方法,以及通过遍历序列创建二叉树的技巧。通过这些内容,读者可以了解到在实际应用中,如何利用栈来实现非递归遍历,以及如何根据前序和中序遍历序列来唯一确定一棵二叉树。这些技术特点使得读者能够更全面地掌握二叉树的操作和应用,为其在实际开发中提供了有力的工具和思路。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《快速上手 C++ 数据结构与算法》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(6)

  • 最新
  • 精选
  • Bruder_Jin
    越来越觉得这门课是一门是非常值得研读的课,学到很多东西,越来越期待后面的内容了

    作者回复: 加油努力

    2023-06-05归属地:广东
    1
  • 阿阳
    老师,好,在判断是否完全二叉树的时候,在层序遍历的出队列判断: if(tmpnode->leftChild == nullptr && tmpnode->rightChild != nullptr) { //这棵二叉树不是一棵完全二叉树。 } 如果一棵二叉树是左斜树,也不满足这个逻辑,但是左斜树不是完全二叉树。这样理解对吗?

    作者回复: 每个对呀

    2023-06-07归属地:江苏
  • 阿阳
    这节课内容真实太多了,两种存储方式,树的遍历,还有常用操作。干货满满。尤其是CreateNode的思路和使用扩展二叉树的前序遍历序列去创建二叉树,真是学习到了,解决了数据结构教材上没有具体实现的缺点。

    作者回复: 恭喜你慧眼识金,选择了这门课。😂😂

    2023-06-01归属地:江苏
  • Tokamak
    CopyTree 的重载函数中,只复制了值,没有设置 tTarget的指针域,怎么也可以得到正确的结果呢?我是哪里看漏了吗,望老师解惑~

    作者回复: 对,你看漏了,在CopyTree重载函数中,tTarget是个引用类型,你细看,他的前面有个&符号呦。😸😸

    2023-03-20归属地:上海
    2
  • peter
    请教老师几个问题: Q1:除了链式队列,还有其他队列吗? Q2:二叉树操作,C++标准库有封装好的类或API吗? 如果有,性能怎么样? Q3:二叉树的典型应用是什么? Q4:实际应用中,二叉树的大小有限制吗?一般多大?

    作者回复: A1:链式是一种实现队列的方式,那你用数组也可以实现队列是吧,队列无非就是先进先出这种特性。当然也有双端队列循环队列等算是对基础队列功能的扩展,想了解可以通过搜索引擎查一下。 A2:标准库没听说有针对二叉树操作的封装好的类或者API,因为一般人还真用不好这种接口。不过标准库中的MAP容器是用红黑树(二叉树的一种)这种数据结构存储数据的。 A3:二叉树是个通称,后面你会学到各种二叉树比如红黑树等。许多用到红黑树的地方,比如LINUX上实现号称单机百万并发的epoll技术,刚才提到的map容器等,有兴趣在搜索引擎里搜一下“二叉树实际应用”这样的关键字即可找到很多结果。 A4:没注意到哪里有限制二叉树大小,不过肯定有内存限制是吧。因为每个二叉树节点都占内存。当然,从实用角度一般几万到几十万个节点就差不多了吧。二叉树深度太深也很影响插入,查找,删除等效率是吧。 我个人建议不用想那么多,用就是了。除非机器性能很吃紧让你不得不精打细算,不然还没听说过有什么限制。

    2023-03-11归属地:北京
  • Geek_5ddd2e
    这节课开始难度”嗖“地一下上来了/哭
    2024-01-07归属地:重庆
收起评论
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部