【数据结构与算法】第十章:树和二叉树

简介: 树结构是一类重要的非线性数据结构。树在计算机领域中也得到广泛应用,尤以二叉树最为常用。本章将重点介绍树的结构定义及二叉树的相关操作。

🙊🙊作者主页:🔗求不脱发的博客

📔📔 精选专栏:🔗数据结构与算法

📋📋 精彩摘要:树结构是一类重要的非线性数据结构。树在计算机领域中也得到广泛应用,尤以二叉树最为常用。本章将重点介绍树的结构定义及二叉树的相关操作。

💞💞觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论💬支持博主🤞


📚目录

📖【数据结构与算法】第十章:树和二叉树

📝1️⃣树

📝2️⃣二叉树


📖【数据结构与算法】第十章:树和二叉树


📝1️⃣树

✨树的定义

树是n(n>=0)个结点的有限集,或为空树,或为非空树。

对于非空树T:

    1. 有且仅有一个称之为根的结点。
    2. 除根结点外,其余结点可分为m个互不相交的有限集T1,T2,...,Tm,其中每个集合本身又是一棵树,称为根结点的子树。

    image.gif编辑

    树的其他表示形式:

    image.gif编辑

    ✨树的基本术语

    image.gif编辑

      1. 结点:数中的一个独立单元。包含一个数据元素及指向其子树的分支。如上图中的A、B、C、D等。
      2. 结点的度:结点拥有的子树树称为结点的度。
      3. 树的度:结点拥有的子树树称为结点的度。
      4. 叶子:度为0的结点称为叶子或终端结点。结点K、L、F、G、M、I、J都是树的叶子。
      5. 森林:指m颗不想交的树的集合(例如删除A后的子树个数)。
      6. 有序树:结点各子树从左至右有序,不能互换(左为第一)。
      7. 无序树:结点各子树可互换位置。
      8. 非终端结点:度不为0的结点称为非终端结点或分支结点。除根结点之外,非终端结点也称为内部结点。
      9. 双亲和孩子:结点的子树的根称为该结点的孩子,相应地,该结点称为孩子的双亲。例如,B的双亲为A,B的孩子有E和F。
      10. 兄弟:同一个双亲的孩子之间互称兄弟。例如,H、I和J互为兄弟。
      11. 祖先:从根到该结点所经分支上的所有结点。例如,M的祖先为A、D和H。
      12. 子孙:以某结点为根的子树中的任一结点都称为该结点的子孙。如B的子孙为E、K、L和F。
      13. 层次:结点的层次从根开始定义起,根为第一层,根的孩子为第二层。树中任一结点的层次等千其双亲结点的层次加l。
      14. 堂兄弟:双亲在同一层的结点互为堂兄弟。例如,结点G与E、F、H、I、J互为堂兄弟。

      ✨树的抽象数据类型定义

      根据树的结构定义,加上树的一组基本操作就构成了树的抽象数据类型定义:

      ADT Tree{ 
          数据对象D:D是具有相同特性的数据元素的集合。
          数据关系R:若D为空集,则称为空树;
      } ADT Tree;

      image.gif

      基本操作:

             InitTree(&T)

                 操作结果:构造空树T。

             DestroyTree (&T)

                 初始条件:树T存在。

                 操作结果:销毁树T。

             CreateTree(&T,definition)

                 初始条件:defini巨on给出树T的定义。

                 操作结果:按defini巨on构造树T。

             ClearTree(&T)

                 初始条件:树T存在。

                 操作结果:将树T清为空树。TreeEmpty(T)

             TreeEmpty(T)

                 初始条件:树T存在。

                 操作结果:若T为空树,则返回true,否则false。

             TreeDepth(T)

                 初始条件:树T存在。

                 操作结果:返回T的深度。

             Root(T)

                 初始条件:树T存在。

                 操作结果:返回T的根。

             Value(T,cur_e)

                 初始条件:树T存在,cur_e是T中某个结点。

                 操作结果:返回cur_e的值。

             Assign(T,cur_e,value)

                 初始条件:树T存在,cur_e是T中某个结点。

                 操作结果:结点cur_e赋值为value。

             Parent(T,cur_e);

                 初始条件:树T存在,cur_e是T中某个结点。

                 操作结果:若cur_e是T的非根结点,则返回它的双亲,否则函数值为“空”。

             LeftChild(T,cur_e)

                 初始条件:树T存在,cur_e是T中某个结点。

                 操作结果:若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回“空”。

             RightSibling(T,cur_e)

                 初始条件:树T存在,cur_e是T中某个结点。

                 操作结果:若cur_e有右兄弟,则返回它的右兄弟,否则函数值为“空”。

             InsertChild(&T,p,i,c)

                 初始条件:树T存在,p指向T中某个结点,1,;;i所指结点的度+1, 非空树c与T不相交。

                 操作结果:插入c为T中p指结点的第l.棵子树

             DeleteChild(&T,p,i)

                 初始条件:树T存在,p指向T中某个结点,1,;;i指结点的度。

                 操作结果:删除T中p所指结点的第l.棵子树

             TraverseTree(T)

                 初始条件:树T存在。

                 操作结果:按某种次序对T的每个结点访问一次。

      📝2️⃣二叉树

      ✨二叉树的定义

      二叉树树是n(n>=0)个结点的有限集,或为空树,或为非空树。

      基本特点:

        1. 结点的度小于等于2。
        2. 有序树(子树有序,不能颠倒)。

        对于非空二叉树T:

          1. 有且仅有一个称之为根的结点;
          2. 除根结点以外的其余结点分为两个互不相交的子集T1和T2,分别称为T的左子树和右子树,且T1和T2本身又都是二叉树。

          二叉树与树一样具有递归性质,二叉树与树的区别主要有以下两点:

            1. 二叉树每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点);
            2. 二叉树的子树有左右之分,其次序不能任意颠倒。

            image.gif编辑

             ✨二叉树的抽象数据类型定义

            ADT BinaryTree{ 
                数据对象D:D是具有相同特性的数据元素的集合。
                数据关系R:
            } ADT BinaryTree;

            image.gif

            基本操作P:

                   InitBiTree(&T)

                       操作结果:构造空二叉树T。

                   DestroyBiTree(&T)

                       初始条件:二叉树T存在。

                       操作结果:销毁二叉树T。

                   Crea七eBiTree(&T,definition)

                       初始条件;definition给出二叉树T的定义。

                       操作结果:按definition构造二叉树T。

                   ClearBiTree(&T)

                       初始条件:二叉树T存在。

                       操作结果:将二叉树T清为空树。

                   BiTreeEmpty(T)

                       初始条件:二叉树T存在。

                       操作结果:若T为空二叉树,则返回true,否则false。

                   BiTreeDepth (T)

                       初始条件:二叉树T存在。

                       操作结果:返回T的深度。

                   Root(T)

                       初始条件:二叉树T存在。

                       操作结果:返回T的根。

                   Value(T,e)

                       初始条件:二叉树T存在,e是T中某个结点。

                       操作结果:返回e的值。

                   Assign(T,&e,value)

                       初始条件:二叉树T存在,e是T中某个结点。

                       操作结果:结点e赋值为value。

                   Parent(T,e)

                       初始条件:二叉树T存在,e是T中某个结点。

                       操作结果:若e是T的非根结点,则返回它的双亲,否则返回“空”。

                   LeftChild(T,e)

                       初始条件:二叉树T存在,e是T中某个结点。

                       操作结果:返回e的左孩子。若e无左孩子,则返回“空”。

                   RightChild(T,e)

                       初始条件:二叉树T存在,e是T中某个结点。

                       操作结果:返回e的右孩子。若e无右孩子,则返回“空”。

                   LeftSibling (T, e)

                       初始条件:二叉树T存在,e是T中某个结点。

                       操作结果:返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回“空”。

                   RightSibling(T,e)

                       初始条件:二叉树T存在,e是T中某个结点。

                       操作结果:返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回“空”。

                   InsertChild(&T,p,LR,c)

                       初始条件:二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T不相交且右子树为空。

                       操作结果:根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的原有左或右子树成        为c的右子树。

                   DeleteChild (&T, p, LR)

                       初始条件:二叉树T存在,p指向T中某个结点,LR为0或1。

                       操作结果:根据LR为0或1,删除T中p所指结点的左或右子树。

                   PreOrderTraverse(T}

                       初始条件:二叉树T存在。

                       操作结果:先序遍历T,对每个结点访问一次。

                   InOrderTraverse(T)

                       初始条件:二叉树T存在。

                       操作结果:中序遍历T,对每个结点访问一次。

                   PostOrderTraverse(T}

                       初始条件:二叉树T存在。

                       操作结果:后序遍历T,对每个结点访问一次5

                   LevelOrderTraverse(T)

                       初始条件:二叉树T存在。

                       操作结果:层序遍历T,对每个结点访问一次。

             ✨二叉树的性质

              1. 在二叉树的第i层上最多有2^(i-1)个结点。
              2. 深度为k的二叉树至多有2^k-1个结点。
              3. 对于任何一颗二叉树,若2度的结点数1有n2个则叶子数n0必定为n2+1。(即 n0 = n2 + 1)
              4. 具有n个结点的完全二叉树的深度必为[log2n]+1。
              5. 对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2。

              对此有如下定义:

              image.gif编辑image.gif编辑

                                   (满二叉树 )                                        (完全二叉树)            

              满二叉树:一棵深度为k 且有2k -1个结点的二叉树。(特点:每层都“充满”了结点

              完全二叉树:深度为k 的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k 的满二叉树中编号从1至n的结点一一对应

              满二叉树与完全二叉树的区别:

              满二叉树是叶子一个也不少的树,而完全二叉树虽然前n-1层是满的,但最底层却允许在右边缺少连续若干个结点。满二叉树是完全二叉树的一个特例。

              相关文章
              |
              12天前
              |
              存储 C++
              【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
              【数据结构——树】哈夫曼树(头歌实践教学平台习题)【合集】目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:任务描述 本关任务:编写一个程序构建哈夫曼树和生成哈夫曼编码。 相关知识 为了完成本关任务,你需要掌握: 1.如何构建哈夫曼树, 2.如何生成哈夫曼编码。 测试说明 平台会对你编写的代码进行测试: 测试输入: 1192677541518462450242195190181174157138124123 (用户分别输入所列单词的频度) 预
              49 14
              【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
              |
              12天前
              |
              Java C++
              【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
              本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
              36 12
              |
              12天前
              |
              C++
              【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
              本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
              37 10
              |
              12天前
              |
              存储 算法 测试技术
              【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
              本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
              36 2
              |
              26天前
              |
              存储 算法 Python
              文件管理系统中基于 Python 语言的二叉树查找算法探秘
              在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
              50 5
              |
              26天前
              |
              数据库
              数据结构中二叉树,哈希表,顺序表,链表的比较补充
              二叉搜索树,哈希表,顺序表,链表的特点的比较
              数据结构中二叉树,哈希表,顺序表,链表的比较补充
              |
              2月前
              |
              存储 缓存 算法
              在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
              在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
              87 5
              |
              2月前
              |
              机器学习/深度学习 存储 算法
              数据结构实验之二叉树实验基础
              本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
              112 4
              |
              4天前
              |
              算法 数据安全/隐私保护 计算机视觉
              基于Retinex算法的图像去雾matlab仿真
              本项目展示了基于Retinex算法的图像去雾技术。完整程序运行效果无水印,使用Matlab2022a开发。核心代码包含详细中文注释和操作步骤视频。Retinex理论由Edwin Land提出,旨在分离图像的光照和反射分量,增强图像对比度、颜色和细节,尤其在雾天条件下表现优异,有效解决图像去雾问题。
              |
              4天前
              |
              算法 数据可视化 安全
              基于DWA优化算法的机器人路径规划matlab仿真
              本项目基于DWA优化算法实现机器人路径规划的MATLAB仿真,适用于动态环境下的自主导航。使用MATLAB2022A版本运行,展示路径规划和预测结果。核心代码通过散点图和轨迹图可视化路径点及预测路径。DWA算法通过定义速度空间、采样候选动作并评估其优劣(目标方向性、障碍物距离、速度一致性),实时调整机器人运动参数,确保安全避障并接近目标。

              热门文章

              最新文章