数据结构(六)二叉树

news2024/11/25 20:42:06

一、树形结构

概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

1、有一个特殊的结点,称为根结点,根结点没有前驱结点

2、除根结点外,其余结点被分成M(M > 0)个互不相交的集合T1、T2、......、Tm,其中每一个集合 Ti (1 <= i<= m) 又是一棵与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继

3、树是递归定义的。

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

结点的度:一个结点含有子树的个数称为该结点的度; 如上图:A的度为6

树的度:一棵树中,所有结点度的最大值称为树的度; 如上图:树的度为6

叶子结点或终端结点:度为0的结点称为叶结点; 如上图:B、C、H、I...等节点为叶结点

双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点

孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点

根结点:一棵树中,没有双亲结点的结点;如上图:A

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

树的高度或深度:树中结点的最大层次; 如上图:树的高度为4

树的以下概念只需了解,在看书时只要知道是什么意思即可:

非终端结点或分支结点:度不为0的结点; 如上图:D、E、F、G...等节点为分支结点

兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点

堂兄弟结点:双亲在同一层的结点互为堂兄弟;如上图:H、I互为兄弟结点

结点的祖先:从根到该结点所经分支上的所有结点;如上图:A是所有结点的祖先

子孙:以某结点为根的子树中任一结点都称为该结点的子孙。如上图:所有结点都是A的子孙

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

二、二叉树

概念

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

1. 或者为空

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

从上图可以看出:

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

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

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

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

-若i>0,双亲序号:(i-1)/2i=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; // 当前节点的根节点
}

孩子双亲表示法后序在平衡树位置介绍,本文采用孩子表示法来构建二叉树

二叉树的基本操作

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

    public TreeNode(char val) {
        this.val = val;
    }
}
public class TestBinaryTree {
    public TreeNode creteTree(){
        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;//根节点
    }

    // 前序遍历
    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 static int count=0;
    // 获取树中节点的个数
    int size1(TreeNode root) {
        if (root==null){
            return 0;
        }
        count++;
        size1(root.left);
        size1(root.right);
        return count;
    }
    public int size(TreeNode root){
        if (root==null){
            return 0;
        }
        int tmp=size(root.left)+size(root.right)+1;
        return tmp;
    }
    public static int leafCount=0;
    // 获取叶子节点的个数
    void getLeafNodeCount1(TreeNode root) {
        if (root==null){
            return;
        }
        if (root.left==null&&root.right==null){
            leafCount++;
        }
        getLeafNodeCount1(root.left);
        getLeafNodeCount1(root.right);
    }
    // 子问题思路-求叶子结点个数
    public int getLeafNodeCount(TreeNode root){
        if (root==null){
            return 0;
        }
        if (root.left==null&&root.right==null){
            return 1;
        }
        int tmp=getLeafNodeCount(root.left)+getLeafNodeCount(root.right);
        return tmp;
    }
    // 获取第K层节点的个数
    int getKLevelNodeCount(TreeNode root,int k){
        if (root==null){
            return 0;
        }
        if (k==1){
            return 1;
        }
        int tmp=getKLevelNodeCount(root.left,k-1)+getKLevelNodeCount(root.right,k-1);
        return tmp;
    }
    // 获取二叉树的高度
    int getHeight(TreeNode root) {
        if (root==null){
            return 0;
        }
        int leftH=getHeight(root.left);
        int rightH=getHeight(root.right);

        return leftH > rightH ? leftH+1 : rightH+1;

    }
    // 检测值为value的元素是否存在
    TreeNode find(TreeNode root, char val) {
        if (root==null){
            return null;
        }
        if (root.val==val){
            return root;
        }
        TreeNode ret=find(root.left,val);
        if (ret!=null){
            return ret;
        }
        ret=find(root.right,val);
        if (ret!=null){
            return ret;
        }
        return null;
    }
}

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

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

相关文章

昇腾AI新技能,还能预防猪生病?

国药集团动物保健股份有限公司&#xff08;简称“国药动保”&#xff09;是专业从事动物保健产品研发、生产和销售的国家高新技术企业&#xff0c;是国内少数几家具备新产品原创能力的动物保健企业。其中&#xff0c;猪圆环病毒灭活疫苗等市场份额位居行业前列。 “猪圆环病毒…

【Linux学习笔记】8.Linux yum 命令和apt 命令

前言 本章介绍Linux的yum命令和apt命令。 Linux yum 命令 yum&#xff08; Yellow dog Updater, Modified&#xff09;是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包管理器。 基于 RPM 包管理&#xff0c;能够从指定的服务器自动下载 RPM 包并且安装&#xf…

一种全新的图像滤波理论的实验(三)

一、前言 2023年02月22日&#xff0c;我发布了滤波后&#xff0c;为针对异常的白色和黑色像素进行处理的实验&#xff0c;本次发布基于上下文处理的方案的实验&#xff0c;目的是通过基于加权概率模型滤波后&#xff0c;在逆滤波时直接修复大量的白色和黑色的异常像素&#xf…

html css输入框获得焦点、失去焦点效果

input输入框获得焦点、失去焦点效果 废话shao shuo ! 直接看效果图&#xff0c;好吧&#xff01; 效果图&#xff1a; code: <!DOCTYPE html> <html> <head><title></title><meta charset"utf-8" /><style type"text…

电子统计台账:海量数据中导入特定行,极力减少键盘编辑工作量

1 前言从事企业统计工作的小伙伴&#xff0c;本来已经够忙的了&#xff0c;现在又要加上什么电子台账这种鬼任务&#xff0c;而且居然还要每月来一次&#xff0c;简直不能忍。如果非要捏着鼻子忍了&#xff0c;那么有什么办法&#xff0c;减轻工作量&#xff1f;2 问题的提出有…

应用场景五: 西门子PLC通过Modbus协议连接DCS系统

应用描述&#xff1a; 西门子PLC&#xff08;S7200/300/400/200SMART&#xff09;通过桥接器可以支持ModbusRTU串口和ModbusTCP以太网&#xff08;有线和无线WIFI同时支持&#xff09;两种通讯方式连接DCS系统&#xff0c;不需要编程PLC通讯程序&#xff0c;直接在模块中进行地…

【数据库】第九章 关系查询处理与优化

第九章 关系查询处理与优化 索引 索引文件是一种辅助存储结构&#xff0c;其存在与否不改变存储表的物理存储结 构&#xff1b;然而其存在&#xff0c;可以明显提高存储表的访问速度。 索引文件组织方式有两种&#xff1a;(相对照的&#xff0c;主文件组织有堆文件、排序文件、…

Python3-字符串

Python3 字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号( ’ 或 " )来创建字符串。 创建字符串很简单&#xff0c;只要为变量分配一个值即可。 Python 访问字符串中的值 Python 不支持单字符类型&#xff0c;单字符在 Python 中也是作为一个字符串使用…

行测-判断推理-图形推理-位置规律-旋转、翻转

短指针每次逆时针旋转60&#xff08;排除法选C走人&#xff09;长指针每次顺时针旋转120选C左上菱形每次顺时针旋转90&#xff08;排除C D&#xff09;右上每次旋转180&#xff08;选B走人&#xff09;左下每次保持不变右下每次逆时针旋转90选B左上和右上为左右翻转&#xff0c…

结合JasperReports输出报表

结合JasperReports输出报表 前面我们已经使用Jaspersoft Studio设计了两个模板文件&#xff1a;demo1.jrxml和demo2.jrxml。其中demo1.jrxml的动态列表数据是基于JDBC数据源方式进行数据填充&#xff0c;demo2.jrxml的动态列表数据是基于JavaBean数据源方式进行数据填充。本小节…

ATTCK实战系列-红队评估(一)

from ATT&CK实战系列-红队评估(一) 环境搭建 下载地址:http://vulnstack.qiyuanxuetang.net/vuln/detail/2/ 将三个虚拟机启动起来 除了windows 7那个主机&#xff0c;其他都只设置成仅主机模式 windows 7添加两个网卡&#xff0c;一个是仅主机&#xff0c;一个是NAT …

解决SpringBoot中@RequestBody不能和Multipart同时传递的问题

问题描述 今天在做文件上传的时候&#xff0c;遇到了这么一个错误日志&#xff1a; Resolved[org.springframework.web.HttpMediaTypeNotSupportedException: Content type ‘multipart/form-data;boundary--------------------------771899451541318130280588;charsetUTF-8’…

[牛客Hot101]链表篇

文章目录1.翻转链表2.链表内指定区间翻转3. 链表中的节点每k个一组翻转4. 合并两个排序的链表5. 合并k个排序的链表6. 判断链表是否有环7. 链表中倒数第k个节点8. 删除链表中的倒数第k和节点9. 两个链表的第一个公共节点10.链表的入环节点11. 链表相加&#xff08;二&#xff0…

mac 如何设置 oh my zsh 终端terminal 和添加主题powerlevel10k

Oh My Zsh 是什么 Oh My Zsh 是一款社区驱动的命令行工具&#xff0c;正如它的主页上说的&#xff0c;Oh My Zsh 是一种生活方式。它基于 zsh 命令行&#xff0c;提供了主题配置&#xff0c;插件机制&#xff0c;已经内置的便捷操作。给我们一种全新的方式使用命令行。 **Oh …

Buuctf reverse [FlareOn4]IgniteMe 题解

一. 查壳 无壳32位程序 二. ida打开 GetStdHandle函数根据微软官方文档可以得知是获取标准输入/输出/错误的句柄 参数里的 0xFFFFFFF6转换一下是4294967286, 对应(DWORD) -10 所以这里的WriteFile函数实际上是实现了printf的功能 sub_4010F0()函数 其功能是通过ReadFile函数读取…

Java EE|TCP/IP协议栈之数据链路层协议详解

文章目录一、数据链路层协议感性认识数据链路层简介以太网简介特点二、以太网数据帧格式详解帧头不同类型对应的载荷三、关于MTU什么是MTUMTU有什么作用ip分片&#xff08;了解&#xff09;参考一、数据链路层协议感性认识 数据链路层简介 从上图可以看出 &#xff0c; 在TCP/…

「JVM 高效并发」Java 线程

进程是资源分配&#xff08;内存地址、文件 I/O 等&#xff09;的基本单位&#xff0c;线程是执行调度&#xff08;处理器资源调度&#xff09;的基本单位&#xff1b; Loom 项目若成功为 Java 引入纤程&#xff08;Fiber&#xff09;&#xff0c;则线程的执行调度单位可能变为…

搭建Vue工程

搭建Vue工程 localhost 127.0.0.1 域名 IP 192.168.0.28 联网IP 最后都会渲染到一个页面里面&#xff0c;有多少个页面就有多少个页面模板。 vue里面改webpack配置 vue.config.js 配置参考 | Vue CLI /assets /api* 开发的时候用到的请求后台地址 和 项目真实部署上线的时候 请…

Linux 练习二 (VIM编辑器 + GCC编译器 + GDB调试)

文章目录VIM命令思维导图GCC编译器1、GCC编译文件练习2、静态库动态库制作练习将此函数编译成动态库将此函数编译成静态库GCC优化选项 -OnGDB调试命令练习练习一&#xff1a;编写一个程序&#xff0c;通过gdb调试&#xff0c;使用到gdb的b&#xff0c;n&#xff0c;s&#xff0…

ccc-台大林轩田机器学习基石-hw1

文章目录Question1-14Question15-PLAQuestion16-PLA平均迭代次数Question17-不同迭代系数的PLAQuestion18-Pocket_PLAQuestion19-PLA的错误率Question20-修改Pocket_PLA迭代次数Question1-14 对于有明确公式和定义的不需要使用到ml 智能系统在与环境的连续互动中学习最优行为策…