二叉树(Java)

news2024/9/23 21:21:36

目录

  • 一、概念
  • 二、 两种特殊的二叉树
  • 三、 二叉树的性质
  • 四、二叉树的存储
  • 五、二叉树的基本操作
    • 1、二叉树的遍历
      • (1)前中后序遍历
      • (2)层序遍历
    • 2、基本操作
  • 六、总结

一、概念

一棵二叉树是结点的一个有限集合,该集合:

  1. 或者为空
  2. 或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。

在这里插入图片描述

二、 两种特殊的二叉树

  1. 满二叉树: 一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树。也就是说,如果一棵二叉树的层数为K,且结点总数是 ,则它就是满二叉树。
  2. 完全二叉树: 完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。
    在这里插入图片描述

三、 二叉树的性质

  1. 若规定 根节点的层数为 1 ,则一棵 非空二叉树的第 i 层上最多有 2^(i-1) (i>0) 个结点;
  2. 若规定只有 根节点的二叉树的深度为 1 ,则 深度为 K 的二叉树的最大结点数是2^k - 1
    (k>=0);
  3. 对任何一棵二叉树 , 如果其 叶结点个数为 n0, 度为 2 的非叶结点个数为 n2, 则有 n0 = n2 + 1;
    假设二叉树有N个节点,一棵二叉树,有n0(度为0的节点),n1(度为1的节点),n2(度为2)有N=n0+n1+n2;
    一个有N个节点的二叉树,共有N-1条边;
    度为0的节点产生0条边,度为1的节点有n1个 产生n1条边,度为2的节点有n2个 产生2n2条边,N-1=n1+2n2;
    联立得n0=n2+1;
    对于任意一个二叉树,叶子节点的个数比度为2的节点多一个。
  4. 具有 n 个结点的完全二叉树的深度 k 为log₂(n+1) 上取整;
    2^k-1=n->k=log₂(n+1)
  5. 对于具有 n 个结点的完全二叉树 ,如果按照 从上至下从左至右的顺序对所有节点从 0 开始编号 ,则对于 序号为 i 的结点有 :
    若 i>0 , 双亲序号: (i-1)/2 ; i=0 , i 为根节点编号 ,无双亲节点
    若 2i+1<n ,左孩子序号: 2i+1 ,否则无左孩子;
    若 2i+2<n ,右孩子序号: 2i+2 ,否则无右孩子。

四、二叉树的存储

二叉树的存储结构分为:顺序存储和类似于链表的链式存储。

二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式,具体如下:

// 孩子表示法
class Node {
	int val; // 数据域
	Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
	Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
} 
// 孩子双亲表示法
class Node {
	int val; // 数据域
	Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
	Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
	Node parent; // 当前节点的根节点
}

五、二叉树的基本操作

1、二叉树的遍历

(1)前中后序遍历

NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点—>根的左子树—>根的右子树。
LNR:中序遍历(Inorder Traversal)——根的左子树—>根节点—>根的右子树。
LRN:后序遍历(Postorder Traversal)——根的左子树—>根的右子树—>根节点。

// 前序遍历
void preOrder(Node root);
// 中序遍历
void inOrder(Node root);
// 后序遍历
void postOrder(Node root);

前序遍历
先输出当前节点(初始的时候是root节点)
如果左子节点不为空,则递归继续前序遍历
如果右子节点不为空,则递归继续前序遍历

中序遍历
如果当前节点的左子节点不为空,则递归中序遍历
输出当前节点
如果当前的右子节点不为空,则递归中序遍历

后序遍历
如果当前节点的左子节点不为空,则递归后序遍历
如果当前节点的右子节点不为空,则递归后序遍历
输出当前节点

// 前序遍历  
void preOrder(Node root) {  
	if (root == null) {  
		return;  
	}  
	// 访问根节点  
	System.out.print(root.data + " ");  
	// 递归遍历左子树  
	preOrder(root.left);  
	// 递归遍历右子树  
	preOrder(root.right);  
}  
  
// 中序遍历  
void inOrder(Node root) {  
	if (root == null) {  
		return;  
	}  
	// 递归遍历左子树  
	inOrder(root.left);  
	// 访问根节点  
	System.out.print(root.data + " ");  
	// 递归遍历右子树  
	inOrder(root.right);  
}  
  
// 后序遍历  
void postOrder(Node root) {  
	if (root == null) {  
		return;  
	}  
	// 递归遍历左子树  
	postOrder(root.left);  
	// 递归遍历右子树  
	postOrder(root.right);  
	// 访问根节点  
	System.out.print(root.data + " ");  
}  

(2)层序遍历

层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在
层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层
上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

public void levelOrder(TreeNode root){
	Queue<TreeNode> queue = new LinkedList<>();
	if(root != null){
		queue.offer(root);
	}
	while (!queue.isEmpty()){
		TreeNode top = queue.poll();
		System.out.print(top.val+" ");
		if(top.left != null){
			queue.offer(top.left);
		}
		if(top.right != null){
			queue.offer(top.right);
		}
	} 
}

2、基本操作

(1)获取二叉树结点个数:

public int size(Node root){
	if(root==null)
	return 0;
	return size(root.left)+size(root.right)+1;
}

(2)获取叶子结点个数:

// 获取叶子节点的个数
public int getLeafNodeCount(Node root){
	if(root==null){
		return 0;
	}
	if(root.left==null&&root.right==null){
		return 1;
	}
	return getLeafNodeCount(root.left)+getLeafNodeCount(root.right);
}

(3) 获取第k层结点个数:

public int getKLevelNodeCount(TreeNode root, int k){
	if(root == null){
		return 0;
	}
	if(k == 1){
		return 1;
	}
	return getKLevelNodeCount(root.left,k-1) + getKLevelNodeCount(root.right,k-1);
}

(4) 获取二叉树高度:

public  int getHeight(TreeNode root){
	if(root == null){
		return 0;
	}
	int leftH = getHeight(root.left);
	int rightH = getHeight(root.right);
 
	return (leftH > rightH ? leftH :rightH) + 1;
}

(5)检测是否存在value值:

public TreeNode find(TreeNode root,int val){
	if(root == null) return null;
	if(root.val == val){
		return root;
	}
	TreeNode leftL = find(root.left,val);
	if(leftL != null){
		return leftL;
	}
	TreeNode leftLR = find(root.right,val);
	if(leftLR != null){
		return leftLR;
	}
	return null;
}

(6)是否为完全二叉树:

public boolean isCompleteTree(TreeNode root){
	Queue<Node> queue = new LinkedList<>();
	if(root != null){
		queue.offer(root);
	}
	while (!queue.isEmpty()){
		Node cur = queue.poll();
		if(cur != null){
			queue.offer(cur.left);
			queue.offer(cur.right);
		}else{
			break;
		}
	}
	while (!queue.isEmpty()){
		Node cur = queue.poll();
		if(cur != null){
			return false;
		}
	}
	return true;
}

六、总结

通过对二叉树的深入学习,我们可以理解其性质、存储方式以及基本操作,从而在实际问题中灵活运用二叉树来解决各种问题。在实际应用中,我们还需要根据具体问题选择合适的二叉树类型(如满二叉树、完全二叉树、平衡二叉树等)以及相应的存储方式(顺序存储或链式存储)。此外,二叉树的遍历是二叉树操作的基础,需要熟练掌握前序、中序、后序和层序遍历的方法。通过不断练习和实践,我们可以更好地应用二叉树来解决实际问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1483787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java使用itex生成PDF

Text是著名的开放源码的站点sourceforge一个项目&#xff0c;是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档&#xff0c;而且可以将XML、Html文件转化为PDF文件。 项目要使用iText&#xff0c;必须引入jar包。才能使用&#xff0c;maven依赖如下&…

在线开源免费问卷调查系统

在线开源免费问卷调查系统 平台简介 本项目旨在提供一个简单易用的问卷调查平台&#xff0c;帮助用户创建、分享问卷&#xff0c;并收集、分析调查数据。我们希望能够为各行各业的调查需求提供一种高效、便捷的解决方案。 项目特点 用户友好&#xff1a;清晰直观的用户界面…

【SpringBoot】测试单元使用多线程

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;SpringBoot ⛺️稳重求进&#xff0c;晒太阳 问题产生 今天学习了乐观锁&#xff0c;但在测试单元执行多线程的时候出现了问题&#xff0c;多线程并没有直接结果 在控制台没有任何输出…

★【二叉搜索树(中序遍历特性)】【 ★递归+双指针】Leetcode 98. 验证二叉搜索树

★【二叉搜索树&#xff08;中序遍历特性&#xff09;】【 ★递归双指针】Leetcode 98. 验证二叉搜索树 二叉搜索树 98. 验证二叉搜索树解法1 笨 中序递归遍历为一个数组 然后判断数组是不是升序排列就可以★解法2 不使用数组 递归法 ---------------&#x1f388;&#x1f38…

电脑中msvcp140_CODECVT_IDS.dll丢失的解决方法分享

msvcp140_CODECVT_IDS.dll是Microsoft Visual C 2015 Redistributable Package的一个组成部分&#xff0c;它是一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;包含了运行基于C编译的应用程序时所需的特定编码转换支持。这个dll文件特别与字符编码转换和本地化支持…

观察者模式 详解 设计模式

观察者模式 观察者模式是一种行为型设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;使得当一个对象的状态发生变化时&#xff0c;其相关依赖对象都会得到通知并自动更新&#xff0c;如同发布-订阅模式。常见的情况如&#xff1a;公众号更新内容&#xff0c;所有…

灯塔:CSS笔记

CSS&#xff1a;层叠样式表 所谓层叠 即叠加的意思&#xff0c;表示样式可以一层一层的层叠覆盖 css写在style标签中&#xff0c;style标签一般写在head标签里面&#xff0c;title标签下面 <!DOCTYPE html> <html lang"en"> <head><meta cha…

Docker_设置docker服务以及容器开机自启

本文目录 docker服务开机自启动查询docker服务开机自启动状态将docker服务设置为开机自启动取消docker服务开机自启动 容器开机自启动修改docker容器为自启动容器启动时设置自启动-docker版容器启动时设置自启动-docker-compose版 docker服务开机自启动 查询docker服务开机自启…

【airtest】自动化入门教程(三)Poco操作

目录 一、准备工作 1、创建一个pthon脚本 2、光标位置 2、选择Android 3、选择yes 二、定位元素 三、poco基于设备/屏幕 方式 1、poco.click( (x,y))基于屏幕点击相对坐标为x&#xff0c;y的位置 2、poco.get_screen_size() 3、poco.swipe(v1,v2)基于屏幕从v1位置滑到…

腾讯云学生服务器使用教程_申请腾讯云学生机详细流程

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

Linux篇: 进程控制

一、进程创建 1.1 fork函数初识 在Linux中&#xff0c;fork函数是非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。 返回值&#xff1a; 在子进程中返回0&#xff0c;父进程中返回子进程的PID&#xff0c;子进程创…

腾讯云-云+校园扶持-2核2G学生服务器套餐30元起

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

【风格迁移】URST:解决超高分辨率图像的风格迁移问题

URST&#xff1a;解决超高分辨率图像的风格迁移问题 提出背景URST框架的整体架构 提出背景 论文&#xff1a;https://arxiv.org/pdf/2103.11784.pdf 代码&#xff1a;https://github.com/czczup/URST?v1 有一张高分辨率的风景照片&#xff0c;分辨率为1000010000像素&#…

【分类讨论】【割点】1568. 使陆地分离的最少天数

作者推荐 动态规划的时间复杂度优化 本文涉及知识点 分类讨论 割点 LeetCode1568. 使陆地分离的最少天数 给你一个大小为 m x n &#xff0c;由若干 0 和 1 组成的二维网格 grid &#xff0c;其中 1 表示陆地&#xff0c; 0 表示水。岛屿 由水平方向或竖直方向上相邻的 1 …

Bootstrap的使用

目录 js的引入&#xff1a; 1.行内式 2.嵌入式 3.外链式 Bootstrap:的引入 注意事项&#xff1a; 条件注释语句&#xff1a; 栅格系统&#xff1a; 列嵌套&#xff1a; 列偏移&#xff1a; 列排序&#xff1a; 响应式工具&#xff1a; Bootstrap的字体图标的使用&a…

【MATLAB源码-第147期】基于matlab的QPSK调制解调在AWGN信道,瑞利信道,莱斯信道理论与实际误码率对比仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 四相位移键控&#xff08;QPSK&#xff0c;Quadrature Phase Shift Keying&#xff09;是一种重要的数字调制技术&#xff0c;它通过改变信号的相位来传输数据。与其他调制技术相比&#xff0c;QPSK在相同的带宽条件下能够传…

某象滑块js逆向(主要是声明拿过我代码的进来)

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018…

MySQL中json类型的字段

有些很复杂的信息&#xff0c;我们一般会用扩展字段传一个json串&#xff0c;字段一般用text类型存在数据库。mysql5.7以后支持json类型的字段&#xff0c;还可以进行sql查询与修改json内的某个字段的能力。 1.json字段定义 ip_info json DEFAULT NULL COMMENT ip信息, 2.按…

python脚本实现全景站点矩阵转欧拉角

效果 脚本 import re import numpy as np import math import csv from settings import * # 以下是一个示例代码,可以输入3*3旋转矩阵,然后输出旋转角度:# ,输入3*3旋转矩阵# 计算x,y,z旋转角def rotation_matrix_to_euler_angles(R):

缓存相关问题:雪崩、穿透、预热、更新、降级的深度解析

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 1. 缓存雪崩 1.1 问题描述 1.2 解决方案 1.2.1 加锁防止并发重建缓存 2. 缓存穿透 2.1 问题描述 2.2 解决方案 2.2.1 …