力扣144题:二叉树的先序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

输入:root = [1,2]
输出:[1,2]

示例 5:

输入:root = [1,null,2]
输出:[1,2]

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

【方法一】递归算法

二叉树的先序遍历按照:根-左-右来进行。

针对主函数,我们需要定义一个数组a,将遍历的树中元素放在数组中;returnSize指针所指向的值初始化为0,表示结果数组的大小初始为0;调用preorder函数,返回数组a。

针对调用函数,首先进行判断是否为空,为空的话直接进行返回,不需要进行任何操作。然后按照根-左-右来进行遍历。针对根节点处理:a[(*returnSize)++] = root->val。将根节点保持到数组中,然后将returnSize+1,进行下一个节点操作。

具体案例分析:

root = [1,null,2,3],输出:[1,2,3]。

针对主函数,开始时a[0]={},returnSize=0,然后调用preorder(root, a, returnSize)。

由于 root 不为空,访问 root->val,即1,将其添加到数组 a[0],并将 *returnSize 递增为1。然后递归调用 preorder(root->left, a, returnSize),但 root->left 为空,因此直接返回。

递归调用 preorder(root->right, a, returnSize)。

同样地,由于 root->right->val不为空,访问 root->val,即2,将其添加到数组 a[1],并将 *returnSize 递增为1。继续递归调用preorder(root->left, a, returnSize)。

进入左子树后,此时的root->left->val不为空,访问 root->val,即3,将其添加到数组 a[2],并将 *returnSize 递增为1。然后继续preorder(root->left, a, returnSize)和preorder(root->right, a, returnSize)。为空返回到上一层,进行调用root=2的右子树,preorder(root->right, a, returnSize)。为空,直接返回。

最终,数组 a 包含元素 [1, 2, 3],并且 *returnSize 为3。

返回数组 a。

(整个流程可以描述为,root=1->返回1->preorder(root->left, a, returnSize)为空->调用preorder(root->right, a, returnSize)进入右子树,此时root=2->返回2->调用preorder(root->left, a, returnSize)进入左子树,此时root=3->返回3->preorder(root->left, a, returnSize)和preorder(root->right, a, returnSize)为空,返回到根为2的这一层,调用preorder(root->right, a, returnSize)为空。循环和调用结束。返回a[1,2,3])

C语言具体代码如下:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
/*** Note: The returned array must be malloced, assume caller calls free().*/
void preorder(struct TreeNode* root, int* a, int *returnSize){if(!root)return ;a[(*returnSize)++] = root->val;preorder(root->left,a, returnSize);preorder(root->right, a, returnSize);
}int* preorderTraversal(struct TreeNode* root, int* returnSize) {*returnSize = 0;int *a = (int*)malloc(sizeof(int)*100);preorder(root,a,returnSize);return a;}

时间复杂度O(n);空间复杂度O(n)

【方法二】非递归算法

二叉树的中序遍历按照:根-左-右来进行

非递归通过栈来进行模拟。

第一步:创建一个栈。

第二步:定义一个stack来开辟一个栈空间。并将栈初始化,top=0。定义一个数组,用来返回最后中序遍历后的树,returnSize指针所指向的值初始化为0,定义一个移动指针p指向树的根,用来遍历树。

第三步:树不为空的时候 ,入栈,然后将栈中的元素给数组,并向左遍历。左子树为空的时候,将p指针向下移动,并向右遍历树。最后返回数组a。

具体案例分析:

root = [1,null,2,3],输出:[1,2,3]。

开始时p指向root,也就是1,不为空,执行if(p != NULL)中的语句,将1进行入栈,将top++,也就是等于1,然后将栈中的元素给数组a,并将(*returnSize)++,此时returnSize=1。遍历左子树,此时为空,执行else中的语句,首先是p = stack->s[(stack->top) - 1](此时p=stack->[0]=1,也就是将p指针移回到1),然后(stack->top)--(也就是stack->top=0),下一句是 p = p->right(也就是2),开始遍历1的右子树。

此时p=2,不为空,执行if(p != NULL)中的语句,将2进行入栈,将top++,也就是等于1,然后将栈中的元素给数组a,并将(*returnSize)++,此时returnSize=2。然后继续向左遍历。此时p=3,不为空,执行if(p != NULL)中的语句,将3进行入栈,将top++,也就是等于2,然后将栈中的元素给数组a,并将(*returnSize)++,此时returnSize=3。然后继续向左遍历,为空,则进行else语句的执行。

首先是p = stack->s[(stack->top) - 1](此时p=stack->[1]=3,也就是将p指针移回到3),然后(stack->top)--(也就是stack->top=1),下一句是 p = p->right,为空,继续进入else语句的执行。首先是p = stack->s[(stack->top) - 1](此时p=stack->[0]=2,也就是将p指针移回到2),然后(stack->top)--(也就是stack->top=0),下一句是 p = p->right,为空,此时不符合while循环,跳出。结束。最后返回a=[1,2,3]。

C语言具体代码如下:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
/*** Note: The returned array must be malloced, assume caller calls free().*/
// 创建栈
struct stack {struct TreeNode *s[100];int top;
};// 先序遍历函数
int* preorderTraversal(struct TreeNode* root, int* returnSize) {// 开辟一个栈空间struct stack *stack = (struct stack *)malloc(sizeof(struct stack));// 初始化stack->top = 0;// 定义一个数组,用来返回最后先序遍历后的树int *a = (int *)malloc(sizeof(int) * 100);// returnSize指针所指向的值初始化为0*returnSize = 0;struct TreeNode *p = root; // 定义一个移动指针指向树的根,用来遍历树while (p != NULL || (stack->top) != 0) { // 树不为空或者栈不为空的时候,进行入栈和出栈操作if (p != NULL) { // 树不为空的时候 ,向左遍历。并入栈stack->s[stack->top] = p;(stack->top)++;a[(*returnSize)++] = p->val; // 访问当前节点p = p->left;} else {// 左子树为空,右进行遍历右字树p = stack->s[(stack->top) - 1];(stack->top)--;p = p->right;}}return a;
}

时间复杂度O(n);空间复杂度O(h)

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

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

相关文章

C++入门学习——初始化列表

概念 初始化列表&#xff1a;以一个冒号开始&#xff0c;接着是一个以逗号分隔的数据成员列表&#xff0c;每个"成员变量"后面跟一个放在括 号中的初始值或表达式 class Date { public://初始化列表Date(int year,int month,int day):_year(year),_month(month),_d…

[Windows] 油.管视频下载神器 Gihosoft TubeGet Pro v9.3.88

描述 对于经常在互联网上进行操作的学生&#xff0c;白领等&#xff01; 一款好用的软件总是能得心应手&#xff0c;事半功倍。 今天给大家带了一款高科技软件 管视频下载神器 无需额外付费&#xff0c;永久免费&#xff01; 亲测可运行&#xff01;&#xff01; 内容 目前主…

高德地图显示圆形区域并在区域边上标注半径

bug&#xff1a;循环创建三个圆形区域 &#xff0c;数组设置为[{raduis:500,color:“#FF0000”}]&#xff0c;然后循环取颜色会莫名其妙报错修改为 strokeColor: [“#FF0000”, “#1EE3C2”, “#3772E9”][i]即可 initAMap() {AMapLoader.load({key: "130cca3be68a2ff0fd5…

记VMware网络适配器里的自定义特定虚拟网络一直加载问题解决办法

1、问题描述 VMware网络适配器里的自定义特定虚拟网络一直加载问题&#xff1a; 在自定义&#xff1a;特定虚拟网络选择的时候 没有上图所示的三个选择&#xff0c;而是正在加载虚拟网络.... 如下图所示&#xff1a; 2、解决办法 2.1、原因分析&#xff1a; 是安装时候出现…

安防视频监控/视频汇聚EasyCVR平台浏览器http可以播放,https不能播放,如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台基于云边端一体化架构&#xff0c;兼容性强、支持多协议接入&#xff0c;包括国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SD…

7.15洛谷蓝题

二分答案的两个模板&#xff1a; 1.最小值的最大化&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include<bits/stdc.h> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> #include<…

Studying-代码随想录训练营day40| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

第40天&#xff0c;动态规划part07&#xff0c;动态规划经典题型“打家劫舍”(ง •_•)ง&#xff0c;编程语言&#xff1a;C 目录 198.打家劫舍 213.打家劫舍II 337.打家劫舍III 总结 198.打家劫舍 文档讲解&#xff1a;代码随想录打家劫舍 视频讲解&#xff1a;手…

【C++进阶学习】第七弹——AVL树——树形结构存储数据的经典模块

二叉搜索树&#xff1a;【C进阶学习】第五弹——二叉搜索树——二叉树进阶及set和map的铺垫-CSDN博客 目录 一、AVL树的概念 二、AVL树的原理与实现 AVL树的节点 AVL树的插入 AVL树的旋转 AVL树的打印 AVL树的检查 三、实现AVL树的完整代码 四、总结 前言&#xff1a…

JavaScript青少年简明教程:输入输出

JavaScript青少年简明教程&#xff1a;输入输出 JavaScript的输入输出情况相对复杂&#xff0c;因为它依赖于其运行的宿主环境&#xff08;如Web浏览器或Node.js&#xff09;来提供具体的输入输出机制。JavaScript的核心规范&#xff08;ECMAScript&#xff09;本身并不直接提…

C基础day9

一、思维导图 二、课后练习 1> 使用递归实现 求 n 的 k 次方 #include<myhead.h>int Pow(int n,int k) {if(k 0 ) //递归出口{return 1;}else{return n*Pow(n,k-1); //递归主体} }int main(int argc, const char *argv[]) {int n0,k0;printf("请输入n和k:&…

韩国coupang上线的卖家官网是什么?韩国电商有哪些平台?

根据Statista的调查报告&#xff0c;预计2024年电子商务市场收入将达到4.117亿美元。而韩国的电子商务市场是全球最具活力和创新性的市场之一&#xff0c;有数据显示2023年韩国电商市场规模已突破1700亿美元&#xff0c;全球排名第四。 韩国coupang上线的卖家官网是什么&#x…

Linux虚拟机扩展磁盘空间

文章目录 在VM上进行扩展新的磁盘空间进入虚拟机将扩展的磁盘空间分配给对应的分区 VM 下的Linux虚拟机提示磁盘空间不足&#xff0c;需要对其进行磁盘扩容&#xff0c;主要有以下两步&#xff1a; 在VM上进行扩展新的磁盘空间 先关闭虚拟机在VM的虚拟机设置处进行硬盘扩展 …

Redislnsight-v2远程连接redis

redis安装内容添加&#xff1a; Linux 下使用Docker安装redis-CSDN博客 点击添加 添加ip地址&#xff0c;密码&#xff0c;端口号 创建完成 点击查看内容&#xff1a;

Redis的单线程讲解与指令学习

目录 一.Redis的命令 二.数据类型 三.Redis的key的过期策略如何实现&#xff1f; 四.Redis为什么是单线程的 五.String有关的命令 Redis的学习专栏&#xff1a;http://t.csdnimg.cn/a8cvV 一.Redis的命令 两个基本命令 在Redis当中&#xff0c;有两个基本命令&#xff1…

记录些MySQL题集(3)

MySQL 分区技术深入解析 分区的基本概念 MySQL分区 是一种数据库优化的技术&#xff0c;它允许将一个大的表、索引或其子集分割成多个较小的、更易于管理的片段&#xff0c;这些片段称为“分区”。每个分区都可以独立于其他分区进行存储、备份、索引和其他操作。这种技术主要…

Docker初识及使用研究

公司使用docker&#xff0c;小组成员人人都是默默使用&#xff0c;也没讲解培训&#xff0c;真是搞笑。 记录自己独自研究及使用&#xff1a; 1)自己安装->失败-系统弄崩->安装成功 目录 1. Docker安装-初次安装失败2. Docker安装-初次安装成功 1. Docker安装-初次安装失…

微信小程序密码 显示隐藏 真机兼容问题

之前使用type来控制&#xff0c;发现不行&#xff0c;修改为password属性即可 <van-fieldright-icon"{{passwordType password? closed-eye:eye-o}}"model:value"{{ password }}"password"{{passwordType password ? true: false}}"borde…

PostgreSQL 中如何解决因长事务阻塞导致的其他事务等待问题?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何解决因长事务阻塞导致的其他事务等待问题&#xff1f;一、了解长事务阻塞的原因&…

结合实体类型信息(2)——基于本体的知识图谱补全深度学习方法

1 引言 1.1 问题 目前KGC和KGE提案的两个主要缺点是:(1)它们没有利用本体信息;(二)对训练时未见的事实和新鲜事物不能预测的。 1.2 解决方案 一种新的知识图嵌入初始化方法。 1.3 结合的信息 知识库中的实体向量表示&#xff0b;编码后的本体信息——>增强 KGC 2基…

思迈特软件2023H2商业智能和分析软件市场份额增长速度跃居第一

近日&#xff0c;全球知名的IT市场研究与咨询公司IDC发布了《中国商业智能和分析软件市场跟踪报告&#xff0c;2023H2》。根据报告显示&#xff0c;思迈特软件在中国商业智能和分析软件市场份额中位列前五&#xff0c;在中国BI厂商中排名TOP2。 尤其值得一提的是&#xff0c;思…