树的概念

树(tree)是一种能够分层存储数据的重要数据结构,树中的每个元素被称为树的节点,每个节点有若干个指针指向子节点。从节点的角度来看,树是由唯一的起始节点引出的节点集合。这个起始结点称为根(root)。树中节点的子树数目称为节点的度(degree)。在面试中,关于树的面试问题非常常见,尤其是关于二叉树(binary tree),二叉搜索树(Binary Search Tree, BST)的问题。

所谓的二叉树,是指对于树中的每个节点而言,至多有左右两个子节点,即任意节点的度小于等于2。而广义的树则没有如上限制。二叉树是最常见的树形结构。二分查找树是二叉树的一种特例,对于二分查找树的任意节点,该节点存储的数值一定比左子树的所有节点的值大比右子树的所有节点的值小“(与之完全对称的情况也是有效的:即该节点存储的数值一定比左子树的所有节点的值小比右子树的所有节点的值大)。

基于这个特性,二分查找树通常被用于维护有序数据。二分查找树查找、删除、插入的效率都会于一般的线性数据结构。事实上,对于二分查找树的操作相当于执行二分搜索,其执行效率与树的高度(depth)有关,检索任意数据的比较次数不会多于树的高度。这里需要引入高度的概念:对一棵树而言,从根节点到某个节点的路径长度称为该节点的层数(level),根节点为第0层,非根节点的层数是其父节点的层数加1。树的高度定义为该树中层数最大的叶节点的层数加1,即相当于于从根节点到叶节点的最长路径加1。由此,对于n个数据,二分查找树应该以“尽可能小的高度存储所有数据。由于二叉树第L层至多可以存储 2^L 个节点,故树的高度应在logn量级,因此,二分查找树的搜索效率为O(logn)。

直观上看,尽可能地把二分查找树的每一层“塞满”数据可以使得搜索效率最高,但考虑到每次插入删除都需要维护二分查找树的性质,要实现这点并不容易。特别地,当二分查找树退化为一个由小到大排列的单链表(每个节点只有右孩子),其搜索效率变为O(n)。为了解决这样的问题,人们引入平衡二叉树的概念。所谓平衡二叉树,是指一棵树的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。通过恰当的构造与调整,平衡二叉树能够保证每次插入删除之后都保持平衡性。平衡二叉树的具体实现算法包括AVL算法和红黑算法等。由于平衡二叉树的实现比较复杂,故一般面试官只会问些概念性的问题。

满二叉树(full binary tree):如果一棵二叉树的任何结点,或者是叶节点,或者左右子树都存在,则这棵二叉树称作满二叉树。

完全二叉树(complete binary tree):如果一棵二叉树最多只有最下面的两层节点度数可以小于2,并且最下面一层的节点都集中在该层最左边的连续位置上,则此二叉树称作完全二叉树。

Free tree

指的是相互连接的无环无向图

假设 G = (V, E) 是一个无向图,那么下面的语句是等价的:

  1. G 是一个 free tree
  2. G 中的任意两个节点间都有唯一的一条路径
  3. G 是连通的的,但是如果去掉任何一条边,G 就不连通了
  4. G 是连通的,并且 $|E|=|V|-1$
  5. G 是无环的,并且 $|E|=|V|-1$
  6. G 是无环的,但是加入任何一条新的边,就会变成有环的

Forest 森林

同样是无环无向图,但不是所有的节点都是连通的

下图中包含一个环,所以不能算是森林:

Rooted Tree

有根的树也是一棵 free tree,但是其中一个节点和其他不同,称为根。有根树中有一些概念需要理解清楚,这里只列举出来不再赘述:ancestor, descendant, proper ancestor, proper descendant, parent, child, siblings, external node(leaf), internal node。

一个节点的孩子数量称之为节点的度(degree),从根到某节点的要经过的边的数量就是该节点的深度,最大的深度称为树的高度。

根树有几个特例,也非常常用,需要理解清楚,这里列举如下:

  • Binary tree
  • Full binary tree: each node is either a leaf or has degree exactly 2
  • Complete k-ary tree: a k-ary tree in which all leaves have the same depth and all internal nodes have degree k
  • Binary search tree: 一个节点的左右子节点和节点本身满足一定的大小关系

树的遍历

这一部分也是非常重要的内容,基本来说各类考点都在这里,不但需要对概念的清晰理解,还需要利用递归来解决问题(虽然不用递归也可以),主要有下面这四类:

  1. 前序遍历
  2. 中序遍历
  3. 后序遍历
  4. 层次遍历

具体的概念可以在 wiki 上查看,注意一下层次遍历可能需要一些特殊处理即可。

二叉树的常见操作包括树的遍历,即以一种特定的规律访问树中的所有节点。常见的遍历方式包括:

  • 前序遍历(Pre-order traversal):访问根结点;按前序遍历左子树;按前序遍历右子树。
  • 中序遍历(In-order traversal):按中序遍历左子树;访问根结点;按中序遍历右子树。特别地,对于二分查找树而言,中序遍历可以获得一个由小到大或者由大到小的有序序列。
  • 后续遍历(Post-order traversal):按后序遍历左子树;按后序遍历右子树;访问根结点。

以上三种遍历方式都是深度优先搜索算法(depth-first search)。深度优先算法最自然的实现方式是通过递归实现,事实上,大部分树相关的面试问题都可以优先考虑递归。此外,另一个值得注意的要点是:深度优先的算法往往都可以通过使用栈数据结构将递归化为非递归实现。这里利用了栈先进后出的特性,其数据的进出顺序与递归顺序一致(请见 Stack and Queue) 。

层次遍历(Level traversal):首先访问第0层,也就是根结点所在的层;当第i层的所有结点访问完之后,再从左至右依次访问第i+1层的各个结点。层次遍历属于广度优先搜索算法(breadth-first search)。广度优先算法往往通过队列数据结构实现。

B-Tree

如果我们想要表示一个 complete binary tree 的话,其实可以用数组来完成,这种结构其实也可以看成是一个堆。堆的话需要理解的不算特别多,注意下最大堆最小堆,以及对应的操作即可。另外前面提到的优先队列也可以认为是堆,不过这个不展开了。

这一部分我们着重来看看 B-Tree,这是一类搜索树,在给定 n 个节点的条件下,尽可能减少树的高度,相对于原来的二叉搜索树,B-Tree 做了两个调整:

  1. 节点可以有多于两个子节点
  2. 节点中可以保存多个元素

因为需要保存不定数量的元素,所以一般用 set 来实现(这种情况下不允许有重复的元素,重复的情况这里暂时不考虑)。稍微提一下,许多数据库都是用 B-Tree 实现的。

所有的 B-Tree 都有一个非常重要的常数 MINIMUM,决定了每个节点中需要保存多少元素,具体的规则如下:

  1. 根节点有 0 或 1 个元素,其他的节点至少需要保存 MINIMUM 个元素
  2. 一个节点中最多可以保存 2*MINIMUM 个元素
  3. 一个节点中保存的元素是有序的,从最小到最大
  4. 假设一个非叶节点中存有 N 个元素,那么它会有 N+1 个子树
  5. <

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0搭建出海 Demo:免费香港服务器实战指南

你有没有在通勤地铁上、午饭后摸鱼时&#xff0c;突然冒出一个想法&#xff1a;“要不我也做个应用试试&#xff1f;好像不少人靠这个补贴生活开销啊&#xff01;” 结果随手搜了几篇“海外项目经验分享”&#xff0c;瞬间被一堆术语劝退&#xff1a;CDN、备案、分发平台、服务…

《仿盒马》app开发技术分享--未完成订单列表展示逻辑优化(61)

技术栈 Appgallery connect 前言&#xff1a; 上一节我们实现订单与优惠券的联合提交时&#xff0c;我去到订单列表页面查看生成的订单信息&#xff0c;发现现在的订单从信息展示到价格计算全都是有问题的。所以紧急的把对应的问题修改一下。 问题来源&#xff1a; async …

手搓多模态-08 主模型的搭建(上)

前情回顾 在之前的章节我们已经构建好了视觉编码器&#xff0c;预处理模块&#xff0c;以及gemma模型的顶层。gemma模型的顶层&#xff0c;主要是构建图中圈出的输入&#xff0c;它把视觉编码器里每个图像patch的编码维度对齐到自然语言token的嵌入维度&#xff0c;并组装成了一…

Matlab 角点探测

文章目录 一、简介二、实现代码三、实现效果一、简介 这里实现一种角点探测功能,其思路仍然是借助图像的局部梯度信息,实现亚像素精度的角点定位。该功能核心思想是利用角点周围的局部梯度信息,通过加权最小二乘优化的方式迭代调整角点位置,使定位精度达到亚像素级别。整个…

错误监控----比如实现sentry一些思路

错误监控 ⼀、引⾔ 1.为什么需要前端错误监控 你的脚本在哪些边界条件下会报错&#xff1f; 你的脚本和样式兼容性如何&#xff1f; 有哪些地区不能正常访问你的⽹站&#xff1f; 出现问题之后&#xff0c;你如何快速定位排查&#xff0c;把损失降到最低&#xff1f; 如果你想解…

linux内核调试

1. 前置安装 1.1 编译好的内核 参考&#xff1a; https://blog.csdn.net/qq_51950769/article/details/148596916 1.2 编译busybox BusyBox 是一个非常轻量级的多合一工具箱&#xff0c;常被称为“Linux 的瑞士军刀”。 简单来说&#xff1a; 它把很多常用的 Linux 命令&am…

什么是曲面细分

什么是曲面细分 在CAD格式中&#xff0c;通常使用曲线和数学函数来定义曲面和实体。这些曲面的精确度和光滑度非常适用于制造过程。但是&#xff0c;现代GPU芯片针对由三角形网格体组成的曲面的渲染计算进行了高度优化。通常&#xff0c;实时渲染器和虚幻之类的游戏引擎只能处…

CANFD加速是什么?和CANFD有什么区别?

文章目录 摘要什么是CANFD加速?CAN FD的基本原理:仲裁阶段(Arbitration Phase):数据阶段(Data Phase):关键特性:优势:总结摘要 下面的截图,大家肯定不陌生,在使用CAN设备上位机的时候,已经选择了CANFD,但还有一个选项是“CANFD加速”,那CANFD加速和不加速有什么…

minio 启动失败--Incorrect Usage: flag provided but not defined: -consoleaddress

根据错误信息 flag provided but not defined: -consoleaddress&#xff0c;这表明 Minio 服务启动时使用了未定义的命令行参数 --consoleaddress&#xff0c;导致启动失败。这个问题与 Minio 版本兼容性有关。 问题原因 参数名称变更&#xff1a; Minio 版本 > RELEASE.20…

基于Rust的Polars学习笔记

基于Rust的Polars学习笔记 Polars 学习笔记 Cargo.toml通用配置 [package] name = "rustP" version = "0.1.0" edition = "2024"[dependencies] polars = { version = "0.48.1", features = ["full"]}Quickstart use po…

SpringBoot扩展——定时任务!

定时任务 项目开发中会涉及很多需要定时执行的代码&#xff0c;如每日凌晨对前一日的数据进行汇总&#xff0c;或者系统缓存的清理、对每日的数据进行分析和总结等需求&#xff0c;这些都是定时任务。单体系统和分布式系统的分布式任务有很大的区别&#xff0c;单体系统就一个…

RTDETRv2 pytorch 官方版自己数据集训练遇到的问题解决

rtdetrv2 训练问题遇到的问题。 pip install torch2.0.1 torchvision0.15.2 torchaudio2.0.2 --index-url https://download.pytorch.org/whl/cu117 1 Please make sure torchvision version > 0.15.2 发现自己实际装的是 torchvison0.15.2cu117 修改_misc.py中修改为…

Linux系统移植⑤:uboot启动流程详解-board_init_f执行过程

Linux系统移植⑤&#xff1a;uboot启动流程详解-board_init_f执行过程 _main 中会调用 board_init_f 函数。 board_init_f 函数主要有两个工作&#xff1a; ①初始化一系列外设&#xff0c;比如串口、定时器&#xff0c;或者打印一些消息等。 ②初始化 gd 的各个成员变量&am…

Git命令与代码仓库管理

步骤一、完成Gitee码云上账号注册并新建代码仓库。 1.1 新建代码仓库 1.2 填写信息并创建 1.3 获取仓库地址 https://gitee.com/dog-kidney/2022082206.git 步骤二、建立本地代码仓库&#xff0c;并连接到远程代码仓库。 2.1初始化 git init 2.2添加仓库 git remote add o…

资源占用多,Linux 系统中如何降低 CPU 资源消耗并提升利用率?

在 Linux 系统中降低 CPU 资源消耗并提升利用率,需从系统服务优化、进程管理、资源调度及内核参数调整等多维度入手。以下是适用于各类 Linux 发行版的通用优化方案,涵盖基础操作与进阶策略: 一、服务与进程优化:减少无效资源占用 1. 关闭冗余系统服务 查看运行中的服务 …

技术与情感交织的一生 (八)

目录 融合 东西厂公 接风宴 头痛 “巴巴罗萨” 突击 推进 助攻 96小时 寒冬 食堂 反攻 消耗 Delphi 西厂 内困 外患 “敦刻尔克” 多线作战 大撤退 资源 融合 东西厂公 初次来到纸箱厂&#xff0c;是主厂区&#xff0c;感觉很大&#xff0c;相对西面正在…

webuploader分片上传示例,服务端上传文件到腾讯云CDN Teo 应用示例

本文环境&#xff1a;php7.3.4 CI3.0框架 一、大概步骤&#xff1a; &#xff08;1&#xff09;利用百度的webuploader插件&#xff0c;将大文件分片上传的自己的服务器 &#xff08;2&#xff09;利用腾讯云接口从本服务器上传到腾讯云 二、详细代码&#xff1a; 1、进入…

LeetCode 632.最小区间

你有 k 个 非递减排列 的整数列表。找到一个 最小 区间&#xff0c;使得 k 个列表中的每个列表至少有一个数包含在其中。 我们定义如果 b-a < d-c 或者在 b-a d-c 时 a < c&#xff0c;则区间 [a,b] 比 [c,d] 小。 示例 1&#xff1a; 输入&#xff1a;nums [[4,10,…

篇章五 系统性能优化——资源优化——CPU优化(2)

目录 1.高级并发模式 1.1 工作窃取&#xff08;Work Stealing&#xff09; 1.工作窃取模式 2.ForkJoinPool实现 3.具体例子 1.2 结构化并发&#xff08;Structured Concurrency&#xff09; 1.结构化并发模式 2.Java 19 的 StructuredTaskScope 3.具体例子 1.3 对比与…

《中国电信运营商骨干网:历史、现状与未来演进》系列 第四篇:后发先至——中国移动CMNET的快速扩张与IP专网布局

摘要&#xff1a; 本文深入探讨中国移动骨干网CMNET (AS9808) 的发展历程、网络架构及其与中国电信扁平化策略的差异。同时&#xff0c;解析其为承载高价值业务而构建的IP专用承载网的定位、结构与技术特点。最后&#xff0c;展望中国移动在5G、云计算和算力网络时代&#xff0…