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

news2024/11/14 4:10:21

给你二叉树的根节点 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.coloradmin.cn/o/1927856.html

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

相关文章

跳妹儿学编程之ScratchJr(9):程序控制积木篇—短跑比赛

跳妹儿学编程之ScratchJr(7)&#xff1a;动作积木篇—爸爸去散步 跳妹儿学编程之ScratchJr(8)&#xff1a;外观积木篇—捉迷藏 跳妹儿学编程之ScratchJr(9)&#xff1a;程序控制积木篇—短跑比赛 引言 在之前的一篇文章中&#xff0c;我们了解了ScratchJr的动作积木和外观积…

排序(三)——归并排序(MergeSort)

欢迎来到繁星的CSDN&#xff0c;本期内容主要包括归并排序(MergeSort)的实现 一、归并排序的主要思路 归并排序和上一期讲的快速排序很像&#xff0c;都利用了分治的思想&#xff0c;将一整个数组拆成一个个小数组&#xff0c;排序完毕后进行再排序&#xff0c;直到整个数组排序…

php反序列化--2--PHP反序列化漏洞基础知识

一、什么是反序列化&#xff1f; 反序列化是将序列化的字符串还原为PHP的值的过程。 二、如何反序列化 使用unserialize()函数来执行反序列化操作 代码1&#xff1a; $serializedStr O:8:"stdClass":1:{s:4:"data";s:6:"sample";}; $origina…

autoware.universe源码略读(3.15)--perception:object_merger

autoware.universe源码略读3.15--perception:object_merger Overviewnode&#xff08;enum&#xff09;MSG_COV_IDX&#xff08;Class&#xff09;ObjectAssociationMergerNode&#xff08;Func&#xff09;isUnknownObjectOverlapped&#xff08;Func&#xff09;convertListT…

Directory Opus 13 专业版(Windows 增强型文件管理器)值得购买?

在使用电脑时&#xff0c;总少不了和文件打交道。系统自带的 Explorer 资源管理器功能又非常有限&#xff0c;想要拥有一个多功能文件管理器吗&#xff1f; Directory Opus 是一款老牌多功能文件管理器&#xff0c;能很好地接管 Windows 资源管理器。 接管资源管理器 Directo…

【Linux系列】TEE 命令:同时输出到终端和文件

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

(leetcode学习)15. 三数之和

给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 示例 1&a…

java算法day13

java算法day13 104 二叉树的最大深度111 二叉树的最小深度226 翻转二叉树101 对称二叉树100 相同的树 104 二叉树的最大深度 我最开始想到的是用层序遍历。处理每一层然后计数。思路非常的清楚。 迭代法&#xff1a; /*** Definition for a binary tree node.* public class…

Nginx入门到精通三(反向代理1)

下面内容整理自bilibili-尚硅谷-Nginx青铜到王者视频教程 Nginx相关文章 Nginx入门到精通一&#xff08;基本概念介绍&#xff09;-CSDN博客 Nginx入门到精通二&#xff08;安装配置&#xff09;-CSDN博客 Nginx入门到精通三&#xff08;Nginx实例1&#xff1a;反向代理&a…

Linux系统搭建轻量级个人博客VanBlog并一键发布公网远程访问

文章目录 前言1. Linux本地部署2. VanBlog简单使用3. 安装内网穿透4. 创建公网地址5. 创建固定公网地址 前言 今天和大家分享如何在Linux Ubuntu系统搭建一款轻量级个人博客VanBlog&#xff0c;并结合cpolar内网穿透软件生成公网地址&#xff0c;轻松实现随时随地远程访问本地…

Python与自动化脚本编写

Python与自动化脚本编写 Python因其简洁的语法和强大的库支持&#xff0c;成为了自动化脚本编写的首选语言之一。在这篇文章中&#xff0c;我们将探索如何使用Python来编写自动化脚本&#xff0c;以简化日常任务。 一、Python自动化脚本的基础 1. Python在自动化中的优势 Pyth…

内存RAS技术介绍:内存故障预测

故障预测是内存可靠性、可用性和服务性&#xff08;RAS&#xff09;领域中的一个重要方面&#xff0c;旨在提前识别潜在的不可纠正错误&#xff08;UE&#xff09;&#xff0c;以防止系统崩溃或数据丢失。 4.1 错误日志记录与预测基础 错误一般通过Linux内核模块Mcelog记录到…

1.31、基于长短记忆网络(LSTM)的发动机剩余寿命预测(matlab)

1、基于长短记忆网络(LSTM)的发动机剩余寿命预测的原理及流程 基于长短期记忆网络(LSTM)的发动机剩余寿命预测是一种常见的机器学习应用&#xff0c;用于分析和预测发动机或其他设备的剩余可用寿命。下面是LSTM用于发动机剩余寿命预测的原理和流程&#xff1a; 数据收集&#…

实践之K近邻算法实现红酒聚类

前言 K近邻算法是一种用于分类和回归的非参数统计方法&#xff0c;通过计算样本与训练样本的距离&#xff0c;找出最接近的k个样本进行投票来确定分类结果。算法的基本要素包括K值、距离度量和分类决策规则。 K值决定了邻居的影响程度&#xff0c;距离度量反映了样本间的相似度…

python条件

条件语句 if语句 if...else语句 if...elif...else语句 嵌套 is is 是一个身份运算符&#xff0c;用于比较两个对象的身份&#xff0c;即它们在内存中的地址是否相同。这与比较两个对象是否相等的 运算符不同。 运算符比较的是两个对象的值是否相等。 比较对象 比较基本数据…

npm发布的包如何快速在cnpm上使用

npm发布的包如何快速在cnpm上使用 解决方案 前往淘宝npm镜像官网 搜索插件库并点击同步 等待一分钟即可查看最新版本

C++ 类和对象 赋值运算符重载

前言&#xff1a; 在上文我们知道数据类型分为自定义类型和内置类型&#xff0c;当我想用内置类型比较大小是非常容易的但是在C中成员变量都是在类(自定义类型)里面的&#xff0c;那我想给类比较大小那该怎么办呢&#xff1f;这时候运算符重载就出现了 一 运算符重载概念&…

ts踩坑!vue3中defineEmits接收父组件向子组件传递方法,以及方法所需传的参数及类型定义!

使用说明 1、在子组件中调用defineEmits并定义要发射给父组件的方法 const emits defineEmits([‘foldchange’]) 2、使用defineEmits会返回一个方法&#xff0c;使用一个变量emits(变量名随意)去接收 3、在子组件要触发的方法中&#xff0c;调用emits并传入发射给父组件的方法…

【C语言初阶】探索编程基础:深入理解分支与循环语句的奥秘

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C语言 “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C语言入门 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀分支与循环语句 &#x1f4d2;1.…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十三)-更换无人机控制器

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…