[数据结构】二叉树

news2024/11/19 23:36:17

1.概念

一棵二叉树是结点的一个有限集合,该集合:
1. 或者为空
2. 或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成

从上图我们可以发现:

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

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

任意二叉树都是由上图构成的

2.两种特殊的二叉树

2.1.满二叉树

    如果一棵二叉树每层的节点都达到最大值,则我们称这颗二叉树为满二叉树。

如果一棵二叉树的层数为K,且结点总数是2^k-1 ,则它就是满二叉树。


2.2完全二叉树

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

3.二叉树的性质

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


4.二叉树的存储

  二叉树的存储分为:顺序存储和链式存储

我将在下一篇博客中给大家介绍顺序存储,我们先来看看链式存储:

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

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

5.二叉树的基本操作

  为了方便大家理解,这里我先手动快速创建一颗二叉树: 

·

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

         TreeNode(char val) {
             this.val = val;
        }
    }
    public TreeNode create(){
        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;
    }

再看二叉树基本操作前,再回顾下二叉树的概念,二叉树是:
1. 空树
2. 非空:根节点,根节点的左子树、根节点的右子树组成的
从概念中可以看出,二叉树定义是递归式的,因此后序基本操作中基本都是按照该概念实现的。
 

5.1 二叉树的遍历

1. 前中后序遍历
   学习二叉树结构,最简单的方式就是遍历。所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题(比如:打印节点内容、节点内容加1)。 遍历是二叉树上最重要的操作之一,是二叉树上进行其它运算之基础。
        在遍历二叉树时,如果没有进行某种约定,每个人都按照自己的方式遍历,得出的结果就比较混乱,如果按照某种规则进行约定,则每个人对于同一棵树的遍历结果肯定是相同的。如果N代表根节点,L代表根节点的左子树,R代表根节点的右子树,则根据遍历根节点的先后次序有以下遍历方式:
NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点--->根的左子树--->根的右子树。
LNR:中序遍历(Inorder Traversal)——根的左子树--->根节点--->根的右子树。
LRN:后序遍历(Postorder Traversal)——根的左子树--->根的右子树--->根节点
 

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

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

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

5. 二叉树的基本操作

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

         TreeNode(char val) {
             this.val = val;
        }
    }
    public TreeNode create(){
        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');

        TreeNode g = new TreeNode('g');
        A.left=B;
        A.right=C;
        B.left=D;
        B.right=E;
        E.right=H;
        C.left=F;
        C.right=G;
        return A;
    }
    // 前序遍历
    void preOrder(TreeNode root){
        if(root == null){
            return;
        }
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    };

    // 中序遍历
    void inOrder(TreeNode root){
        if(root == null){
            return;
        }
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    };
    // 后序遍历
    void postOrder(TreeNode root){
        if(root == null){
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val + " ");
    }
    public int size;
    // 获取树中节点的个数
    int size(TreeNode root){
        if(root == null){
            return 0;
        }
      int leftSize =  size(root.left);
      int rightSize = size(root.right);
      return leftSize+rightSize+1;
    }

    // 获取叶子节点的个数
    int getLeafNodeCount;
    int getLeafNodeCount(TreeNode root){
        if(root == null){
            return 0;
        }
        if(root.left == null && root.right ==null){
            return 1;
        }
        int leftSize =getLeafNodeCount(root.left);
        int rightSize=getLeafNodeCount(root.right);
        return leftSize+rightSize;
    }
    // 子问题思路-求叶子结点个数
    // 获取第K层节点的个数
    int getKLevelNodeCount(TreeNode root,int k){
        if(root == null ){
            return 0;
        }
        if(k == 1){
            return 1;
        }
        int leftSize = getKLevelNodeCount(root.left,k-1);
        int rightSize = getKLevelNodeCount(root.right,k-1);
        return leftSize+rightSize;
    }
    // 获取二叉树的高度
    int getHeight(TreeNode root){
        if(root == null){
            return 0;
        }
        if(root.left == null && root.right == null){
            return 1;
        }
        int leftSize = getHeight(root.left);
        int rightSize = getHeight(root.right);
        return (Math.max(leftSize, rightSize)) +1 ;
    }
    // 检测值为value的元素是否存在

    TreeNode find(TreeNode root, char val){
        if(root == null){
            return root;
        }
        if(root.val == val){
            return root;
        }
      TreeNode left =  find(root.left,val);
        if(left !=null){
            return left;
        }
        TreeNode right =  find(root.right,val);
        if(right != null){
            return right;
        }
        return null;

    }
}


 

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

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

相关文章

关于内存泄漏的经典面试题

目录 前言 一、内存泄漏基本概念 二、如何判断并查找内存泄漏 1、方案设计 2、方案实现 前言 对于C/C程序员来说&#xff0c;或多或少都会被面试官问到关于内存泄漏的问题&#xff0c;内存泄漏是程序的bug&#xff0c;他会一点一点的侵蚀你的内存&#xff0c;导致程序运行…

jmeter报Java.NET.BindException: Address already in use: connect

1、windows10和window11上&#xff1a; 修改注册表的内容&#xff1a; HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters&#xff1a; 新建dword&#xff08;值&#xff09;的类型&#xff1a; MaxUserPort 65334 TcpTimedWaitDelay 30window

2023年Q3线上生鲜水产数据分析:市场不景气,销额同比下滑44%

事实上&#xff0c;今年线上的生鲜生意市场并不景气。无论是Q1季度还是Q2季度&#xff0c;线上&#xff08;京东平台&#xff09;的销售额均同比去年下滑了10%左右。 然而到了Q3季度&#xff0c;整个下滑态势愈发严峻。可以看到鲸参谋数据显示&#xff0c;7月至9月生鲜水产在京…

腾讯云学生专享云服务器介绍及购买攻略

随着互联网技术的不断发展&#xff0c;越来越多的人开始关注云计算领域。作为国内领先的云计算服务商&#xff0c;腾讯云推出了“云校园”扶持计划&#xff0c;完成学生认证即可购买学生专享云服务器。 一、活动对象 仅限腾讯云官网通过个人认证的35岁以下学生用户参与&#x…

数据结构笔记——树和图(王道408)(持续更新)

文章目录 传送门前言树&#xff08;重点&#xff09;树的数据结构定义性质 二叉树的数据结构定义性质储存结构 二叉树算法先中后序遍历层次展开法递归模拟法 层次遍历遍历序列逆向构造二叉树 线索二叉树&#xff08;难点&#xff09;定义线索化的本质 二叉树线索化线索二叉树中…

Java 使用 poi 和 aspose 实现 word 模板数据写入并转换 pdf 增加水印

本项目所有源码和依赖资源都在文章顶部链接&#xff0c;有需要可以下载使用 1. 需求描述 从指定位置读取一个 word 模板获取业务数据并写入该 word 模板&#xff0c;生成新的 word 文档将新生成的 word 文档转换为 pdf 格式对 pdf 文档添加水印 2. 效果预览 word 模板 带水印的…

【递归、搜索与回溯算法】第六节.98. 验证二叉搜索树和230. 二叉搜索树中第K小的元素

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;递归、搜索与回溯算法 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&am…

Golang Struct 继承的深入讨论和细节

1&#xff09;结构体可以使用嵌套匿名结构体所有的字段和方法&#xff0c;即&#xff1a;首字母大写或者小写的字段、方法&#xff0c;都可以使用。 package mainimport "fmt"type A struct {Name stringage int }func (a *A) SayName() {fmt.Println("A say …

澳大利亚量子计算制造商SQC获5000万美元投资用于硅量子计算

​&#xff08;图片来源&#xff1a;网络&#xff09; Silicon Quantum Computing&#xff08;SQC&#xff09;是一家总部位于悉尼的量子计算制造商初创公司。澳大利亚联邦政府、联邦银行&#xff08;CBA&#xff09;&#xff0c;新南威尔士大学和Telstra联合向其投入资金超过5…

算法--单链表

算法–单链表 1.合并链表 1.合并两个排序的链表 解法&#xff1a;这个比较容易&#xff0c;直接对比两个两个链表节点&#xff0c;小的节点直接插入到返回的新链表上 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr)…

2023高频前端面试题-TCP

1. TCP 协议是什么? TCP(Transmission Control Protocol 传输控制协议) 是一种面向连接(连接导向) 的、可靠的、 基于 IP 的传输层协议。 TCP 使⽤校验、确认和重传机制来保证可靠传输 而 HTTP 协议 就是建立在 TCP / IP 协议 之上的一种应用。 TCP: 三次握手, 四次挥手~ …

关于本地项目上传到gitee的详细流程

如何上传本地项目到Gitee的流程&#xff1a; 1.Gitee创建项目 2. 进入所在文件夹&#xff0c;右键点击Git Bash Here 3.配置用户名和邮箱 在gitee的官网找到命令&#xff0c;注意这里的用户名和邮箱一定要和你本地的Git相匹配&#xff0c;否则会出现问题。 解决方法如下&…

支付宝证书到期更新完整过程

如果用户收到 支付宝公钥证书 到期通知后&#xff0c;可以根据如下指引更新证书 确认上传成功后就会生成新的证书&#xff0c;把新的证书替换到生产环境就可以了

python DataFrame的用法

pandas 首先要import pandas as pd&#xff0c;如果运行时报错找不到pandas则需要下载对应库&#xff0c;下载流程参考以下链接《Phthon下载库函数》 https://blog.csdn.net/qq_33308135/article/details/134054352?spm1001.2014.3001.5502 创建一个DataFrame import pandas…

kubernetes(3)

目录 service微服务 ipvs模式 clusterip headless nodeport loadbalancer metallb nodeport默认端口 externalname ingress-nginx 部署 基于路径访问 基于域名访问 TLS加密 auth认证 rewrite重定向 canary金丝雀发布 基于header灰度 基于权重灰度 业务域拆分…

【C++】变参函数va_start,va_arg,va_end介绍及实现方式

如果写过JS的话&#xff0c;就知道在JS中定义一个函数&#xff0c;就算输入的实参和形参不一致&#xff0c;也可以同过arguments获取参数 function abc(x) {console.log(x)console.log(arguments[0])console.log(arguments[1])console.log(arguments[2]) } abc(1,2,3)上例输出…

算法通关村第三关-青铜挑战数组专题

本期大纲 线性表基础线性表概念数组概念 数组的基本操作数组创建和初始化查找一个元素增加一个元素修改一个元素删除一个元素 小题一道 - - 单调数组问题小题一道 - - 数组合并问题小结 线性表基础 线性表概念 我们先搞清楚几个基本概念&#xff0c;在很多地方会看到线性结构…

Adversarial attacks and defenses on AI in medical imaging informatics: A survey

Adversarial attacks and defenses on AI in medical imaging informatics: A survey----《AI在医学影像信息学中的对抗性攻击与防御&#xff1a;综述》 背景&#xff1a; 之前的研究表明&#xff0c;人们对医疗DNN及其易受对抗性攻击的脆弱性一直存在疑虑。 摘要&#xff1a;…

实力认可!安全狗入选2023年国产云原生安全技术代表厂商

10月25日&#xff0c;安全牛发布了《2023云原生安全技术应用指南》报告暨年度代表性厂商推荐。 作为国内云原生安全领导厂商&#xff0c;安全狗凭借突出的云原生安全产品与实力成为2023年国产云原生安全技术代表厂商之一。 厦门服云信息科技有限公司&#xff08;品牌名&#xf…

04MQ消息队列

一、同步异步通讯 1.同步通讯和异步通讯 同步通讯&#xff1a;当A服务调用B服务时&#xff0c;一直等待B服务执行完毕&#xff0c;A才继续往下走 优点&#xff1a;时效性强&#xff0c;可以立即得到结果。 缺点&#xff1a; ①耦合度高&#xff0c;加入新的需求就要修改原…