数据结构与算法三【树】

news2024/10/6 18:33:13

二叉树性质

满二叉树在这里插入图片描述

深度为k,有 2 k − 1 2^{k}-1 2k1个结点的二叉树,为满二叉树。

完全二叉树

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。

二叉树的存储方式

包括链式存储和顺序存储
由于链式存储的二叉树更有利于我们理解,所以我们一般都是用链式存储二叉树。
所以大家要了解,用数组依然可以表示二叉树。

在这里插入图片描述

二叉树链式存储代码

struct TreeNode{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x):val(x),left(NULL),right(NULL){}
};

二叉树的遍历方式

遍历方式分两类,四种

关于二叉树的遍历方式,首先从深度和广度来区分。

  1. 深度优先遍历:先往深走,遇到叶子节点再往回走。
  2. 广度优先遍历:一层一层地去遍历。
    这两种遍历是图论中最基本的两种遍历方式,后面在介绍图论的时候,还会介绍到。

那么我们进一步扩展深度优先遍历和广度优先遍历,才会有更为细致的遍历方式的区分:

  • 深度优先遍历
    • 前序遍历(递归法,迭代法)
    • 中序遍历(递归法,迭代法)
    • 后序遍历(递归法,迭代法)
  • 广度优先遍历
    • 层次遍历(迭代法)
      在深度优先遍历中:有三个顺序,前中后序遍历,有同学总分不清这三个顺序,经常搞混,我这里教大家一个技巧。
      这里前中后,其实指的就是中间节点的遍历顺序,只要大家记住,前中后序指的就是中间节点的位置就可以了。看如下节点的遍历顺序,就可以发现中间节点的顺序就是所谓的遍历方式名称的由来:
  • 前(先)序遍历:中左右
  • 中序遍历:左中右
  • 后序遍历:左右中

遍历方式的实现

最后再说一说二叉树中深度优先遍历和广度优先遍历的实现方式。我们做二叉树相关的题目,经常会使用递归的方式来实现深度优先遍历。
之前讲栈的时候,说过栈其实就是递归的一种实现结构,先进后出。也就就是说前中后序遍历的逻辑其实都是可以借助栈使用非递归的方式来实现。(通过栈的结构避免了递归操作)

而广度优先遍历的实现,一般借助队列来实现,这也是由于队列先进先出的特点所决定的,因为需要先进先出的结构,才能一层一层的来遍历二叉树。

这里其实我们又了解了栈与队列的一个应用场景了。
具体的实现我们后面都会讲的,这里大家先要清楚这些理论基础。

二叉树与递归(二叉树的递归遍历)

说到二叉树,就不得不说递归,很多同学对递归都是又熟悉又陌生,递归的代码一般很简短,但每次都是一看就会,一写就废。

递归写不好的根本原因就是不成体系,没有递归方法论。通过二叉树的前中后序的递归写法,我们把递归方法论确定下来,进而应对复杂的递归题目。

首先,每次写递归算法,先确定三要素:

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
  3. **确定单层递归的逻辑:**确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

那三要素怎么切入,怎么找呢?
我们以前序遍历为例子,来找感觉!
1.确定递归函数的参数和返回值:因为我们要打印前序遍历节点的数值,因此参数里需要传入vector来放节点的数值,除了这一点就不需要再处理什么数据了,也不需要有返回值,所以递归函数返回类型就是void,代码如下:
(代码随想录点评:为什么要传入vector没讲清楚,另外代码还传入了节点本身,也很令人困惑?因为后面说的是除了vector不需要再处理什么数据了,也不需要有返回值,但是没提到传入TreeNode *cur的目的,但是我的猜想是,对树本身进行处理,肯定是要传入当前处理的树节点的指针的,至于为什么一定要用vector来放节点的数值,我想不通,希望后面会想通)

void traversal(TreeNode* cur, vector<int>& vec)

2.确定终止条件:在递归过程中,如何算递归结束?对于前序遍历,如果当前遍历的节点是空了,就说明递归结束了,所以如果当前遍历的节点是空,就直接return,代码如下:

if (cur == NULL) return;

3.确定单层递归的逻辑:前序遍历是中左右的顺序,因此单层递归的逻辑就是,先取中点节点的数值,(单层递归的逻辑这个概念讲的也不通!! 首先,什么是单层递归?如果重复调用单层递归实现递归的过程? 我的理解就是,每读到一个新数据,应当怎么处理这个数据,这个就是单层递归的数据处理逻辑!!!数据处理完成之后,就到了递归的逻辑了,单层递归本质上在数据处理完之后就结束了!!!后面就是递归的逻辑,例如这里递归下一个处理的数据是左子树的节点,因此对左子树进行递归,然后处理右子树,这里就继续对右子树进行递归!! 因此这里所说的单层递归,本质上就是一次数据处理过程+后面需要继续递归的数据!!!)

因此,代码如下

vec.push_back(cur->val);    // 中
traversal(cur->left, vec);  // 左
traversal(cur->right, vec); // 右

到这,我仍然看不懂,原因在于,我不知道TreeNode* cur的意义,以及vector &vec的意义,这就是代码随想录这一部分的败笔,读者很难理解!!!

然而,当读者继续往下读,读到整体代码的时候,就会恍然大悟:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result; //vector就是我们的遍历结果存储向量
        traversal(root, result);//遍历需要输入树的根节点
        return result;
    }
};

vector就是我们的遍历结果存储向量;遍历需要根据树逐步往下走,因此需要传入树根,并根据树根往下走,因此需要传入TreeNode* cur这参数。

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

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

相关文章

【jQuery】常用API——jQuery选择器

一、 jQuery基础选择器原生JS获取元素方式很多&#xff0c;很杂&#xff0c;而且兼容性情况不一致&#xff0c;因此jQuery给我们做了封装&#xff0c;使荻取元素统一标准。$(“选择器”); //里面选择器直接写CSS选择器即可&#xff0c;但是要加号<script src"../jquery…

Ubuntu18.04系统 部署python3.9.0 源码编译安装及pip配置全过程记录

1.Ubuntu系统镜像下载和基本配置 1.1 镜像下载 镜像下载&#xff1a;https://cn.ubuntu.com/download/desktop 1.2 配置静态IP 配置固定IP方式&#xff1a; Ubuntu18之前在/etc/network/interfaces进行配置&#xff0c;Ubuntu18及之后版本在/etc/netplan/*.yaml进行配置&am…

Node.JS(1)

目录 命令行窗口&#xff08;cmd窗口、小黑屏、终端、shell&#xff09; 环境变量 命令行窗口&#xff08;cmd窗口、小黑屏、终端、shell&#xff09; winR快捷键-->cmd 常用指令 dir 列出当前目录下的所有文件 cd 目录名 进入到指定的目录 md 目录名 创建一个文件…

redis安装和使用说明

Redis安装说明大多数企业都是基于Linux服务器来部署项目&#xff0c;而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis.此处选择的Linux版本为CentOS 7.Redis的官方网站地址&#xff1a;https://redis.io/1.单机安装Redis1.1.安装Redis依…

数字验证学习笔记——SystemVerilog芯片验证23 ——数据采样

一、数据采样 当你coverpoint指定采样一个变量或表达式时&#xff0c;SV会创建很多“仓&#xff08;bin&#xff09;”来记录每个数值被捕捉到的次数。这些bin是衡量功能覆盖率的基本单位。covergroup中可以定义多个coverpoint&#xff0c;coverpoint中可以自定义多个cover bi…

SAP灵活工作流场景模板创建

目录 1. 创建流程对象容器 2. 编辑模板中的灵活块 3. 设置工作流启动事件 4. 设置工作流运行时事件 5. 设置工作流输出结果&#xff08;可选&#xff09; 6. 工作流控制类 7. 创建流程活动 8. 创建流程条件 9. 代理规则 9. 值帮助 10. 参考时间 11. 电子邮件模版 …

[ AWS - SAA ] 解决方案架构师之设计弹性架构 - 选择可靠的弹性存储(如何选择 SSD vs. HDD)

本系列博文会围绕AWS Well-Architected 和六大支柱进行讲解&#xff0c;这些领域的内容对成为AWS亚马逊云科技上的 解决方案架构师&#xff08;SAA&#xff09; 非常重要。 本文主要介绍AWS亚马逊云中&#xff0c;关于弹性架构设计中存储设备的一些讲解。 本文的部分内容适用于…

哈希切割 + 位图 + 布隆过滤器 —— 海量数据面试题

目录 题目一&#xff1a;给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址&#xff1f; 哈希切割 题目二&#xff1a;给定100亿个整数&#xff0c;设计算法找到只出现一次的整数&#xff1f; 解法一&#xff1a;哈希切割 解法二&#xf…

【论文精读】Guided-MVS

今天读的是一篇发表在IROS2022上的MVS文章&#xff1a;Multi-View Guided Multi-View Stereo&#xff0c;作者是来自于意大利University of Bologna的Matteo Poggi。 论文链接&#xff1a;arxiv 代码链接&#xff1a;https://github.com/andreaconti/multi-view-guided-multi-v…

SpringCloud Netflix复习之OpenFeign

文章目录写作背景Feign核心组件介绍Encoder和DecoderLoggerContractFeign.Builder上手实战开启FeignClient调用请求日志给FeignClient注入自定义拦截器Feign支持文件上传配置Feign开启Gzip压缩Feign配置超时时间Feign整合Ribbon支持负载均衡核心源码部分FeignClient注入到Sprin…

【Qt】通过创建ui界面类成员变量的方式显示窗体

【Qt】通过创建ui界面类成员变量的方式显示窗体1、背景2、实例3、验证1、背景 将.ui 文件转化为.h 头文件参考&#xff1a; 【Qt】将QtDesigner生成的.ui文件转化为.h头文件 https://jn10010537.blog.csdn.net/article/details/128589666其生成的.h头文件的显示&#xff0c;如…

HQChart实战教程56-限制指标周期

HQChart实战教程56-限制指标周期 指标周期范围效果图增加周期限制步骤1. 创建系统指标Condition.PeriodCONDITION_PERIOD 枚举说明提示信息提示信息配色实例源码指标周期范围 有些指标我们需要限制它的周期, 如指标A它只能对日线周期有效, 分时周期时无效的, 所有在切换到分…

Apache Hive 使用

Apache Hive 使用使用beeline 连接Apache Hive查看数据库使用或进入数据库创建表查看数据表上传数据数据操纵语言&#xff08;DML&#xff09;查询语句函数数学函数条件函数) 使用beeline 连接Apache Hive /export/server/apache-hive-3.1.2-bin/bin/beelinebeeline> ! co…

C51单片机基础之4G模块

一、4G模块初识EC03-DNC是亿佰特公司推出的 LTE CAT1 数传模块产品&#xff0c; 该产品软件功能完善&#xff0c; 覆盖绝大多数常规应用场景&#xff0c; EC03-DNC 是为实现串口设备与网络服务&#xff0c;通过网络相互传输数据而开发的产品 &#xff0c; 该产品是一款带分集接…

Linux 计算机网络 从 ping 来初窥计算机网络

Linux 计算机网络 从 ping 来初窥计算机网络 在上一章节《计算机网络从零到一》我们重点讲解了整个网络的形成&#xff0c;以及物理层、数据链路层、网络层这三层的形成以及他们所解决的问题&#xff0c;而本章节主要讲解 ping 命令在 Linux 中到底发生了一些什么。 ping 简介…

学习open62541 --- [73] 数据源造成无法监测变量的问题解决

本人最近遇到一个问题&#xff1a;给一个变量添加数据源后&#xff0c;使用监测项去监测变量变化&#xff0c;如果采样时间为0&#xff0c;会发现无法监测到变量的变化。 本文讲述这种情况的发生原因以及解决办法。 一 Server例子 首先准备server例子&#xff0c;如下&#x…

WSL 下载服务器加速

网络下载加速&#xff0c;这里使用修改 hosts 文件 &#xff0c;地址映射 方法&#xff0c;所有网址适用&#xff0c;这里以 WSL 下载服务器为例子 命令 wsl -l -o 访问的地址&#xff1a; https://raw.githubusercontent.com/microsoft/WSL/master/distributions/Distributi…

Java设计模式中组合模式是什么/树形结构怎么组合或显示存储,编程怎么实现树形结构

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 5.7 组合模式 5.7.1 概述 又名整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次属于…

基于asp.net+vbscript+wsc编写网站

1、前言 asp大家应该都比较熟悉&#xff0c;就是一个动态服务器页面&#xff0c;有点类似于jsp。只是不同的是asp可以在IIS服务器上创建&#xff0c;并且如果配置了.net环境的话&#xff0c;那么就可以在asp里面<%%>写vbscript。vbscript是一种脚本语言&#xff0c;其实就…

因果推断5--DML(个人笔记)

目录 1论文介绍 1.1论文 1.2摘要 1.3DML思路 2价格需求曲线 2.1价格需求弹性 2.2价格需求弹性计算DML代码 2.3价格需求弹性例子--数据集 2.4建模过程 2.5回归结果 1论文介绍 1.1论文 V. Chernozhukov, D. Chetverikov, M. Demirer, E. Duflo, C. Hansen, and a. W.…