数据结构-树、二叉树

news2024/11/26 0:35:30

一、概念

1、树的概念

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

如果一个数的结点n为0,那么这个树叫做空树。反之,如果结点n>0,那么这个树是非空树T。

结点:树中的一个独立单元,如6、1、20、43等都是结点

结点的度:结点拥有的字数的个数或者分支的个数。例如6有3棵子树,那么结点6的度就是3。

树的度:树中各结点的度的最大值

叶子结点:又叫做终端结点。指度为0的结点,例如图中的5,23,29,8,32,10,0都是叶子结点。

非终端结点:又叫做分支结点。指度不为0的结点。

孩子:结点子树的根。如 6结点的孩子为1,20,43。

双亲:与孩子的定义对应。如 1,20,43结点的双亲为6。

兄弟:同一个双亲的孩子之间互为兄弟。如 1,20,43互为兄弟。

祖先:从根到该结点所经分支上的所有结点。

子孙:以某结点为根的子树中的任一结点都称为该结点的子孙。

层次:结点的层次从根开始定义起,根为第一层,根的孩子为第二层。

堂兄弟:双亲在同一层的结点互为堂兄弟。

树的深度:树中结点的最大层次称为树的深度或高度。

有序树和无序树:如果将树中的结点的各子树看成从左到右是有次序的(即不能互换),则称该树为无序树。在有序树中最左边的子树的根称为第一个孩子,最右边的称为最后一个孩子。

森林:是m(m>0)棵互不相交的树的集合。

2、二叉树

二叉树(Binary Tree)是n(n>=0)个节点所构成的集合,每个节点最多有两棵子树,子树又有左右之分,分为左子树和右子树。

二叉树共有5种形态:

  • 空二叉树
  • 只有一个根结点的二叉树
  • 只有左子树的二叉树
  • 只有右子树的二叉树
  • 既有左子树又有右子树的二叉树
(1)满二叉树

如果一棵二叉树所有的分支节点都存在左子树和右子树,并且所有的叶子节点都在同一层上,这样的二叉树称为满二叉树

满二叉树具有如下特点:

叶子只能出现在最下一层

非叶子节点的度一定是2

同样深度的二叉树中,满二叉树的结点个数最多,叶子树最多。

(2)完全二叉树

若二叉树的高度为h,除第h层外,其他(1~h-1层)的结点数都达到了最大个数,第h层有叶子节点,并且叶子节点都是从左到右依次排布,这就是完全二叉树。

 完全二叉树的特点:

  • 叶子节点只能出现在最下两层
  • 最下层叶子节点在左侧并且连续
  • 同样结点数的二叉树,完全二叉树的深度最小

注意:满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树。

二叉树的存储结构有两种方式:顺序存储和链式存储

(3)二叉搜索树(二叉排序树)
  • 若它的左子树不为空,则左子树上所有结点的值都小于根结点的值
  • 若它的右子树不为空,则右子树上所有结点的值都大于根结点的值。
  • 它的左右子树也分别是二叉搜索树

注意:二叉搜索树的中序遍历的结果是有序的。

(4)平衡二叉树(又成AVL树)

用于解决二叉排序树高度不确定的情况,如果二叉排序树的高度相差太大,就会让二叉排序树的时间复杂度升级为O(n),为了避免这一情况,就出现了平衡二叉树,使树的高度尽可能的小,其本质还是一棵二叉搜索树。

平衡二叉树的性质:

  • 左子树和右子树的高度之差的绝对值小于等于1
  • 左子树和右子树也是平衡二叉树
(5)红黑树

 红黑树的特性:

  • 每个节点要么是红色,要么是黑色
  • 根结点为黑色
  • 每个叶子节点(NIL)均为黑色【注:这里的叶子节点指的是空(NIL或者NULL)的叶子节点】
  • 如果一个节点是红色,那么它的子节点必定是黑色
  • 从一个节点到该节点的子孙节点NIL的所有路径上包含相同数据的黑色节点。【注:这里指到叶子节点的路径。】

特别说明:

  • 特性第三条指的叶子节点为空(NIL或NULL)的结点
  • 特性第五条,确保没有一条路径会比其他路径长出两倍。因为红黑树是相对接近平衡二叉树的。

红黑树的应用:

红黑树可以用来存储有序数据,时间复杂度是O(logn),效率非常高。例如,Java集合中的TreeSet和TreeMap都是通过红黑树来实现的。

红黑树的基本操作——左旋和右旋:

红黑树在删除或者添加节点滞后,很有可能破坏原有的红黑树结构特性,这时候旋转操作就必不可少了,这和AVL树有一点点相像。总而言之,旋转的目的是为了保持红黑树的特性。

左旋

 对节点F进行左旋,意味着将节点F变为其右孩子节点R的左孩子结点,并将节点R的左子树变为节点F的右子树。

右旋

对节点F进行右旋,意味着将节点F变为其左孩子节点L的右孩子节点,并将节点L的右子树变为节点F的左子树

二、二叉树的实现及遍历

1、用Java代码实现一个二叉树的创建

(1)创建一个二叉树的结点:

    public static class TreeNode {
        public int value;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int value) {
            this.value = value;
        }
    }

(2)创建二叉树:

    /**
     * 创建二叉树
     *
     * @return
     */
    public TreeNode createBinaryTree(LinkedList<Integer> linkedList) {
        TreeNode treeNode = null;
        if (linkedList == null || linkedList.size() == 0) return treeNode;

        Integer value = linkedList.removeFirst();
        if (value != null) {
            treeNode = new TreeNode(value);
            treeNode.left = createBinaryTree(linkedList);
            treeNode.right = createBinaryTree(linkedList);
        }
        return treeNode;
    }

2、二叉树的遍历

(1)先序遍历:

    /**
     * 二叉树遍历-先序遍历
     *
     * @param treeNode
     */
    public void preOderBinaryTree(TreeNode treeNode) {
        if (treeNode == null) return;

        System.out.println(treeNode.value);
        preOderBinaryTree(treeNode.left);
        preOderBinaryTree(treeNode.right);
    }

(2)中序遍历:

    /**
     * 二叉树遍历-中序遍历
     *
     * @param treeNode
     */
    public void midOrderBinaryTree(TreeNode treeNode) {
        if (treeNode == null) return;

        midOrderBinaryTree(treeNode.left);
        System.out.println(treeNode.value);
        midOrderBinaryTree(treeNode.right);
    }

(3)后序遍历:

    /**
     * 二叉树遍历-后序遍历
     *
     * @param treeNode
     */
    public void postOrderBinaryTree(TreeNode treeNode) {
        if (treeNode == null) return;

        postOrderBinaryTree(treeNode.left);
        postOrderBinaryTree(treeNode.right);
        System.out.println(treeNode.value);
    }

(4)层序遍历:

    /**
     * 二叉树遍历-层序遍历
     *
     * @param root
     */
    public List<List<Integer>> levelOrderBinaryTree(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result;

        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()) {
            int queueSize = queue.size();
            List<Integer> level = new ArrayList<>();

            for (int i = 0; i < queueSize; i++) {
                TreeNode treeNode = queue.poll();
                if (treeNode != null) level.add(treeNode.value);

                if (treeNode != null && treeNode.left != null) {
                    queue.offer(treeNode.left);
                }
                if (treeNode != null && treeNode.right != null) {
                    queue.offer(treeNode.right);
                }
            }
            result.add(level);

        }
        return result;
    }

(5)求二叉树的最大深度:

    /**
     * 求二叉树的最大深度
     *
     * @param root
     * @return
     */
    public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }

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

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

相关文章

图论算法:DFS求有向图或无向图两点间所有路径及最短路径

1、目的 根据有向图获取指定起终点的所有路径,包括最长和最短路径。 2、示例效果 2.1 原始数据 路线起终点整理如下: // 共计12个顶点,19条边。 (起点,终点,1)最后的1代表起点终点是连通的。 起点,终点,1:2 4 1 起点,终点,1:9 10 1 起点,终点,1:8 11 1 起点…

易基因: RRBS揭示基于DNA甲基化驱动基因的肾透明细胞癌预后模型的鉴定和验证|项目文章

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 肾细胞癌&#xff08;RCC&#xff09;是最常见的肾癌亚型&#xff0c;每年超400万例新发病例&#xff0c;是泌尿系统恶性肿瘤导致的第二大死因。2%-70%的RCC为透明细胞RCC&#xff08;Cl…

node.js使用nodemailer发送阿里云企业邮箱的邮件

百度一搜就能搜到各种博客例子&#xff0c;但是有个问题&#xff1a;有些参数写的不明不白的&#xff0c;我在发送的时候总是报错 后面看到了一篇博客&#xff1a; 基于nodemailer使用阿里云企业邮箱发送邮件&#xff08;526错误的解决&#xff09; 注意几点&#xff1a; …

【现场问题】flink-cdc,sql一直校验不通过,为什么,明明sql没有错误

flink-cdc 问题展示问题解决校验结果 问题展示 这里的flink-cdc的sql对了好几遍&#xff0c;都没问题&#xff0c;包括单个执行create&#xff0c;也是显示校验通过 如图&#xff1a; 但是多个一起就报错了&#xff1a; java.lang.IllegalArgumentException: only single state…

奇点云DataSimba R4.9 LTS发布:稳定性加固,架构升级,142项功能上新

不久前&#xff0c;奇点云的数据云全系产品如期发布新一季商业化版本更新&#xff1a; 数据云平台DataSimba&#xff1a;R4.9 LTS版发布&#xff0c;稳定性全面加固&#xff0c;功能上新&#xff1b;自R4系列起架构升级&#xff0c;封装底层复杂性&#xff0c;支撑上层快速构建…

git代码合并merge与rebase

一、概述 1.区别 Merge具有更高的可追溯性 保留真实的历史&#xff0c;而Rebase则更整洁且易于审核。 rebase:不会有单独的commit合并记录&#xff0c;直接将分支中的所有commit排到master的记录之后。 merge:将在子分支的所有提交记录成一次commit&#xff0c;作为单独的一…

机器学习实战:Python基于LR线性回归进行预测(十)

文章目录 1 前言1.1 LR的介绍1.2 LR的应用 2. weather数据集实战演示2.1 导入函数2.2 导入数据2.3 数据整体可视化2.4 训练模型2.5 预测模型2.6 评估模型 3.讨论 1 前言 注意这里的LR指的是Linear Regression&#xff0c;线性回归。而非逻辑回归Logistic Regression&#xff0c…

【QT】——TCP套接字通信

目录 1.基本概念 2.QTcpServer 2.1 常用接口 2.2信号 3 QTcpSocket 3.1构造函数 3.2 连接函数 3.3 接收数据 3.4 发送数据 3.5 信号 4.通信的过程 4.1服务器端 4.2 客户端 通信流程&#xff1a; 1.基本概念 QT是 C 的一个框架&#xff0c;并且里边提供了用于套接…

让你不再好奇ai绘画免费网站有哪些

你有没有想过成为一名画家&#xff0c;但是缺乏绘画技巧&#xff1f;现在有了 ai作画生成器&#xff0c;让你可以轻松地创作出绝美的艺术品&#xff01;现在有很多ai作画的免费网站&#xff0c;但是这些网站大多数操作繁琐&#xff0c;不易上手。这时我们可以寻求一款趁手的ai绘…

【算法与数据结构】剑指 Offer 58 - II. LeetCode左旋转字符串

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;以例一为例&#xff0c;例一的字符串可以分为"ab" "cdefg"两个子串&#xff0c;首…

element Plus Select选择器实现查询搜索 下拉选择

这Select选择器用于哪里 怎么用&#xff1f; Select 选择器可以用于许多不同的场景&#xff0c;包括但不限于以下几个方面&#xff1a; 表单&#xff1a;Select 选择器常用于表单中的下拉选择字段&#xff0c;例如选择国家、城市、性别、职位等。用户可以从预定义的选项中选择…

软考:中级软件设计师:计算机体系结构,CISC和RISC,Flynn分类,指令流水线,吞吐率,效率

软考&#xff1a;中级软件设计师:计算机体系结构 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的…

Win10任务栏的天气怎么关闭?Win10任务栏的天气关闭方法

Win10任务栏的天气怎么关闭&#xff1f;Win10任务栏的天气功能可以提供即时的天气信息&#xff0c;方便用户随时获取当前和未来的天气预报。然而&#xff0c;对于一些用户来说&#xff0c;这个天气小部件可能并不是必需的&#xff0c;并且想要关闭它以腾出任务栏的空间。无论是…

工程师抓秃头总结卡尔曼滤波简单原理及收敛原因

1、关于矩阵的一些想法 有小伙伴看到矩阵就脑瓜壳疼&#xff0c;那是没有了解数学家为啥闲的没事要用矩阵呢&#xff0c;从来没有人说不用矩阵就算不了&#xff0c;矩阵最初我认为是数学家偷懒&#xff0c;因为写一堆方程字太多太长&#xff0c;所以用了简写的形式&#xff0c;…

【SAP-MDG】售前常见问题

在与甲方的交流过程中&#xff0c;常常会有以下几个问题 一、“为什么要上主数据管理系统&#xff1f;” 见&#xff1a;主数据管理的意义 二、“有了主数据管理机制&#xff0c;还要不要上主数据管理平台&#xff1f;” 主数据的管理机制是通用性的&#xff0c;我们在任何系…

【算法与数据结构】28、LeetCode实现strStr函数

文章目录 一、题目二、暴力穷解法三、KMP算法四、Sunday算法五、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、暴力穷解法 思路分析&#xff1a;首先判断字符串是否合法&#xff0c;然后利用for循环&#xff…

:hover悬浮在元素上方时,不出现黑边

给element plus的下拉菜单设置悬浮样式 .el-dropdown :hover{border: none;outline: none; } border:node 表示元素本身的边框没有了 outline:none 表示元素的轮廓线没有了

K8S集群管理

集群管理 1 集群管理1.1 节点管理1.1.1 令牌管理1.1.2 集群扩缩容1.1.3 集群升级1.1.4 证书管理 1.2 数据管理1.2.1 ETCD基础1.2.2 ETCD实践1.2.3 备份还原1.2.4 ETCD集群 1 集群管理 1.1 节点管理 1.1.1 令牌管理 学习目标 这一节&#xff0c;我们从 令牌基础、令牌实践、…

【Part 2】博物馆防刷票小程序接入无感验证--跳转式接入

前文在这里&#xff1a; 【Part 1】现在去博物馆都预约不上了&#xff0c;黑产多少有点疯狂了 前面这篇文章讲到目前博物馆的门票基本被黄牛薅没了&#xff0c;我们普通人只能通过黄牛去买票&#xff0c;并且讲到了预约小程序如何通过插件式接入无感验证。 这篇文章我们继续讲…

数据结构之 时间复杂度与空间复杂度

目录 1&#xff1a;什么是时间复杂度和空间复杂度 2&#xff1a;时间复杂度与空间复杂度求法 3&#xff1a;几个典型时间复杂度与空间复杂度的分析 1&#xff1a;什么是时间复杂度与空间复杂度 首先对于我们所写的程序来说&#xff0c;为了评估一个算法的好与坏我们需要通过…