数据结构之树和二叉树

news2024/11/18 20:20:25

目录

一、树简介

二、二叉树

1、简介

2、二叉树的性质

3、满二叉树和完全二叉树 

三、二叉树的遍历

四、二叉树遍历代码实现

五、二叉搜索树(Binary Search Tree)

1、简介

2、二插搜索树的局限性

六、平衡二叉搜索树(AVL树)

七、红黑树(Red-Black Tree)

1、简介

2、性质

3、使用场景 

八、B树(B-Tree)

 1、简介

2、特点

九、B+树

1、简介

2、B+的特性

3、稠密索引

4、稀疏索引


一、树简介

        树是一种非线性的数据结构,是由n(n >=0)个结点组成的有限集合。

        如果n==0,树为空树。如果n>0,树有一个特定的结点,叫做根结点(root)根结点只有直接后继,没有直接前驱

        除根结点以外的其他结点划分为m(m>=0)个互不相交的有限集合,T0,T1,T2,...,Tm-1,每个集合都是一棵树,称为根结点的子树(sub tree)

 

下面是一些其它基本概念:

  • 节点的度:节点拥有的子树个数
  • 叶子节点(leaf):度为0的节点,也就是没有子树的节点
  • 树的高度:树中节点的最大层数,也叫做树的深度

二、二叉树

1、简介

对于树这种数据结构,使用最频繁的是二叉树

每个节点最多只有2个子节点的树,叫做二叉树。二叉树中,每个节点的子节点作为根的两个子树,一般叫做节点的左子树和右子树

 

2、二叉树的性质

  • 若二叉树的层次从0开始,则在二叉树的第i层至多有2^i个结点(i>=0)
  • 高度为k的二叉树最多有2^(k+1) - 1个结点(k>=-1)(空树的高度为-1)
  • 对任何一棵二叉树,如果其叶子结点(度为0)数为m, 度为2的结点数为n, 则m = n + 1

3、满二叉树和完全二叉树 

  • 满二叉树:除了叶子节点外,每个节点都有两个子节点,每一层都被完全填充。
  • 完全二叉树:除了最后一层外,每一层都被完全填充,并且最后一层所有节点保持向左对齐。

三、二叉树的遍历

  • 中序遍历:即左-根-右遍历,对于给定的二叉树根,寻找其左子树;对于其左子树的根,再去寻找其左子树;递归遍历,直到寻找最左边的节点i,其必然为叶子,然后遍历i的父节点,再遍历i的兄弟节点。随着递归的逐渐出栈,最终完成遍历

3c722946ebdd459f8bb2f9db7afd0ea8.png

 

  • 先序遍历:即根-左-右遍历

58a00fbca77c41798d3bfeaaf26189c6.png

 

  • 后序遍历:即左-右-根遍历

88e0eaf4249e4d7b8f79da8b38227c01.png

 

  • 层序遍历:按照从上到下、从左到右的顺序,逐层遍历所有节点。

 


四、二叉树遍历代码实现

package com.kgf.algorithm.tree;

import java.util.ArrayDeque;
import java.util.Queue;

/***
 * 二叉树的遍历
 */
public class TreeErgodic {

    public static void main(String[] args) {

        TreeNode root = new TreeNode(1);
        TreeNode tn1 = new TreeNode(3);
        TreeNode tn2 = new TreeNode(5);
        TreeNode tn3 = new TreeNode(2);
        TreeNode tn4 = new TreeNode(7);
        TreeNode tn5 = new TreeNode(6);

        root.left=tn1;
        root.right=tn2;

        tn1.left = tn3;
        tn1.right = tn4;
        tn2.left = tn5;

        TreeErgodic te = new TreeErgodic();
        te.levelTraversal2(root);
    }
    /***
     * 层序遍历
     * 按照从上到下、从左到右的顺序,逐层遍历所有节点。
     * 结果是:1 3 5 2 7 6
     * @param treeNode
     */
    public void levelTraversal2(TreeNode treeNode){
        //创建一个队列,先进先出
        Queue<TreeNode> queue = new ArrayDeque();
        queue.add(treeNode);
        while (!queue.isEmpty()){
            TreeNode node = queue.poll();
            System.out.print(node.val+"\t");
            if (node.left!=null){
                queue.add(node.left);
            }
            if (node.right!=null){
                queue.add(node.right);
            }
        }
    }
    /***
     * 层序遍历
     * 按照从上到下、从左到右的顺序,逐层遍历所有节点。
     * 结果是:1 3 5 2 7 6
     * @param treeNode
     */
    public void levelTraversal(TreeNode treeNode){
        //创建一个队列,先进先出
       Queue queue = new ArrayDeque();
       queue.add(treeNode.val);
       loadTreeNode(treeNode,queue);
       while (!queue.isEmpty()){
           System.out.print(queue.poll()+"\t");
       }
    }

    private void loadTreeNode(TreeNode treeNode, Queue queue) {
        if (treeNode==null)return;
        if (treeNode.left!=null){
            queue.add(treeNode.left.val);
        }
        if (treeNode.right!=null){
            queue.add(treeNode.right.val);
        }
        loadTreeNode(treeNode.left,queue);
        loadTreeNode(treeNode.right,queue);
    }

    /***
     * 后序遍历
     * 即左-右-根遍历
     * 结果是:2	 7	3	6	5	1
     * @param treeNode
     */
    public void afterOrder(TreeNode treeNode){
        if (treeNode==null)return;
        afterOrder(treeNode.left);
        afterOrder(treeNode.right);
        System.out.print(treeNode.val+"\t");
    }

    /***
     * 中序遍历
     * 即左-根-右遍历
     * 结果是:2  3	7	1	6	5
     * @param treeNode
     */
    public void centerOrder(TreeNode treeNode){
        if (treeNode==null)return;
        centerOrder(treeNode.left);
        System.out.print(treeNode.val+"\t");
        centerOrder(treeNode.right);
    }

    /***
     * 先序遍历
     * 即根-左-右遍历
     * 结果是:1 3 2 7 5 6
     * @param treeNode
     */
    public void preOrder(TreeNode treeNode){
        if (treeNode==null)return;
        System.out.print(treeNode.val+"\t");
        preOrder(treeNode.left);
        preOrder(treeNode.right);
    }
}

五、二叉搜索树(Binary Search Tree)

1、简介

二叉搜索树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质:

  • 任意节点左子树如果不为空,则左子树中节点的值均小于根节点的值
  • 任意节点右子树如果不为空,则右子树中节点的值均大于根节点的值
  • 任意节点的左右子树,也分别是二叉搜索树
  • 没有键值相等的节点

基于二叉搜索树的这种特点,在查找某个节点的时候,可以采取类似于二分查找的思想,快速找到某个节点。n 个节点的二叉查找树,正常的情况下,查找的时间复杂度为 O(logN)。 

2、二插搜索树的局限性

 一个二叉搜索树是由n个节点随机构成,所以,对于某些情况,二叉查找树会退化成一个有n个节点的线性链表。如下图:

 


六、平衡二叉搜索树(AVL树)

         通过二叉搜索树的分析我们发现,二叉搜索树的节点查询、构造和删除性能,与树的高度相关,如果二叉搜索树能够更“平衡”一些,避免了树结构向线性结构的倾斜,则能够显著降低时间复杂度。

        平衡二叉搜索树:简称平衡二叉树。由前苏联的数学家Adelse-Velskil和Landis在1962年提出的高度平衡的二叉树,根据科学家的英文名也称为AVL树。

它具有如下几个性质:

  • 可以是空树
  • 假如不是空树,任何一个结点的左子树与右子树都是平衡二叉树,并且高度之差的绝对值不超过1

        平衡的意思,就是向天平一样保持左右水平,即两边的分量大约相同。如定义,假如一棵树的左右子树的高度之差超过1,如左子树的树高为2,右子树的树高为0,子树树高差的绝对值为2就打破了这个平衡。

        比如,依次插入1,2,3三个结点后,根结点的右子树树高减去左子树树高为2,树就失去了平衡。我们希望它能够变成更加平衡的样子。

        AVL树是带有平衡条件的二叉搜索树,它是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的。旋转的目的是为了降低树的高度,使其平衡。 

 

         AVL树适合用于插入删除次数比较少,但查找多的情况。也在Windows进程地址空间管理中得到了使用


七、红黑树(Red-Black Tree)

1、简介

         红黑树是一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。

2、性质

  • 节点是红色或黑色
  • 根节点是黑色
  • 每个叶子节点都是黑色的空节点(NIL节点)。
  • 每个红色节点的两个子节点都是黑色(从每个叶子到根的所有路径上不能有两个连续的红色节点)
  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

         在插入一个新节点时,默认将它涂为红色(这样可以不违背最后一条规则),然后进行旋转着色等操作,让新的树符合所有规则

        红黑树也是一种自平衡二叉查找树,可以认为是对AVL树的折中优化

3、使用场景 

红黑树多用于搜索,插入,删除操作多的情况下。红黑树应用比较广泛:

  • 广泛用在各种语言的内置数据结构中。比如C++的STL中,map和set都是用红黑树实现的。Java中的TreeSet,TreeMap也都是用红黑树实现的。
  • 著名的linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块。
  • epoll在内核中的实现,用红黑树管理事件块
  • nginx中,用红黑树管理timer等

八、B树(B-Tree)

 1、简介

        B树(B-Tree)是一种自平衡的树,它是一种多路搜索树(并不是二叉的),能够保证数据有序。同时,B树还保证了在查找、插入、删除等操作时性能都能保持在O(logn),为大块数据的读写操作做了优化,同时它也可以用来描述外部存储

2、特点

  • B树可以定义一个M值作为预定范围,即M路(阶)B树,每个节点最多有M个孩子;且M>2
  • 根结点的儿子数为[2, M]
  • 除根结点以外的非叶子结点的儿子数为[M/2, M]
  • 每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个key)
  • 非叶子结点的关键字个数 = 指向儿子的指针个数 – 1
  • 非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1]
  • 非叶子结点的指针:P[1], P[2], …, P[M],其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树
  • 所有叶子结点位于同一层

 


九、B+树

1、简介

 B+树是B-树的变体,也是一种多路搜索树

 B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找。

2、B+的特性

  • 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的
  • 不可能在非叶子结点命中
  • 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层
  • 更适合文件索引系统

 

3、稠密索引

        稠密索引,即每一条记录,对应一个索引字段。稠密索引,访问速度非常块,但是维护成本大。根据索引字段不一样,有候选键索引和非候选键索引之分 。

4、稀疏索引

  • 相对稠密索引,稀疏索引并没有每条记录,建立了索引字段,而是把记录分为若干个块,为每个块建立一条索引字段
  • 稀疏索引字段,要求索引字段是按顺序排序的,否则无法有效索引

稀疏索引是如何进行定位的呢?

  • 假设需要搜索字段值为K的记录,那先检索出比K小的最大值索引字段,再根据该字段所在的记录集合,进行顺序查找,直到找到记录K。
  • 稀疏索引,数据查询速度较慢,但是存储空间小,维护成本低

那么如何设置索引字段呢?

  • 既然索引是为了提高访问速度,简单说,要是一些数据经常被使用、被查询,那这些字段就应该设置索引

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

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

相关文章

【Spring框架】--04.单元测试JUnit、事务、资源操作Resources、国际化、数据校验Validation、提前编译AOT

文章目录 6.单元测试&#xff1a;JUnit6.1整合JUnit56.1.1搭建子模块6.1.2引入依赖6.1.3添加配置文件6.1.4添加java类6.1.5测试 6.2整合JUnit46.2.添加依赖6.2.2测试 7.事务7.1JdbcTemplate7.1.1简介7.1.2准备工作7.1.3实现CURD①装配 JdbcTemplate②测试增删改功能③查询数据返…

docker 使用记录

要点&#xff1a; 参考&#xff1a;https://www.cnblogs.com/yurenjun/p/15991062.html 一 打包部署步骤 参考&#xff1a; Docker教程&#xff08;超全总结&#xff09;_生信技术的博客-CSDN博客 参考部署基础操作&#xff1a;如何用Docker打包部署自己写的项目&#xff1f;…

中介中心性算法原理与源码解析(Between Centrality)

前言 中介中心性(Between Centrality)&#xff0c;或者叫介数中心性&#xff0c;是基于最短路径对关系图谱中节点的中心性进行测量的典型图论算法。和其它的图论中心性算法一样&#xff0c;中介中心性用来衡量社会关系网络中&#xff0c;个人、企业或者其它的实体在整个网络中…

stm32wb15cc蓝牙芯片学习

由于项目选型需要&#xff0c;初次接触stm32的蓝牙芯片&#xff0c;需要总体做一些学习。也记些笔记&#xff0c;防止遗忘。 一、主要的ST的蓝牙芯片 简单介绍一下主要ST的蓝牙芯片 1.1. STM32WB系列 这个系列的芯片是一个双核的MCU&#xff0c;相当于一个普通的STM32 MCU和…

全面分析低代码平台:各大热门产品详细对比

低代码平台彻底改变了企业构建和部署定制应用程序的方式。它们提供了一种用最少的代码&#xff0c;更快、更高效地开发软件的方法。使得公司在加快创新的同时节省了时间和资源。对于一些想进行数字化转型&#xff0c;选择低代码平台入门的中小企业来讲&#xff0c;应该选择哪个…

NTP时间服务器同步时钟系统安装汇总分享

在现代科技发展的背景下&#xff0c;各种设备的时间同步变得越来越重要。同步时钟管理系统的应用可以让多个设备在时间上保持一致&#xff0c;提高工作效率和安全性&#xff0c;为各个行业的发展提供了重要的支持。 一、同步时钟系统介绍 同步时钟管理系统的应用范围非常广泛&…

私有化部署的即时通讯软件:消息、文件安全加密,全面可控

如今&#xff0c;数字化转型进入纵深阶段&#xff0c;在企业数字化转型过程中&#xff0c;数据规模激增&#xff0c;结构更为复杂&#xff0c;数据零散化和安全性问题日益显著&#xff0c;使得众多企业在数据资产管理上面临不小的挑战。企业为提高内部沟通效率&#xff0c;通常…

C++源码分析完美转发

C源码分析完美转发 完美转发作用&#xff1a; 可以保持实参数据在函数中的左值或者右值类型。 不使用完美转发的后果 #include<iostream> using namespace std;// 容器里面元素的类型 class A { public:A() {}// 带左值引用参数的赋值函数A& operator(const A&…

24 KVM管理虚拟机-配置VNC-TLS登录

文章目录 24 KVM管理虚拟机-配置VNC-TLS登录24.1 概述24.2 操作步骤 24 KVM管理虚拟机-配置VNC-TLS登录 24.1 概述 VNC服务端和客户端默认采用明文方式进行数据传输&#xff0c;因此通信内容可能被第三方截获。为了提升安全性&#xff0c;openEuler支持VNC服务端配置TLS模式进…

在光伏行业的自动化生产中,EAP起到了什么作用?

随着可再生能源的快速发展和环保意识的增强&#xff0c;光伏行业作为一种清洁能源产业正迅速崛起。光伏生产过程的自动化已成为行业的追求和趋势。在光伏行业的自动化生产中&#xff0c;EAP&#xff08;设备自动化程序&#xff09;系统发挥着关键的作用&#xff0c;为生产线的运…

drawio@绘制带有latex公式的图表@示意图@流程图@白板模式whiteboard

文章目录 drawio绘制带有latex公式的图表示意图流程图白板模式whiteboard使用drawio小结 公式编辑Use mathematical typesetting in diagramsUse mathematical typesetting in diagramsTroubleshooting关于文本框元素公式渲染问题&#x1f388;Maths is not rendered 模式切换d…

【K哥爬虫普法】你很会写爬虫吗?10秒抢票、10秒入狱,了解一下?

我国目前并未出台专门针对网络爬虫技术的法律规范&#xff0c;但在司法实践中&#xff0c;相关判决已屡见不鲜&#xff0c;K 哥特设了“K哥爬虫普法”专栏&#xff0c;本栏目通过对真实案例的分析&#xff0c;旨在提高广大爬虫工程师的法律意识&#xff0c;知晓如何合法合规利用…

【TES745D】基于复旦微的FMQL45T900 全国产化ARM 核心模块(100%国产化)方案设计中文资料

板卡概述 TES745D 是一款基于上海复旦微电子FMQL45T900 的全国产化ARM 核心板。该核心板将复旦微的FMQL45T900&#xff08;与XILINX 的XC7Z045-2FFG900I 兼容&#xff09;的最小系统集成在了一个87*117mm 的 核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩…

主成分分析(PCA)直观理解与数学推导

近期在完成信息论的作业&#xff0c;发现网上的资料大多是直观解释&#xff0c;对其中的数学原理介绍甚少&#xff0c;并且只介绍了向量降维&#xff0c;而没有介绍向量重构的问题&#xff08;重构指的是&#xff1a;根据降维后的低维向量来恢复原始向量&#xff09;&#xff0…

Yolov5轻量化:MobileNetV3,轻量级骨架首选

1.轻量化网络简介 轻量化网络是指在保持模型性能的前提下,尽可能减小模型参数量和计算量的神经网络。这种网络通常被用于在移动设备等资源受限的场景中部署,以提高模型的实时性和运行效率。 轻量化网络的设计思路可以包括以下几个方面: 去除冗余层和参数:通过剪枝、蒸馏等技…

基于RT-Thread的lwip网卡优化笔记

基于RT-Thread的lwip网卡优化笔记 一、RT-Thread的lwip框架二、网卡驱动三、网卡吞吐速率测试四、网卡吞吐速率优化4.1 TCP参数优化4.2 lwip参数优化4.3 内存拷贝优化4.3.1 rt_memcpy优化4.3.2 使用uboot下的memcpy.S 4.4 网卡收发优化4.3.1 lwip发送优化4.4.2 网卡发送优化 一…

MyBatis查询各种类型数据该如何处理才能得到数据

文章目录 1、前言2、查询一个实体类对象字段名和属性名无法映射处理方式一&#xff1a;起别名方式二&#xff1a;使用全局配置文件配置映射规则方式三&#xff1a;自定义resultmap 3、查询一个list集合4、查询单个数据5、查询一条数据为map集合6、 查询多条数据为map集合方式一…

课程分享:华清远见联合NXP推出i.MX8M Plus开发与实践课程,超干超实用!

​课程名称&#xff1a; i.MX8M Plus开发与实践课程 课程介绍&#xff1a; i.MX8M Plus应用处理器是NXP推出的一款致力于推动机器学习&#xff08;ML&#xff09;&#xff0c;机器视觉&#xff0c;多媒体与工业边缘物联网应用的工业人工智能芯片。拥有4个ARM Cortex-A53核心…

远程桌面连接黑屏怎么解决?方法大全

远程桌面连接是一种非常有用的技术&#xff0c;它可以让用户从任何位置远程访问到其它计算机。然而&#xff0c;当你尝试连接到一个计算机时&#xff0c;你有可能会遇到远程桌面连接黑屏的问题。这个问题很常见&#xff0c;但是它可能会给你带来很多麻烦。在本文中&#xff0c;…

ssRender Plugin 基础

ssRender Plugin 基础 一.什么是Plugin ​ 插件(Plug-in,又称addin、add-in、addon或add-on,又译外挂)是一种遵循一定规范的应用程序接口编写出来的程序。其只能运行在程序规定的系统平台下&#xff08;可能同时支持多个平台&#xff09;&#xff0c;而不能脱离指定的平台单独…