树与二叉树基本概念与性质

article/2025/8/26 20:41:55

树的基本概念

基本概念

树的度—— 一棵树中最大的结点度数
双亲—— 孩子结点的上层结点叫该结点的双亲
兄弟—— 同一双亲的孩子之间互成为兄弟
祖先—— 结点的祖先是从根到该结点所经分支上的所有结点
子孙—— 以某结点为根的子树中的任一结点都成为该结点的子孙
结点的层次—— 从根结点算起,根为第一层,它的孩子为第二层……
堂兄弟—— 其双亲在同一层的结点互称为堂兄弟。
深度—— 树中结点的最大层次数
有序树—— 如果将树中结点的各子树看成从左至右是有次序的(即不能互换),则称该树为有序树,否则称为无序树。在有序树中最左边的子树的根称为第一个孩子,最右边的称为最后一个孩子。
森林—— m(m0)棵互不相交的树的集合

形象表示

这里写图片描述

m叉树定义

每个结点的度数 <= m;

二叉树

于是二叉树有如下五种形态

这里写图片描述

二叉树的子树有左右之分,不能颠倒

特殊的二叉树

满二叉树

重点是
形象表示(图片中数字仅代表编号,不代表真实数值)

这里写图片描述

1.定义: 高度为h,并且含有(2^h)-1个结点的二叉树
2.对于编号为 i 的结点,如果有双亲,双亲为 i/2 向下取整;如果有左孩子,左孩子编号为 2i,如果有右孩子,右孩子编号为 (2i + 1)

完全二叉树

1.若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
2.如果有度为 1 的结点,那只可能有一个,且该节点只有左孩子,而无右孩子

满二叉树、完全二叉树、非完全二叉树对比

这里写图片描述

二叉排序树

形象表示

二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。

这里写图片描述

定义

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则 左子树 上所有结点的值均 <= 它的 根结点 的值;
(2)若右子树不空,则 右子树 上所有结点的值均 >= 它的 根结点 的值;
(3)左、右子树也分别为二叉排序树 (递归定义);

平衡二叉树

形象表示

这里写图片描述

定义

平衡二叉树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的 左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树,同时,平衡二叉树必定是二叉搜索树,反之则不一定

二叉树性质

性质1 在二叉树的第 i 层上至多有 2^(i-1)个 结点(i>=1)

用数学归纳法证明
归纳基础:i=1时,有2^(i-1)=2^0=1。因为第1层上只有一个根结点,所以命题成立。
归纳假设:假设对所有的 j ( 1<=j < i ) 命题成立,即第j层上至多有 2^(j-1) 个结点,证明j=i时命题亦成立。
归纳步骤:根据归纳假设,第 i-1 层上至多有2^(i-2)个结点。由于二叉树的每个结点至多有两个孩子,故第 i 层上的结点数至多是第 i-1 层上的最大结点数的2倍。即 j=i 时,该层上至多有2×2^(i-2)=2^(i-1)个结点,故命题成立。

性质2 深度为k的二叉树至多有2^k-1个结点(k≥1)。

至多,即视之为满二叉树
证明:计算等比数列 2^0+2^1+…+2^(k-1)=2^k-1

性质3 在任意-棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则no=n2+1。

回顾 m叉树 的性质
1. 设m叉树中,度数为 i 的结点树为 Ni, 则总结点数为: N = N0 + N1 + … + Nm;
2. N = 分支数 + 1 , 1 为根结点
3. 于是 N = N0 + N1 + …+ Nm = 0*(N0) + 1*(N1) + … + m*(Nm) + 1
4. 对应于现在所讨论的二叉树,于是有 N = N0 + N1 + N2 = N1 + 2*(N2) + 1,于是等到结论 N0 = N2 + 1

详细证明

证明:因为二叉树中所有结点的度数均不大于2,所以结点总数(记为n)应等于0度结点数、1度结点(记为n1)和2度结点数之和:
n=no+n1+n2 (式子1)
  另一方面,1度结点有一个孩子,2度结点有两个孩子,故二叉树中孩子结点总数是:
nl+2n2
  树中只有根结点不是任何结点的孩子,故二叉树中的结点总数又可表示为:
n=n1+2n2+1 (式子2)
  由式子1和式子2得到:
no=n2+1

二叉树遍历

二叉树的前中后序的遍历,坐标名词针对的是 根节点;无论何种遍历,左孩子永远比右孩子前

  • 先序递归遍历 先访问根结点,再前序遍历左子树,最后前序遍历右子树。可见,这个操作的定义就是递归的
public void pre_order_traversal_recursion_way(Node root) {if (root == null) {return;}out.print(root.data + " ");pre_order_traversal_recursion_way(root.left);pre_order_traversal_recursion_way(root.right);}
  • 中序递归遍历 先中序遍历左子树,再访问根结点,最后中序遍历右子树。由于左子树上的值都比根结点小,右子树上的值都比根结点大,所以,中序遍历一棵树所得到的结果,是从小到大有序的,可以根据这个特点,来检验你的中序遍历是否正确实现了
 void mid_order_traversal_recursion_way(Node root){if(root == null){return;}mid_order_traversal_recursion_way(root.left);out.print(root.data+" ");mid_order_traversal_recursion_way(root.right);}
  • 后序递归遍历 先后序遍历左子树,再后序遍历右子树,最后访问根结点
void post_order_traversal_recursion_way(Node root){if(root == null){return;}post_order_traversal_recursion_way(root.left);post_order_traversal_recursion_way(root.right);out.print(root.data+" ");}
  • 非递归先序遍历 先让根节点进栈,只要栈不为空,就可以做弹出操作;每次弹出一个结点,记得把它的左右结点都进栈。记得先右孩子,这样可以保证右子树在栈中总处于左孩子树的下面。
void pre_order_traversal_not_recursion_way(Node root) throws StackEmptyException {Stack<Node> stack = new Stack(100);Node currentNode= root;stack.push(currentNode);while (!stack.isEmpty()){currentNode = stack.pop();out.print(currentNode.data + " ");if(currentNode.right != null){stack.push(currentNode.right);}if(currentNode.left != null){stack.push(currentNode.left);}}}
  • 非递归中序遍历

一直遍历到左子树最下边,边遍历边保存根节点到栈中
当p为空时,说明已经到达左子树最下边,这时需要出栈了
进入右子树,开始新的一轮左子树遍历(这是递归的自我实现)

private void mid_order_traversal_not_recursion_way(Node root) throws StackEmptyException {Stack<Node> stack = new Stack(100);Node currentNode = root;while (currentNode != null || !stack.isEmpty()){if(currentNode != null){stack.push(currentNode);currentNode = currentNode.left;}else{Node topNode = stack.pop();out.print(topNode.data + " ");currentNode = topNode.right;}}}
  • 层次遍历 队列,先进先出;每出一个结点,其左右孩子进队;依此类推
 private void level_order(Node root){Queue<Node> queue = new LinkedList();Node currentNode = root;queue.add(currentNode);while (!queue.isEmpty()){currentNode = queue.poll();out.print(currentNode.data+ " ");if(currentNode.left != null){queue.add(currentNode.left);}if(currentNode.right != null){queue.add(currentNode.right);}}}

数学归纳法:

1)当n=1时,显然成立.
2)假设当n=k时(把式中n换成k,写出来)成立,
则当n=k+1时,(这步比较困难,化简步骤往往繁琐)该式也成立.
由(1)(2)得,原命题对任意正整数均成立


http://chatgpt.dhexx.cn/article/90cRfglg.shtml

相关文章

【数据结构】 树与二叉树的基本概念、结构特点及性质

前言&#xff1a;本章内容主要是数据结构中树与二叉树的基本概念、结构特点及性质的引入。 文章目录 树的概念树的特点&#xff1a;树的常用术语&#xff1a;树的表示&#xff1a;代码创建&#xff1a; 树在实际中的应用&#xff1a; 二叉树的概念特殊的二叉树满二叉树完全二叉…

二叉树的基本性质

一、二叉树的定义&#xff1a; 二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”&#xff08;right subtree&#xff09;。二叉树常被用于实现二叉查找树和二叉堆。 如图所示为一颗二叉树&#xff1a; ​ 二、二叉树的基本性质&#xff1a; 1、…

B+树叶子结点到底存储了什么?

首先MYSQL默认InnoDB引擎&#xff0c;该引擎默认B树&#xff1b;先说结论&#xff1a;B树叶子结点存储的是主键KEY或者具体数据。分情况讨论&#xff1a; 主键KEY 比如说user_name是个索引&#xff0c;当执行该SQL&#xff1a;select * from user_info where user_name xiao…

二叉树叶子结点,非叶子节点以及深度的计算

二叉树叶子结点的计算 //统计叶子结点的数目 int LeafNum(BiTree T) {if (!T) {return 0;} else if (!T->lchild && !T->rchild) {return 1;} else {return LeafNum(T->lchild) LeafNum(T->rchild);} }二叉树非叶子节点的计算 //统计非叶子结点的数目 i…

叶子结点

叶子结点 叶子结点是离散数学当中的概念。一棵树当中没有子结点&#xff08;即度为0&#xff09;的结点&#xff0c;称为叶子结点&#xff0c;简称“叶子”。 叶子是指度为0的结点&#xff0c;又称为终端结点。 叶子结点 就是度为0的结点 就是没有子结点的结点 n0&#xff1a;…

Pytorch 叶子张量 leaf tensor (叶子节点) (detach)

在Pytorch中&#xff0c;默认情况下&#xff0c;非叶节点的梯度值在反向传播过程中使用完后就会被清除&#xff0c;不会被保留。只有叶节点的梯度值能够被保留下来。 对于任意一个张量来说&#xff0c;我们可以用 tensor.is_leaf 来判断它是否是叶子张量&#xff08;leaf tenso…

Pytorch学习笔记(一)——自动求导和叶子节点

一、什么是叶子节点 PyTorch中的张量tensor有一个属性是is_leaf&#xff0c;当is_leaf为True时&#xff0c;改tensor是叶子张量&#xff0c;也叫叶子节点。 二、叶子节点的作用 PyTorch有自动求导的功能&#xff0c; 当requires_gradTrue时&#xff0c;PyTorch会自动记录运算…

数据结构-树:根节点、子节点、叶子节点是什么?

前言&#xff1a;这个属于数据结构&#xff1a;树。 下面给个例子图解释&#xff08;根节点、子节点、叶子节点&#xff09;。 上图数字 1、3、7是叶子节点&#xff1b;&#xff08;因为他们下面没有分叉出子节点&#xff0c;所以称为&#xff1a;叶子节点&#xff09;【度为0】…

数据结构 - 树

树 &#xff08;1&#xff09;相关概念 兄弟节点&#xff1a;节点的父节点是同一个节点&#xff0c;所以它们之间互称为兄弟节点。 根节点&#xff1a;没有父节点的节点叫作根节点 叶子节点&#xff1a;没有子节点的节点叫作叶子节点或者叶节点。 节点的高度&#xff1a;节…

根节点、子节点、叶子节点是什么?

前言&#xff1a;这个属于数据结构&#xff1a;树。 下面给个例子图解释&#xff08;根节点、子节点、叶子节点&#xff09;。 上图数字 1、3、7是叶子节点&#xff1b;&#xff08;因为他们下面没有分叉出子节点&#xff0c;所以称为&#xff1a;叶子节点&#xff09;【度为0】…

弱网、2G、3G、4G测试

1.各项指标 教程指引&#xff1a;弱网测试教程 2.概念介绍 Bandwidth&#xff08;带宽&#xff09;、Utilistation&#xff08;利用百分比&#xff09;、Round-trip&#xff08;往返延迟&#xff09;、MTU&#xff08;最大传输单元&#xff09; 3G&#xff1a;300k-2Mbps左…

简单实用Chrome 日常开发功能详解,帮助你上班摸鱼

chrome是目前开发过程中一骑绝尘的浏览器&#xff0c;占有绝对领导地位。其强大的功能和生态圈&#xff0c;让很多开发者爱不释手。但很多的开发者使用chrome还是停留在F12打开控制台查看log、检查元素或者debug打断点阶段&#xff0c;其实chrome的强大的功能远远超过我们的想象…

小米路由器3G如何解决USB3.0 5G WiFi速度慢的问题

经常玩电脑&#xff0c;希望家里有个轻 nas&#xff0c;小米路由器是一个不错的选择&#xff0c;tbw买了一个小米路由器3G看重的是快速的速度&#xff08;usb3.0 5G Wifi&#xff09;&#xff0c;及小米的可拓展性&#xff0c;使用usb3.0的usb接口&#xff0c;且使用5gb网速&am…

浏览器通过f12来限制网速

浏览器可以使用F12开发者工具来模拟网速的快慢。 打开需要测试的网站&#xff0c;点击F12&#xff0c;再点击选项里的network-no throttling&#xff0c;展示的有几种&#xff0c;offline&#xff0c;快3g&#xff0c;慢3g&#xff0c;或者自定义 点击add可以自定义网速&#…

移动网速测试软件,网速测试大师APP

网速测试大师APP是一款专业的手机网络测试应用&#xff0c;支持一键测速&#xff0c;精准快速&#xff0c;还能全方位分析网速&#xff0c;Wifi和移动网络全检测&#xff0c;30秒测速当前网络状况&#xff0c;做随时随地的测速专家。 该软件整个测速过程精准又快速&#xff0c;…

android 显示网速,随着掌握联网状态 Android手机如何显示实时网速

很多时候手机信号栏明明显示正在联网而且图标也显示正在下载上传中&#xff0c;但就是打不开网页。实际上&#xff0c;此时可能正处于4G→3G切换状态而出现了短暂的断网。那么&#xff0c;如何才能准确掌握手机当前的联网状态呢&#xff1f; 答案很简单&#xff0c;就是通过手机…

Fiddler工具的弱网模拟2G/3G/4G

日常测试工作中&#xff0c;C端用户会因信号和设备网络原因&#xff0c;出现一些恶劣网络的状态&#xff0c;然后出现奇奇怪怪的丢包、重传、UI空白、UI绘制异常等问题&#xff0c;就需要测试人员去模拟这类弱网环境去重现用户反馈的问题&#xff0c;以方便开发同学解决和调优加…

网速测试大师的软件怎么回事,网速测试大师

手机网速测试大师是一款手机网络测试软件&#xff0c;通过手机网速测试大师你可以直接测试你手机的网络速度&#xff0c;无论是WIFI还是手机移动网络都可以检测&#xff0c;让你更加了解你的手机网络。 软件介绍 网速测试大师是一款热度仅次于Ookla Speedtest. net的网速测试工…

限制浏览器网速

需求&#xff1a;限制浏览器网速&#xff0c;拉长请求时间&#xff0c;方便验证请求loading状态是否添加成功。 ps&#xff1a;一般建议给弹窗/按钮增加loading状态&#xff0c;防止重复点击之后多次请求 解决方案&#xff1a;控制台(f12)-网络(Network) No throttling 无限制…