【数据结构】——二叉树(JAVA)

news2024/11/25 15:59:28
  • 一、二叉树的定义
  • 二、二叉树的形态
  • 三、二叉树的性质
  • 四、二叉树的存储
  • 五、二叉树的创建与遍历(递归)

一、二叉树的定义

二叉树(Binary Tree) 是由n个结点构成的有限集(n≥0),n=0时为空树,n>0时为非空树。对于非空树root:

  • 有且仅有一个根结点;
  • 除根结点外的其余结点又可分为两个不相交的子集rootL和rootR,分别称为root的左子树和右子树,且rootL和rootR本身就是二叉树。

很明显该定义属于递归定义,所以有关二叉树的操作使用递归往往更容易理解和实现。

从定义也可以看出二叉树与一般树的区别主要是两点,一是每个结点的度最多为2;二是结点的子树有左右之分,不能随意调换,调换后又是一棵新的二叉树。

二、二叉树的形态

五种基本形态

从上面二叉树的递归定义可以看出,二叉树或为空,或为一个根结点加上两棵左右子树,因为两棵左右子树也是二叉树也可以为空,所以二叉树有5种基本形态:

三种特殊形态

三、二叉树的性质

四、二叉树的存储

存的目的是为了取,而取的关键在于如何通过父结点拿到它的左右子结点,不同存储方式围绕的核心也就是这。

顺序存储

使用一组地址连续的存储单元存储,例如数组。为了在存储结构中能得到父子结点之间的映射关系,二叉树中的结点必须按层次遍历的顺序存放。具体是:

对于完全二叉树,只需要自根结点起从上往下、从左往右依次存储。
对于非完全二叉树,首先将它变换为完全二叉树,空缺位置用某个特殊字符代替(比如#),然后仍按完全二叉树的存储方式存储。
假设将一棵二叉树按此方式存储到数组后,左子结点下标=2倍的父结点下标+1,右子节点下标=2倍的父结点下标+2(这里父子结点间的关系是基于根结点从0开始计算的)。若数组某个位置处值为#,代表此处对应的结点为空。

可以看出顺序存储非常适合存储接近完全二叉树类型的二叉树,对于一般二叉树有很大的空间浪费,所以对于一般二叉树,一般用下面这种链式存储。

链式存储

对每个结点,除数据域外再多增加左右两个指针域,分别指向该结点的左孩子和右孩子结点,再用一个头指针指向根结点。对应的存储结构:
在这里插入图片描述

五、二叉树的创建与遍历(递归)

二叉树由三个基本单元组成:根结点,左子树,右子树,因此存在6种遍历顺序,若规定先左后右,则只有以下3种:
1.先序遍历
若二叉树为空,则空操作;否则:
(1)访问根结点
(2)先序遍历左子树
(3)先序遍历右子树

2.中序遍历
若二叉树为空,则空操作;否则:
(1)中序遍历左子树
(2)访问根结点
(3)中序遍历右子树

3.后序遍历
若二叉树为空,则空操作;否则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点

从上可以看出先中后其实是相对根结点来说。

对于下面这棵二叉树,其遍历顺序:
先序:ABDEHCFIG
中序:DBHEAFICG
后序:DHEBIFGCA

下面是将以下二叉树的顺序存储[A,B,C,D,E,F,G,#,#,H,#,#,I]转换为链式存储的代码,结点不存在用字符#表示,并分别遍历。

Java代码

public class BinaryTree {

    static class TreeNode {
        public char val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(char val) {
            this.val = val;
        }
    }
    public TreeNode createTree() {
        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;
        C.left = F;
        C.right = G;
        E.right = H;
        return A;
    }

      // 前序遍历
    public void preOrder(TreeNode root) {
        if(root == null) return;
        System.out.print(root.val+" ");
        preOrder(root.left);
        preOrder(root.right);
    }

    // 中序遍历
    public void inOrder(TreeNode root) {
        if(root == null) return;
        inOrder(root.left);
        System.out.print(root.val+" ");
        inOrder(root.right);
    }

    // 后序遍历
    public void postOrder(TreeNode root) {
        if(root == null) return;
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val+" ");
    }


    public int nodeSize;
    /**
     * 遍历思路
     * 获取当前二叉树的节点个数
     * @param root
     * @return
     */
    public void getNodeSize(TreeNode root) {
        if(root == null) return ;
        nodeSize++;
        getNodeSize(root.left);
        getNodeSize(root.right);
    }

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

    public int leafCount;
    /**
     * 获取叶子节点的个数 - 遍历思路
     * @param root
     */
    public void getLeafNodeCount(TreeNode root) {
        if(root == null) {
            return;
        }
        if(root.left == null && root.right == null) {
            leafCount++;
        }
        getLeafNodeCount(root.left);
        getLeafNodeCount(root.right);
    }

    /**
     * 获取叶子节点的个数  - 子问题
     * @param root
     * @return
     */
    public int getLeafNodeCount2(TreeNode root) {
        if(root == null) {
            return 0;
        }
        if(root.left == null && root.right == null) {
            return 1;
        }
        return getLeafNodeCount2(root.left) +
                getLeafNodeCount2(root.right);
    }

}

仔细观察先序、中序、后序的结点访问顺序可以发现:
在这里插入图片描述

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

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

相关文章

如何在Linux 上运行 SciChart WPF图表控件?

SciChart – 一个跨平台图表库,可实现 Windows Presentation Foundation (WPF)、JavaScript 以及原生 iOS (Swift/Objective-C) 和 Android (Java/Kotlin),基于代号为 Visual Xccelerator 的专有 C 渲染引擎。这提供了 SciChart 众所周知的速度和性能&am…

网络编程项目(速递项目)

目录 一、功能要求 服务器 用户客户端 快递员客户端 二、演示效果 1.注册,登录,注销功能演示 ​编辑 2.用户功能演示 ​编辑 3.快递员功能演示 三、项目代码 1.头文件: 2.服务器: 3.用户端: 4..快递员端&…

Vue2 day-04

目录 一. vue组件 1.1 为什么用组件 1.2 vue组件 1.3 基础使用 1.4 全局 - 注册使用 1.5 局部 - 注册使用 1.4 用less写的样式 二. Vue组件之间传值(重点) 2.1 父组件向子组件传值 2.2 子组件向父组件传值 2.3 兄弟之间的传递 三. vue生命周期 3.1 含义 3.2 钩子…

SprinBoot+Vue智慧农业专家远程指导系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…

Transformer、RNN和SSM的相似性探究:揭示看似不相关的LLM架构之间的联系

通过探索看似不相关的大语言模型(LLM)架构之间的潜在联系,我们可能为促进不同模型间的思想交流和提高整体效率开辟新的途径。 尽管Mamba等线性循环神经网络(RNN)和状态空间模型(SSM)近来备受关注,Transformer架构仍然是LLM的主要支柱。这种格局可能即将发生变化:像Jamba、Samb…

红队C2工具Sliver探究与免杀

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330&scene21#wechat_redirect 《网安面试指南》…

【QCA(定性比较分析)组态研究】01 基础入门

【目录】 1.理论入门1.1和个案分析的区别1.2 QCA的特点因果非对称:殊途同归:1.3 什么时候用到QCA2.QCA的一般步骤3.QCA论文精读1.理论入门 QCA(定性比较分析)是一种探索性研究方法,旨在通过系统地比较不同案例的条件组合,识别出影响结果的因果关系。它结合了定性和定量分…

HarmonyOS Next系列之实现一个左右露出中间大两边小带缩放动画的轮播图(十二)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现(一) HarmonyOS Next 系列之验证码输入组件实现(二) HarmonyOS Next 系列之底部标签栏TabBar实现(三) HarmonyOS Next 系列之HTTP请求封装和Token…

ASP.NET Core 中间件

一、什么是中间件? 中间件 是一种装配到 ASP.NET Core 应用程序请求处理管道中的软件组件,用于处理 HTTP 请求和响应。 每个中间件组件可以: 选择是否将请求传递到下一个中间件:通过调用 next() 或者不调用 next() 来决定是否将…

HTML5中的数据存储sessionStorage、localStorage

第8章 HTML5中的数据存储 之前通常使用Cookie存储机制将数据保存在用户的客户端。 H5增加了两种全新的数据存储方式:Web Stroage和Web SQL Database. 前者用于临时或永久保存客户端少量数据,后者是客户端本地化的一套数据库系统。 8.1 Web Storage存…

日本“大米荒”持续!政府再次拒绝投放储备米

KlipC报道:日本多地从7月开始出现“大米荒”,有部分新米上市,但是许多超市的大米仍然存在断购或限购的情况,并且部分新米价格上涨至去年同期的两倍。大阪府官员再次呼吁日本中央政府尽快投放储备米以缓解供应紧张,但遭…

Dynamics CRM Ribbon Workbench-the solution contains non-entity components

今天在一个低版本的环境里准备用Ribbon Workbench去编辑一个按钮时,遇到了如下错误 一开始没当回事,以为是我的解决方案问题,去检查了下,只有一个组件,并且哪怕我把组件换成了某个实体也不行,尝试了其他任何…

开源NAS系统-OpenMediaVault(OMV)共享存储网盘搭建和使用(保姆级教程)

1、OpenMediaVault简介 OpenMediaVault,简称:OMV,是由原 FreeNAS 核心开发成员 Volker Theile 发起的基于 Debian Linux 的开源 NAS 操作系统,主要面向家庭用户和小型办公环境。 OpenMediaVault是一款基于Debian Linux的开源网络附加存储(NAS)操作系统,它提供了强大的存…

酒店智能轻触开关:智慧化的创新实践

在追求高品质住宿体验的今天,酒店智能轻触开关作为智慧酒店建设的关键一环,正逐步成为提升酒店服务品质、优化运营效率、增强顾客满意度的有力工具。本文将深入探讨酒店智能轻触开关如何助力酒店实现智慧化管理,以及它所带来的多重变革。 一、…

大模型时代下,nlp初学者需要怎么入门?

前言 自从 ChatGPT 横空出世以来,自然语言处理(Natural Language Processing,NLP)研究领域就出现了一种消极的声音,认为大模型技术导致 NLP “死了”。 有人认为 NLP 的市场肯定有,但 NLP 的研究会遇到麻…

图片产生3D模型

HyperHuman 上传图片,点击生成 可以多生成几次,点击应用 让效果再好一点 生成完成之后可以导出为fbx格式

实战|等保2.0 Oracle数据库测评过程

以下等保测评过程以Oracle 11g为例,通过PL/SQL进行管理,未进行任何配置、按照等保2.0标准,2021报告模板,三级系统要求进行测评。 一、身份鉴别 a) 应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,…

E212: Can‘t open file for writing

如图 1. 查看当前用户的用户名和所属组 如果你只想查看当前登录用户的用户名和所属组,可以使用以下命令: whoami groups 检查文件和目录权限: ls -ld /private/var/log/wyhy ls -l /private/var/log/wyhy/market.log 修改文件权限&#…

RAKsmart美国大带宽服务器租用体验怎么样?

RAKsmart是一家提供全球服务器租用服务的知名供应商,其在美国的服务器产品种类多样,包括大带宽服务器、多IP站群服务器以及高防御服务器等,以适应不同业务的需求。rak小编为您整理发布。 下面是对RAKsmart美国大带宽服务器租用的具体介绍&…

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…