Java数据结构之树与二叉树

news2024/11/18 21:25:29

2.3 二叉树的性质(重点,选择题常考)

2.4 二叉树的链式存储

2.5 二叉树的基本操作

2.5.1 前提说明

2.5.2 二叉树的遍历

2.5.3 二叉树基本操作的实现(重点)


1. 树形结构

========

1.1 树的概念


树是一种非线性的数据结构,它是由n个(n>=0)个有限节点组成一个具有层次关系的集合。它的形状像一颗倒挂的树,根在上,叶在下。

特点:

· 有一个特殊的结点称为根节点,根节点没有前驱结点

· 除根节点外,其余结点被分成M(M>0)个互不相交的集合T1,T2,…,Tm,其中每一个集合又是一颗与树类似的字树。每棵子树的根节点有且只有一个前驱,可以没有或者多个后继

· 树是递归定义的

**注意:**在树形结构中,子树不能有交集,否则就不是树形结构

重要概念:

结点的度:一个结点含有子树的个数

树的度:所有结点的度的最大值称为树的度

叶子结点或终端结点:度为0的结点

双亲结点或父亲结点:若一个结点含有子节点,则这个结点为其子结点的双亲结点

孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点

根结点:树中没有双亲结点的结点

结点的层次:从根开始定义,根为第一层,根的子结点为第二层,以此类推

树的高度或深度:树中结点层次的最大值

森林:由m(m>0)棵互不相交的树组成的集合称为森林

1.2 树的表示形式(简单了解


树的结构相对于线性表比较复杂,要存储起来也比较麻烦,这里有几种表示方法:双亲表示法,孩子表示法,孩子双亲表示法,孩子兄弟表示法等,这里只简单了解最常用的孩子兄弟表示法。

class Node{

int val; //存储的数据

Node firstChild; // 第一个孩子引用,一般称之为左结点,Node left

Node nextBrother; //下一个兄弟引用,一般称之为右结点,Node right

}

2. 二叉树(重点)

===========

2.1 概念


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

1. 为空

2. 由一个结点加上两颗别称为左子树和右子树的二叉树组成

从图中可以看出:

1. 二叉树不存在度大于2的结点

2. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

注意:对于任意的二叉树都是由以下几种情况复合而成的:

这里展示一张照片—大自然的奇观:现实中的二叉树

2.2 两种特殊的二叉树


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

2.完全二叉树:它是一种效率很高的数据结构,完全二叉树是由满二叉树引出来的。对于深度为k,有n个结点的二叉树,当且仅当每一个结点都与深度为k的满二叉树中编号从0至n-1的结点一一对应时称之为完全二叉树,满二叉树是一种特殊的完全二叉树

2.3 二叉树的性质(重点,选择题常考)


1. 规定根结点的层数是1,则一颗非空二叉树的第i层上最多2^(i-1)个结点

2. 规定只有根结点的二叉树深度为1,则深度为k的二叉树的最大结点数是2^k - 1

3. 对于任何一颗二叉树,如果其叶结点个数为n0,度为2的结点个数为n2,则n0=n2+1

4. 具有n个结点的二叉树的深度为log2(n+1)向上 取整 ,

5. 对于有n个结点的完全二叉树,如果按照从左至右,从上往下的顺序对所有结点从0开始编号,则对于序号为i的结点有:

· 若i>0,双亲序号:2i+1;i=0,i为根节点编号,无双亲结点

· 若2i+1<n,左孩子序号:2i+1,否则无左孩子

· 若2i+2<n,右孩子序号:2i+2,否则无右孩子

2.4 二叉树的链式存储


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

//孩子表示法

class Node{

int val; //数据域

Node left; //左孩子的引用

Node right; //右孩子引用

}

//孩子双亲表示法

class Node{

int val;

Node left;

Node right;

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

}

2.5 二叉树的基本操作


2.5.1 前提说明

从图结合概念可以看出,二叉树是递归定义的,后面基本操作都是按照该概念实现的

我们需要先创建一颗二叉树,这里手动快速创建一颗简单的二叉树:

public class MyTreeBlog {

public class BTNode{

int val;

BTNode left;

BTNode right;

public BTNode(int val){

this.val = val;

}

}

private BTNode root;

public void createBinaryTree(){

BTNode node1 = new BTNode(1);

BTNode node2 = new BTNode(2);

BTNode node3 = new BTNode(3);

BTNode node4 = new BTNode(4);

BTNode node5 = new BTNode(5);

BTNode node6 = new BTNode(6);

root = node1;

node1.left = node2;

node1.right = node4;

node2.left = node3;

node4.left = node5;

node4.right = node6;

}

}

注意:上述代码不是创建二叉树的方式,创建二叉树后面会介绍

2.5.2 二叉树的遍历

1. 前中后序遍历

遍历就是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问,访问结点所做的操作依赖于具体的应用问题(比如:打印结点内容),遍历是二叉树最重要的操作之一,是二叉树上进行其他运算的基础。

N代表根结点,L代表根结点的左子树,R代表根节点的右子树,则根据遍历根节点的先后次序有以下几种遍历方式:

**NLR:前序遍历:**根节点—根的左子树—根的右子树

**LNR:中序遍历:**根的左子树—根结点—根的右子树

**LRN:后序遍历:**根的左子树—根的右子树—根结点

前序遍历结果:1 2 3 4 5 6

中序遍历结果:3 2 1 5 4 6

后序遍历结果:3 2 5 6 4 1

2. 层序遍历

除了上述三种遍历,还可以对二叉树进行层序遍历。根节点所在的层数为第一层,自上到下,自左到右,逐层访问树的结点的过程就是层序遍历

2.5.3 二叉树基本操作的实现(重点)

1. 二叉树的前中后序遍历:采用递归的方式遍历

public void preOrder(BTNode root){

if(root!=null){

System.out.print(root.val+" ");//遍历根

preOrder(root.left); //递归遍历左子树

preOrder(root.right); //递归遍历右子树

}

}

public void inOrder(BTNode root){

if(root!=null){

inOrder(root.left); //递归遍历左子树

System.out.print(root.val+" ");//遍历根

inOrder(root.right); //递归遍历右子树

}

}

public void postOrder(BTNode root){

if(root!=null){

postOrder(root.left); //递归遍历左子树

postOrder(root.right); //递归遍历右子树

System.out.print(root.val+" ");//遍历根

}

}

2. 二叉树的层序遍历:这里需要借助队列完成

public void levelOrder(BTNode root){

if(root==null){

return; //根为空直接返回

}

Queue q = new LinkedList<>();

q.offer(root); //先将根入队列

while(!q.isEmpty()){ //队列不为空时,循环

BTNode cur = q.poll(); //根出队列

System.out.print(cur.val+" ");

if(cur.left!=null){ //根有左子树,将左子树的根入队列

q.offer(root.left);

}

if(cur.right!=null){ //根有右子树,将右子树的根入队列

q.offer(root.right);

}

}

System.out.println();

}

图解:图比较丑,但是能说明情况

3. 获取二叉树中结点的个数

二叉树结点的个数=根的左子树结点的个数+根的右子树结点的个数+1(这个1就是根),所以直接一个递归就解决问题了

public int size(BTNode root){

if(root==null){

return 0;

}

return 1+size(root.left)+size(root.right);

}

4. 获取二叉树中叶子结点的个数

叶子结点就是该结点的左子树为空,右子树为空,所以当遇到此节点时返回1,递归返回所有该结点的总数

public int getLeafNode(BTNode root){

if(root==null){

return 0;

}

if(root.left == null && root.right == null){

return 1;

}

return getLeafNode(root.left)+getLeafNode(root.right);

}

5. 获取二叉树中第k层结点的个数

public int getLevelNode(BTNode root,int k){

if(root==null||k<0){ //判断参数

return 0;

}

if(k1){ //如果k1,则只有根返回1

return 1;

}

//递归

return getLevelNode(root.left,k-1) + getLevelNode(root.right,k-1);

}

6. 获取二叉树的高度

将此二叉树的左子树的高度与右子树的高度进行比较,较大的高度+1就是此二叉树的高度

public int height(BTNode root){

if(root==null){

return 0;

}

int leftHeight = height(root.left);

int rightHeight = height(root.right);

}

if(root.left == null && root.right == null){

return 1;

}

return getLeafNode(root.left)+getLeafNode(root.right);

}

5. 获取二叉树中第k层结点的个数

public int getLevelNode(BTNode root,int k){

if(root==null||k<0){ //判断参数

return 0;

}

if(k1){ //如果k1,则只有根返回1

return 1;

}

//递归

return getLevelNode(root.left,k-1) + getLevelNode(root.right,k-1);

}

6. 获取二叉树的高度

将此二叉树的左子树的高度与右子树的高度进行比较,较大的高度+1就是此二叉树的高度

public int height(BTNode root){

if(root==null){

return 0;

}

int leftHeight = height(root.left);

int rightHeight = height(root.right);

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

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

相关文章

[附源码]JAVA毕业设计体检系统(系统+LW)

[附源码]JAVA毕业设计体检系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xf…

JavaScript实现一段时间之后关闭广告

JavaScript实现一段时间之后关闭广告 案例池子&#xff1a; JS实现鼠标悬停变色 JavaScript中的排他算法实现按钮单选 JavaScript中的localStorage JavaScript中的sessionStorage JavaScript实现网页关灯效果 JavaScript实现一段时间之后关闭广告 JavaScript实现按键快速获…

水下机器人双机械手系统动态建模与控制仿真(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 水下机器人-机械手系统&#xff08;Underwater vehicle-manipulator systems, UVMS&#xff09;可以完成除观测之外的水下采样…

[论文解析] HeadNeRF: A Realtime NeRF-based Parametric Head Model

code link: https://github.com/CrisHY1995/headnerf 相关连接&#xff1a; https://blog.csdn.net/c9Yv2cf9I06K2A9E/article/details/124874717 来自中科大张举勇教授课题组提出了 HeadNeRF&#xff0c;一种基于 NeRF 的高效全息人脸头部参数化模型&#xff0c;该工作发表…

阿里面试Redis最常问的三个问题:缓存穿透、缓存击穿、缓存雪崩(带答案)

一、缓存穿透 如上图&#xff0c;正常情况下&#xff0c;如果用户在redis缓存中没有查询到自己想要的数据&#xff0c;就会去mysql数据库中查询。如果mysql数据库中也没有&#xff0c;在没有任何措施下&#xff0c;用户一定会不断的去mysql数据库中查询&#xff0c;随着时间的推…

风控串行组合模型及其信用评估场景实践

在信贷风控中&#xff0c;数据建模好像是“家常便饭”那么普通且重要&#xff0c;而我们最终享用“饭菜”的美味程度&#xff0c;在数据“食材”较完备的情况下&#xff0c;完全取决于我们建模的方法。根据实际业务场景&#xff0c;采用合理且有效的建模思路&#xff0c;可以较…

诊断和响应故障_RMAN数据修复概念

1&#xff0e;RMAN数据修复概述 1.1&#xff0e;关于需要数据修复的问题 虽然有几种问题会中止Oracle数据库的正常操作或影响数据库I/O操作&#xff0c;只有以下几种情况要求DBA介入和数据修复&#xff1a;用户错误&#xff0c;应用程序错误和介质故障。 1.1.1&#xff0e;关…

[附源码]计算机毕业设计JAVA中达小区物业管理系统

[附源码]计算机毕业设计JAVA中达小区物业管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

【LeetCode】1775. 通过最少操作次数使数组的和相等

题目描述 给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间&#xff08;包含 1 和 6&#xff09;。 每次操作中&#xff0c;你可以选择 任意 数组中的任意一个整数&#xff0c;将它变成 1 到 6 之间 任意 的值&#xff08;包含 1 和 6&…

LaTeX行距以及字体大小

LaTeX行距以及字体大小1、行距2、字体大小1、全局模式2、局部模式1、行距 一&#xff1a;改变全文行距 导言部分前加入\linespread{2.0}即可&#xff0c;代表全文两倍行距。 二&#xff1a;部分段落需要改变行距 \usepackage{setspace} \begin{spacing}{2.0}&#xff08;内…

js_实现网页自动跳转

网页自动跳转实现网页定时自动跳转实现网页定时自动跳转 效果&#xff1a; 10秒后自动跳转到网易云音乐的页面 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>.box{wi…

什么是 NFT 洗盘交易:洗盘交易背后的原理

2022年12月 CoinGecko 与 Footprint Analytics 联合报告 Data Source&#xff1a;Footprint Analytics 市场上有一种说法是&#xff0c;整个NFT 市场的交易本质是欺诈性的&#xff0c;并且是由洗盘交易者操纵出来的假象。我们经常看到许多 媒体头条 在推动这种说法。毕竟&…

HTML学生个人网站作业设计:宠物网站设计——萌宠有家(5页) HTML+CSS 简单DIV布局宠物介绍网页模板代码 DW学生个人网站制作成品下载

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

动态规划:01背包问题例题(leetcode+cpp实现)

文章目录分割等和子集最后一块石头的重量前情回顾&#xff1a; 动态规划(4)&#xff1a;01背包问题详解 分割等和子集 力扣传送门&#xff1a; https://leetcode.cn/problems/partition-equal-subset-sum/ 题目描述&#xff1a; 给你一个整数数组&#xff0c;将这个数组里的…

论文速读Backbone系列一:点云Transformer结合、PointNet++改进、点云卷积核设计

如有错误&#xff0c;恳请指出。 对一些经典论文进行快速思路整理&#xff0c;以下内容主要关注的是3d点云的backbone设计&#xff0c;包括transformer的应用&#xff0c;卷积核的设计&#xff0c;PointNet网络的改进。 文章目录一、Transformer改进1. 《PCT: Point Cloud Tran…

Wireshark高级特征

1&#xff0c;端点和网络会话 想要让网络通信正常进行&#xff0c;你必须至少拥有两台设备进行数据流的交互。端点&#xff08;endpoint&#xff09;就是指网络上能够发送或接收数据的一台设备。两个端点之间的通信被称之为会话&#xff08;conversation&#xff09;。Wiresha…

Python中如何选择Web开发框架?

Python开发中Web框架可谓是百花齐放,各式各样的web框架层出不穷,那么对于需要进行Python开发的我们来说,如何选择web框架也就变成了一门学问了。本篇文章主要是介绍目前一些比较有特点受欢迎的Web框架,我们可以根据各个Web框架的特性进行选择应用。 Django Django是市面上…

利用Astar算法实现飞行轨迹的三维路径规划(基于Matlab代码实现)

目录 1 概述 1.1研究背景 2 运行结果 3 Matlab代码实现 4 参考文献 1 概述 随着自动化技术的发展,现代航空技术水平有了前所未有的提高,促进了无人机在军事、民用领域的广泛应用。航迹规划技术作为无人机任务规划的关键技术,一直都是无人机领域的一大研究热点。无人机航迹规划是…

Synopsys Sentaurus TCAD系列教程之-- Svisual《一》看图工具

Svisual Svisual作为独立的模块&#xff0c;可以实现Inspect对于节点.plt曲线的查看&#xff0c;也可以实现TecplotSV的.tdr看图功能&#xff0c;还可以进行自动化操作。 当作看图工具使用 - 当作一维曲线看图工具&#xff08;.plt,Inspect) 1.1 打开&#xff1a;Sdevice模块…

[附源码]Python计算机毕业设计SSM基于自组网的空地一体化信息系统(程序+LW)

[附源码]Python计算机毕业设计SSM基于自组网的空地一体化信息系统&#xff08;程序LW) 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff0…