【数据结构 Java 版】二叉树的实现(超多图、超详解)(1)

注意

子树也必须是二叉树才能满足该树整体是一个二叉树

2.3 两种特殊的二叉树


2.3.1 满二叉树

满二叉树: 一个二叉树,如果每一层的节点数都达到最大值,则这个二叉树就是满二叉树。

性质: 如果一个二叉树的层数是k,且节点数是 2k-1,则它就是满二叉树。

在这里插入图片描述

2.3.2 完全二叉树

完全二叉树: 完全二叉树是效率很高的数据结构,它是由满二叉树引申出来的。它的叶子节点只会出现在最后2层,且最后一层的叶子节点都靠左对齐。 (满二叉树是一种特殊的完全二叉树)

在这里插入图片描述

2.4 二叉树的性质


  • 若规定根节点的层数为1,则一棵非空二叉树的第 i 层上最多有 2i-1(i>0)个节点
  • 若规定只有根节点的二叉树的深度为1,则深度为 k 的二叉树的最大节点数是 2k-1(k>=0)
  • 对任何一棵二叉树,如果其叶子节点个数为 m,度为2的非叶子节点个数为 n,则有 m=n+1
  • 具有 n 个节点的完全二叉树的深度为 log2(n+1) 向上取整
  • 对于具有 n 个节点的完全二叉树,如果按照从上至下、从左至右的顺序对所有节点从0开始编号,则对序号为 i 的节点有:
*   若 i>0,双亲序号为:(i-1)/2
*   若 i=0,i 为根节点编号,无双亲节点
*   若 2i+1<n,左孩子序号为:2i+1,否则没有左孩子
*   若 2i+2<n,右孩子序号为:2i+2,否则没有右孩子

练习题:

假设一棵完全二叉树中总共有1000个节点,则该二叉树中有____个叶子节点,____个非叶子节点,____个节点只有左孩子,____个节点只有右孩子。

答案:

500、500、1、0

解析:

  • 由于这是一个完全二叉树,所以不可能出现只有右孩子的节点,故最后一空为0
  • 通过节点个数1000,可以推导出该树的深度为10
  • 第10层节点数可以通过总节点数减去前9层节点数得到,为1000-511=489
  • 叶子节点数=第10层的节点数+第九层度为0的节点数,而通过第10层的节点数可以知道他们的父节点有489/2+1=245
  • 由于这是一个完全二叉树,所以第9层的节点肯定是满的,易得第9层节点数为256,而去除第九层度不为0的节点数,得到第九层叶子节点有256-245=11
  • 故叶子节点数为489+11=500,非叶子节点数为1000-500=500
  • 而完全二叉树的节点只有左子树的结果有1或0,通过第十层的节点数489为偶数,我们知道肯定有一个父节点只有一个孩子节点,即只有左子树的节点为1

2.5 二叉树的存储


二叉树的存储结构分为:顺序存储(在堆中介绍)和类似于链表的链式存储

二叉树的链式存储是通过一个一个的节点引用起来的,表示方法有:孩子表示法孩子双亲表示法

孩子表示法:

class Node{

int val; // 数值域

Node left; // 左孩子的引用,常常代表以左孩子为根的整棵树

Node right; // 右孩子的引用,常常代表以右孩子为根的整棵树

}

孩子双亲表示法:

class Node{

int val; // 数值域

Node left; // 左孩子的引用,常常代表以左孩子为根的整棵树

Node right; // 右孩子的引用,常常代表以右孩子为根的整棵树

Node parent; // 当前节点的根节点

}

2.6 二叉树的基本操作


2.6.1 二叉树的前、中、后序遍历(递归实现)

二叉树是一个非线性的数据结构,对它进行遍历的方式其实有多种,因此如果我们都以自己的方式去遍历二叉树,那么这个代码的易懂性就大大降低,显得很混乱。

为此对于二叉树,根据遍历根节点的先后次序,我们有以下三种遍历方式(N:代表根节点;L:代表根节点的左子树;R:代表根节点的右子树)

  • 前序遍历(NLR): 先访问根节点➡根的左子树➡根的右子树
  • 中序遍历(LNR): 先访问根的左子树➡根节点➡根的右子树
  • 后序遍历(LRN): 先访问根的左子树➡根的右子树➡根节点

练习题:

请写出下面这棵二叉树的四种遍历方式

在这里插入图片描述

答案:

  • 前序遍历:ABDEHCFG
  • 中序遍历:DBEHAFCG
  • 后序遍历:DHEBFGCA

注意:

不管是前序、中序还是后序遍历,遍历的路径是一样的,但访问的方式是不一样的

2.6.2 二叉树的层序遍历

除了前中后序遍历外,二叉树还有一种很直观的遍历方式:层序遍历。层序遍历就是从二叉树的根节点出发,首先访问该树的第一层的根节点,然后从左到右访问第二层的节点,接着是第三层的节点,以此类推。

在这里插入图片描述

对于上图的树,使用层序遍历,节点被访问的顺序为:ABCDEFGH

层序遍历一般使用非递归的方式,具体的实现方法可以使用队列在这里插入图片描述

代码: 实现层序遍历

public void levelOrderTraversal(Node root){

if(root==null){

return;

}

Queue queue

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值