数据结构之树(二叉树)
什么是二叉树(binary tree)?
在树结构的基础上,要求其中每个节点最多有两个子节点(一个节点最多有2个边)。
二叉树由根节点和若干个左子树和右子树构成,这些子树也都是二叉树。二叉树可以为空树,也可以只包含一个根节点。
为什么树形结构常用二叉树呢?
就是为了省空间。n叉树,n越大就需要更多的链接建立节点与子节点的关系。推导如下:
树结构一般使用链表(Linked List)存储,对于n叉树(n-way树),虽然每个节点的度数不可能都是n,但每个节点必须预留n个链接,用于建立父子节点关系。因此每个节点的数据结构如下:
这种n叉树十分浪费链接存储空间。
假设此n叉树有m个节点,那么此书需要n*m个链接/指针(每个节点都必须拥有n个链接)。除了根节点以外,每个非空链接都指向一个节点(有m-1个节点就有m-1节点链接/指针,这些链接没有浪费即为非空链接),得知空链接总数为n * m - (m - 1) = m(n-1) + 1,而n叉树的链接浪费率为 m(n-1) + 1除以n * m。因此可以得到结论:
1. n=2时,2叉树的链接浪费率为(m+1)/ 2m,浪费率约为二分之一
2. n=3时,3叉树的链接浪费率为(2m+1)/ 3m,浪费率约为三分之二
3. n=4时,4叉树的链接浪费率为(3m+1)/ 4m,浪费率约为四分之三
……
因此得到n=2时即2叉树的链接浪费率最低,因此常使用二叉树来取代其他树结构。
二叉树与一般树的不同之处
1. 是否可以是空结合:树不可以为空集合,但二叉树可以为空集合
2. 度数的范围:树的度数范围是大于等于0,而二叉树大于等于0且小于等于2
3. 子树关系:树的子树间没有次序关系,而二叉树有(主要涉及插入顺序、遍历顺序、搜索和排序)
二叉树涉及的数学证明
1. 高度为k的二叉树的总节点数是2k-1(最多),其中k大于等于1
为了实现总结点最多,每一层都挂满子节点
20 + 21+ 22+ ……+2k-1=2k-1
https://i.cnblogs.com/posts/edit-done;postId=17795378;isPublished=false
2. 二叉树第i层上的结点数目最多为2i-1(i≥1)
因为是二叉树,一个节点最多有2个子节点,除了第1层根节点是1个。其他层节点最多都是2的倍数。即
第1层:20
第2层:21
第3层:22
……
第i层:2i-1
3. 在任意-棵二叉树中,若终端结点(叶子节点)的个数为n0,度为2的结点数为n2,则no=n2+1。
推导过程:
假设
1. 叶子节点数:n0
2. 度数为1的节点数:n1
3. 读数为2的节点数:n2
4. 总节点数:n
5. 二叉树的总边数:e
从节点数得到:n=n0 + n1 + n2
已知边数与节点数关系:n=e+1
边数与度数为2、1、0节点的关系:
1. 一个度数为2的节点有2个边, n2个有2n2个边。
2. 一个度数为1的节点有1个边, n1个有 n1个边。
3. 度数为0的节点,没有边。
从而得到结论: e= 2n2 + n1
进而得到 n=n0 + n1 + n2 = e +1 = 2n2 + n1 + 1 ==> no=n2+1
特殊情形
满二叉树
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。
第2个、第3个不是满二叉树。
特点:
-
每个节点要么没有子节点,要么有两个子节点。 这意味着每个非叶节点都有两个子节点,而叶节点没有子节点。这是满二叉树与一般二叉树的主要区别。
-
所有叶节点位于同一层级。 也就是说,从根节点到叶节点的路径长度是相同的。这保证了树的高度是最小可能的,也就是log₂(n),其中n是树中的节点数。
-
高度与节点数之间的关系: 如果满二叉树有h层(包括根节点所在的层),则它包含2^h - 1个节点。这是因为每一层的节点数是2^(h-1),因此总节点数就是这些层的节点数之和,即2^0 + 2^1 + 2^2 + ... + 2^(h-1) = 2^h - 1。
完全二叉树
满二叉树是完全二叉树的一个特例
完全二叉树(Complete Binary Tree):假设二叉树的高度为h。除第h层外,其它各层(0~h-1)的结点数都达到最大个数(2k-1),第h层从右向左连续缺若干结点,这就是完全二叉树
上述所说从右向左缺若干节点,也就是说在h层的时候,如果有节点都在左半边,而缺的都是右半边的节点,这就是完全二叉树!
特点:
-
所有叶节点都出现在最底层的左侧。 这意味着叶节点按从左到右的顺序依次排列,而不会在底层之间留下空缺。
-
除了最底层,每一层都是满的。 这意味着除了最底层,每一层的节点数都是最大可能值。通常情况下,如果有h层,则前h-1层应该是满的。
-
高度与节点数之间的关系: 如果完全二叉树有h层(包括根节点所在的层),则它包含的节点数在2^(h-1)到2^h之间,其中n是树中的节点数。
BST树(二叉搜索树)
对于树上的每个节点来说,其左孩子的节点比双亲节点小,其右孩子的节点比双亲结点大,移除根节点,形成的左子树和右子树也都按照这个规则排序。
平衡二叉搜索树(AVL树)
两子树高度相差不超过1的搜索二叉树即为平衡搜索二叉树
平衡二叉搜索树(Balanced Binary Search Tree),通常简称为平衡树,是一种二叉搜索树的变体,它具有一些额外的性质,以确保树的高度保持相对平衡,从而提供高效的查找、插入和删除操作。平衡树的目标是使树的高度尽可能小,从而提高性能。
-
二叉搜索树(BST)的性质:平衡树是基于二叉搜索树的,因此它遵循BST的一些基本性质。在BST中,左子树的值小于根节点的值,右子树的值大于根节点的值。这个性质使得在BST中进行搜索操作非常高效。
-
平衡性质:与普通的BST不同,平衡树要求树的左子树和右子树的高度之差不能太大。这个差距通常被称为树的平衡因子。平衡树的目标是使树的平衡因子保持在较小范围内,通常是-1、0或1。这确保了树的高度相对平衡,防止出现极端不平衡的情况。
-
常见的平衡树类型:有几种不同的平衡树实现,其中最常见的是 AVL 树、红黑树和 Splay 树。这些树使用不同的算法和规则来保持平衡,但它们都旨在提供高效的搜索、插入和删除操作。
-
性能特点:平衡树的搜索、插入和删除操作的平均时间复杂度通常为O(log n),其中n是树中节点的数量。这是因为树的高度保持相对平衡,使得操作的时间复杂度保持在较低水平。这使得平衡树成为高效的数据结构,适用于需要高性能查找操作的应用。
-
应用:平衡树在计算机科学中有广泛的应用,包括数据库管理系统(如MySQL中的InnoDB存储引擎)、编译器优化、路由表的实现、集合和映射数据结构等。它们还用于实现动态有序集合,其中元素可以快速插入、删除和查找,而仍然保持有序。
对称二叉树(Symmetric Binary Tree)
对称二叉树(Symmetric Binary Tree)是一种特殊的二叉树,其中树的结构呈现对称性。这意味着,树的根节点具有两个子节点,这两个子节点的结构是镜像对称的,它们的左子树是对方右子树的镜像,而右子树是对方左子树的镜像。这就意味着树从根节点开始向下延伸,左子树和右子树的结构是对称的。
在这个示例中,树的根节点是1,左子树是以2为根的子树,右子树也是以2为根的子树。而且,这两个子树的结构是镜像对称的,它们的左子树和右子树也是镜像对称的。这使得整个二叉树成为一个对称二叉树。
对称二叉树在编程和数据结构中经常出现,通常用于解决一些与对称性相关的问题。在验证一个二叉树是否是对称二叉树时,通常可以使用递归算法或迭代算法来检查树的左子树和右子树是否镜像对称。
特点:
-
结构对称性:对称二叉树的结构是对称的,意味着它的左子树和右子树是相互镜像的,即它们具有相同的结构。这意味着树的每个节点都有一个与之镜像对称的节点。
-
值对称性:对称二叉树中的每一对镜像节点具有相等的值。这意味着树中节点的值也满足对称性,而不仅仅是结构对称性。
斜二叉树
斜二叉树通常指的是一种特殊类型的二叉树,其中所有节点都沿着一条斜线排列,而不是平衡地分布在左子树和右子树中。斜二叉树通常分为两种类型:左斜二叉树和右斜二叉树。
1. 左斜二叉树(Left Skewed Binary Tree):在左斜二叉树中,每个节点都只有一个子节点,这个子节点是其左子节点
2. 右斜二叉树(Right Skewed Binary Tree):在右斜二叉树中,每个节点也只有一个子节点,但这个子节点是其右子节点
严格二叉树(Strict Binary Tree)
-
每个节点要么没有子节点,要么有且仅有两个子节点:在一般二叉树中,每个节点都可以有零个、一个或两个子节点。这是严格二叉树与一般二叉树的主要不同之处。
-
树的深度和高度之间的关系:严格二叉树的高度等于树中的最大层级数。如果树的高度为h,那么最多有2^h个叶节点,而且总共的节点数不会超过2^(h+1)-1。这意味着严格二叉树的节点数与树的高度之间存在2的指数关系。
-
平衡性:严格二叉树通常是平衡的,因为它的左子树和右子树的高度差不能超过1。这使得严格二叉树的高度相对较小,从而提高了树上各种操作的效率。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)