力扣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.mfbz.cn/a/799672.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【云岚到家】-day05-6-项目迁移-门户-CMS

【云岚到家】-day05-6-项目迁移-门户-CMS 4 项目迁移-门户4.1 迁移目标4.2 能力基础4.2.1 缓存方案设计与应用能力4.2.2 静态化技术应用能力 4.3 需求分析4.3.1 界面原型 4.4 系统设计4.4.1 表设计4.4.2 接口与方案4.4.2.1 首页信息查询接口4.4.3.1 数据缓存方案4.4.3.2 页面静…

【绝命Coding助力秋招】Python实现<实习僧>海投脚本

hello hello~ &#xff0c;这里是绝命Coding——老白~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;绝命Coding-CSDN博客 &a…

Java 实验三:数组操作以及Java中的方法

一、实验目的 1、掌握数组的声明、初始化、查找、排序等的方式&#xff1b; 2、掌握Java中如何定义一个方法&#xff0c;定义好的方法如何进行调用等。 二、实验环境 1、windows11; 2、JDK1.8,集成开发环境Eclipse。 三、实验内容 1、 定义一个函数&#xff0c;获取某个…

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

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

网络配置命令

文章目录 一、查看网络接口信息 ifconfig1.1 网络接口名称1.2 使用 ifconfig 查看网络接口信息1.2.1 输出示例1.2.2 输出解释 1.3 查看特定网络接口信息1.3.1 输出示例 1.4 查看所有网络接口信息1.5 特殊网络接口 二、修改网络配置文件2.1 配置文件示例2.2 使配置生效2.3 关闭 …

JavaScript日期对象倒计时案例

思路&#xff1a;1.先求出当前时间的总毫秒数 2.再求出所需要求的时间的总毫秒数 3.用所求时间的减去当前时间的可得到倒计时剩余时间 4.最后将所求的倒计时剩余时间转换为天&#xff0c;小时&#xff0c;分钟&#xff0c;秒即可 <!DOCTYPE html> <html lang"en…

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

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

可观察性优势:掌握当代编程技术

反馈循环是我们开发人员工作的关键。它们为我们提供信息&#xff0c;并让我们从用户过去和现在的行为中学习。这意味着我们可以根据过去的反应进行主动开发。 TestComplete 是一款自动化UI测试工具&#xff0c;这款工具目前在全球范围内被广泛应用于进行桌面、移动和Web应用的…

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

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

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

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

Nuxt.js 错误侦探:useError 组合函数

title: Nuxt.js 错误侦探&#xff1a;useError 组合函数 date: 2024/7/14 updated: 2024/7/14 author: cmdragon excerpt: 摘要&#xff1a;文章介绍Nuxt.js中的useError组合函数&#xff0c;用于统一处理客户端和服务器端的错误&#xff0c;提供statusCode、statusMessage和…

PostgreSQL修改最大连接数

在使用PostgreSQL 的时候&#xff0c;经常会遇到这样的错误提示&#xff0c; sorry, too many clients already&#xff0c;这是因为默认PostgreSQL最大连接数是 100, 一般情况下&#xff0c;个人使用时足够的&#xff0c;但是在生产环境&#xff0c;这个连接数是远远不够的&am…

内存函数(C语言)

内存函数 以下函数的头文件&#xff1a;string.h 针对内存块进行处理的函数 memcpy 函数原型&#xff1a; void* memcpy(void* destination, const void* source, size_t num);目标空间地址 源空间地址num&#xff0c;被拷贝的字节个数 返回目标空间的起始地…

火星全球彩色影像图介绍(中分辨率相机)

一、数据基本信息 该数据是利用天问一号轨道器中分辨率相机获取的影像经光度校正、几何校正、全球制图等制作而成的全火星地图数据DOM&#xff0c;每个数据包含一个tif数据文件。该影像图分辨率为76米。 任务型号&#xff1a;天问一号 搭载平台&#xff1a;环绕器 数据获…

2.The DispatcherServlet

The DispatcherServlet Spring的Web MVC框架与许多其他Web MVC框架一样&#xff0c;是请求驱动的&#xff0c;围绕一个中央Servlet&#xff08;即DispatcherServlet&#xff09;设计&#xff0c;该Servlet将请求分派给控制器&#xff0c;并提供其他功能以促进Web应用程序的开发…

实现keepalive+Haproxyde 的高可用

需要准备五台实验机 一台客户机&#xff1a;test1 两台&#xff1a;一主一备的实验机&#xff1a;test2 test3 两台真实服务器&#xff1a;nginx1 nginx2 实验 首先在两台实验机上安装Haproxy 安装依赖环境&#xff0c;并将Haproxy的包进行解压处理 yum install -y pcre…

redis redisson(仅供自己参考)

redis 通过setnx实现的分布式锁有问题 如图&#xff1a; 解决的新的工具为&#xff08;闪亮登场&#xff09;&#xff1a;redisson redisson可重入锁的原理 实现语言lua&#xff1a; 加锁实现脚本语言&#xff1a; 释放锁的脚本语言&#xff1a; 加锁的lua -- 首先判断这个锁…

【算法专题】归并排序

1. 排序数组 912. 排序数组 - 力扣&#xff08;LeetCode&#xff09; 今天我们使用归并排序来对数组进行排序&#xff0c;实际上&#xff0c;归并排序和快速排序是有一定相似之处的&#xff0c;都运用了分而治之的思想提升了排序效率。快速排序的实现思路是每次排序把区间划分…

【Linux】进程间通信——命名管道和共享内存

目录 命名管道&#xff08;named pipe&#xff09; 命令行中使用 代码中使用 共享内存&#xff08;shared memory&#xff09; shmget ipcs命令 shmctl shmat/shmdt 简单通信 命名管道&#xff08;named pipe&#xff09; 之前我们说了匿名管道&#xff0c;但是匿名管道…

Spring-Spring、IoC、DI、注解开发

1、Spring是什么 Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。 Spring整体架构 Spring优点&#xff1a; Spring属于低侵入设计。IOC将对象之间的依赖关系交给Spring,降低组件之间的耦合&#xff0c;实现各个层之间的解耦&#xff0c;让我们更专注于业务…