Java二叉树(1)

news2024/11/15 16:00:06

🐵本篇文章将对二叉树的相关概念、性质和遍历等知识进行讲解


  一、什么是树

在讲二叉树之前,先了解一下什么是树:树是一种非线性结构,其由许多节点和子节点组成,整体形状如一颗倒挂的树,比如下图:

A就是这棵树的根,BDEF、D、CG、G等都可以看作这颗树的一颗子树,在树形结构中子树之间不能由交集,否则不能称为树,如下图就不是树:

二、树的相关概念

1. 结点的度:一个结点含有子结点的个数称为该结点的度,如A的度为2,B的度3,D的度为0

2. 树的度:所有结点度的最大值称为树的度,比如上树中B的度最大,则该树的度为3

3. 叶子结点/终端结点:度为0的结点称为叶子结点,如上树中的D E F G

4. 双亲结点/父结点:一个结点的前驱结点称为该结点的父结点,如B的父结点为A

5. 孩子结点/子结点:一个结点的后继结点称为该结点的子结点,如B的子结点有D E F

6. 根结点:没有双亲结点的结点称为根结点,上树的根结点为A

7. 结点的层次:从根结点那一层开始定义,A为第一层(有时是从0开始),B C所处第二层,依此类推

8. 树的高度:树中结点的最大层次为称为该树的高度,上树的高度为3

三、二叉树

二叉树是一种特殊的树,一棵所有结点的度都小于等于2的树称为二叉树

二叉树特别讲究顺序,如上图中如果G为C的左孩子,则又是一颗完全不同的二叉树

3.1 满二叉树

从根结点开始,从上到下从左到右每一层都放满了结点的树称为满二叉树,如下图:

若一个满二叉树有k层,则其每一层有2^(k - 1)个结点,整个树共有(2^k) - 1个结点

3.2 完全二叉树

从根结点开始,从上到下从左到右依次存放结点,最后一层可以不满,这样的二叉树称为完全二叉树,如下图:

下图不是完全二叉树:

3.3 二叉树的性质

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

2. 若规定根结点的层数为1,则一棵非空二叉树的最大结点数是(2^i) - 1

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

4. 具有n个结点的完全二叉树高度为:log₂(n + 1)向上取整,如:3.x为4;或者log₂(n) + 1向下取整,如3.x为3

5. 具有n个结点的完全二叉树,从上到下从左到右依次编号,规定根结点的编号为0,则编号为i的结点:双亲编号:(i - 1) / 2;左孩子编号:2i + 1,若2i + 1 > n则无左孩子;右孩子编号:2i + 2,若2i + 2 > n则无右孩子

下面讲一道例题:

一个具有767个节点的完全二叉树,其叶子节点个数为()
A 383
B 384
C 385
D 386

【解析】由于二叉树中的结点的度都不大于2,所以设度为0,1,2的结点的个数分别为n0,n1,n2,则n0 + n1 + n2 = 767,由性质3:n0 = n2 + 1得2*n0 + n1 = 768,在完全二叉树中,度为1的结点只可能有1个或0个,如果n1 = 1,则n0不是一个整数,所以n1只可能为0,经计算n0 = 384

3.4 二叉树的存储

二叉树有两种存储方式,分别为链式存储和顺序存储,这里主要讲解链式存储,接下来用代码以穷举的方式先构造下面这个二叉树

public class BinaryTree {
    static class TreeNode{
        public char val; 
        public TreeNode left; //指向该结点的左孩子
        public TreeNode right; //指向该结点的右孩子

        public TreeNode(char val) {
            this.val = val;
        }
    }
}

接下来以穷举的方式构造二叉树

    public TreeNode creatTree() {
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');

        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        E.right = H;
        C.left = F;
        C.right = G;

        return A; //返回这个树的根结点
    }

3.5 二叉树的遍历

二叉树共有3种遍历方式,分别为:先序遍历、中序遍历、后序遍历,接下来会逐个讲解 

3.5.1 先序遍历

先序遍历一个树,按照根、左子树、右子树的顺序遍历这个树,直接看例子:

先遍历这个树的根A,之后遍历A的左B,由于B又是一个子树的根,所以要继续遍历B的左,B的左为空,那就遍历B的右:F,F是一个子树的根,所以要继续遍历F的左:D,D的左右都为空,那么F的左子树全部遍历完毕,接着遍历F的右,F的右为空,那么B的右全部遍历完毕,那接着就是A的左全部遍历完毕,之后遍历A的右:C,C又是一个子树的根,所以要继续遍历C的左,C的左为空,那就遍历C的右:G,G的左右都为空,至此A的右也全部遍历完毕,那么整个二叉树遍历完毕整个遍历的序列为:A B F D C G

3.5.2 中序遍历

先序遍历一个树,按照左子树、根、右子树的顺序遍历这个树,直接看例子:

先遍历A的左,由于A的左也是一个子树,所以要遍历这个子树的左:空,这个子树的左遍历完就要遍历这个树的根:B,之后遍历这个子树的右:F D,这也是一个子树,所以要先遍历这个子树左:D,然后遍历根:F,最后是右,右为空,那么整个二叉树的左遍历完毕,接着遍历根:A,然后遍历右子树:C G,先遍历这个树的左,左为空,然后遍历根:C,最后是右:G,至此整个二叉树遍历完毕,整个遍历的序列为:B D F A C G

3.5.3 后序遍历

先序遍历一个树,按照左子树、右子树、根的顺序遍历这个树,直接看例子:

先遍历这个二叉树的左子树:B F D,这也是一个树,所以先遍历这个树的左,左为空,然后遍历这个树的右子树:F D,这也是一个树,所以要先遍历这个树的左:D,然后遍历这个树的右,右为空,最后是根:F,那么B F D这个子树的右遍历完毕,然后遍历B F D这个树的根:B,至此整个树的左子树遍历完毕,然后遍历这个树的右子树:C G,先遍历这个树的左,左为空,然后遍历右:G,再遍历根C,最后遍历整个树的根:A,整个树遍历完毕,整个遍历的序列为:D F B G C A

3.6 代码实现二叉树的遍历

二叉树的三种遍历需要用递归的思想实现

先序遍历:

    public void preOrder(TreeNode root) {
        if (root == null) { //如果根为空则直接返回
            return;
        }

        System.out.print(root.val +" ");
        preOrder(root.left); //以根的左孩子为新的根继续遍历
        preOrder(root.right); //以根的右孩子为新的根继续遍历
    }

root为null后返回至上一个方法,遍历D的右孩子,右孩子也为空,则以D为根的方法结束返回至上一个方法,遍历B的右孩子

右子树也是同样的道理

中序遍历:

    public void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }

        preOrder(root.left);
        System.out.print(root.val +" ");
        preOrder(root.right);
    }

后序遍历:

    public void postOrder(TreeNode root) {
        if (root == null) {
            return;
        }

        preOrder(root.left);
        preOrder(root.right);
        System.out.print(root.val +" ");
    }

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

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

相关文章

探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,并且坚持默默的做事。 备忘录模式揭秘-实现时光回溯、一键还原、后悔药和穿越时空隧道 文章目录 一、案例场景&…

Docker架构概述

Docker是基于Go语言实现的开源容器项目,能够把开发的应用程序自动部署到容器的开源的应用容器引擎。Docker的构想是要实现"Build, Ship and Run Any App, Anywhere",即通过对应用的封装(Packaging)、分发(Distribution)、部署(Deployment)、运…

Autosar Appl介绍

AUTOSAR架构中的应用层 AUTOSAR 应用层构成AUTOSAR 架构中的最顶层,被认为对所有车辆应用至关重要。AUTOSAR 标准使用“组件”概念指定应用层实现。 在谈论应用层实现时,应该考虑的三个最重要的部分是: AUTOSAR 应用软件组件这些组件的 AUTOSAR 端口AUTOSAR 端口接口 AUTOS…

LeetCode受限条件下可到达节点的数目

题目描述 现有一棵由 n 个节点组成的无向树,节点编号从 0 到 n - 1 ,共有 n - 1 条边。 给你一个二维整数数组 edges ,长度为 n - 1 ,其中 edges[i] [ai, bi] 表示树中节点 ai 和 bi 之间存在一条边。另给你一个整数数组 restr…

Game With Sticks

最近思维实在是不活跃。。。。。。 题目链接&#xff1a;Submit - Codeforces 解题思路&#xff1a; 如果n > m,交换 直接判断n就行&#xff0c;偶数M赢&#xff0c;奇数A赢 下面是c代码&#xff1a; #include<iostream> using namespace std; int main() {int n…

iZotope RX 10:专业音频修复,尽在指尖 mac/win版

iZotope RX 10是一款革命性的音频修复和增强软件&#xff0c;它为音频专业人士、电影制片人、音乐制作人和广播工作者提供了无与伦比的工具集&#xff0c;以处理和改善各种音频问题。 iZotope RX 10 软件获取 RX 10的核心是其先进的音频分析和修复算法&#xff0c;这些算法能够…

经典目标检测网络Yolo——原理部分

目标检测问题 分为两个子问题: 找到图片中哪些位置、哪些区域含有目标对象识别这些区域中的目标对象是什么基于CNN的目标检测算法能够很好的解决第二个问题,在一张图片仅含一个对象,且该对象占据了整张图片绝大部分面积时,基于CNN的对象识别算法具有很高的准确率。 一种定…

基于YOLOv的目标追踪与无人机前端查看系统开发

一、背景与简介 随着无人机技术的快速发展&#xff0c;目标追踪成为无人机应用中的重要功能之一。YOLOv作为一种高效的目标检测算法&#xff0c;同样适用于目标追踪任务。通过集成YOLOv模型&#xff0c;我们可以构建一个无人机前端查看系统&#xff0c;实现实时目标追踪和可视化…

搜素题目(蓝桥杯 C++ 代码+注解)

目录 题目一&#xff08;小朋友崇拜圈&#xff09;&#xff1a; 代码&#xff1a; 题目二&#xff08;穿越雷区&#xff09;&#xff1a; 代码&#xff1a; 题目三&#xff08;分考场&#xff09;&#xff1a; 代码&#xff1a; 题目四&#xff08;受伤的皇后&#xff09…

c++之旅——第三弹

大家好啊&#xff0c;这里是c之旅第三弹&#xff0c;跟随我的步伐来开始这一篇的学习吧&#xff01; 如果有知识性错误&#xff0c;欢迎各位指正&#xff01;&#xff01;一起加油&#xff01;&#xff01; 创作不易&#xff0c;希望大家多多支持哦&#xff01; 一.命名空间;…

基于springboot实现图书馆管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现图书馆管理系统演示 摘要 电脑的出现是一个时代的进步&#xff0c;不仅仅帮助人们解决了一些数学上的难题&#xff0c;如今电脑的出现&#xff0c;更加方便了人们在工作和生活中对于一些事物的处理。应用的越来越广泛&#xff0c;通过互联网我们可以更方便地…

OpenCV 4基础篇| OpenCV图像的拼接

目录 1. Numpy (np.hstack&#xff0c;np.vstack)1.1 注意事项1.2 代码示例 2. matplotlib2.1 注意事项2.2 代码示例 3. 扩展示例&#xff1a;多张小图合并成一张大图4. 总结 1. Numpy (np.hstack&#xff0c;np.vstack) 语法结构&#xff1a; retval np.hstack(tup) # 水平…

从嵌入式Linux到嵌入式Android

最近开始投入Android的怀抱。说来惭愧&#xff0c;08年就听说这东西&#xff0c;当时也有同事投入去看&#xff0c;因为恶心Java&#xff0c;始终对这玩意无感&#xff0c;没想到现在不会这个嵌入式都快要没法搞了。为了不中年失业&#xff0c;所以只能回过头又来学。 首先还是…

考研数学——高数:微分方程

一、一阶线性微分方程 两种形式&#xff1a; 非齐次&#xff1a; 齐次&#xff1a; 推导过程 推导公式的过程一般由特殊到一般&#xff1a;所以先求解齐次方程的解 &#xff08;然后对等式两边同时积分&#xff09; 再来求非齐次方程的解&#xff0c;由…

基于springboot实现保险信息网站系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现保险信息网站系统演示 摘要 随着互联网的不断发展&#xff0c;现在人们获取最新资讯的主要途径来源于网上新闻&#xff0c;当下的网上信息宣传门户网站的发展十分的迅速。而保险产品&#xff0c;作为当下人们非常关注的一款能够给人们带来医疗、生活、养老或…

VUE3:省市区联级选择器

一、实现效果 二、代码展示 <template><div class"page"><select v-model"property.province"><option v-for"item in provinces" :key"item">{{ item }}</option></select><select v-model&…

python matplotlib figure-->限制elev旋转角度

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 当前限制的旋转范围是0-60 import pandas as pd import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D# 读取Excel文件中的空间坐标数据 df pd.read_excel(煤仓模拟参数.xl…

更改elementui的箭头图片以及位置

//更改箭头位置 .el-tree-node__content > .el-tree-node__expand-icon {position: absolute;right: 12px; }//更改箭头图片 .el-tree-node__expand-icon {transform: rotate(-90deg); } .el-tree-node__expand-icon.expanded {transform: rotate(0deg); } // 有子节点 且已…

C语言-指针(上)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 本篇文章将为大家介绍C语言中的核心内容-指针&#xff0c;指针在C语言的中知识内容比…

Ubuntu23.10禁用Wayland

禁用前 编辑custom.conf文件 sudo vim /etc/gdm3/custom.conf 去掉WaylandEnablefalse前的#号 保存退出 重启系统 生效: 成功转换为X11