L16.【LeetCode笔记】前序遍历

目录

1.知识回顾

2.题目

代码模板

3.分析

数组的初始化

malloc开辟的几种方案对比

奇怪的参数returnSize

做法

代码框架

4.代码

提交结果

5.PreOrder函数常见的错误写法


1.知识回顾

106.【C语言】数据结构之二叉树的三种递归遍历方式

2.题目

https://leetcode.cn/problems/binary-tree-preorder-traversal/

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

示例 1:

**输入:**root = 1,null,2,3

输出:1,2,3

解释:

示例 2:

**输入:**root = 1,2,3,4,5,null,8,null,null,6,7,9

输出:1,2,4,5,6,7,3,8,9

解释:

示例 3:

**输入:**root = \[\]

输出:\[\]

示例 4:

**输入:**root = 1

输出:1

提示:

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

**进阶:**递归算法很简单,你可以通过迭代算法完成吗?

代码模板

cpp 复制代码
/**
 * 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().
 */
int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{
    
}

3.分析

106.【C语言】数据结构之二叉树的三种递归遍历方式文章有所不同,LeetCode函数的返回值为int*,即返回一个不带NULL的int数组

数组的初始化

注意不可以返回局部数组!就像下面这样

cpp 复制代码
//......
int a[100];
return a;
//......

一旦离开preorderTraversal函数会被销毁,导致出现野指针,因此必须malloc在堆区开辟

而且LeetCode给出了提示

cpp 复制代码
Note: The returned array must be malloced, assume caller calls free().

这里不用担心free的问题,假设调用者调用了free()

malloc开辟的几种方案对比

方案1.LeetCode给出了提示"树中节点数目在范围 0, 100 内",因此可以一次性开辟足够的空间

cpp 复制代码
int* a = (int*)malloc(100*sizeof(int));

但可能会出现空间浪费的情况

方案2.先计算二叉树的大小(节点个数*每个节点所占的内存空间),再malloc

方案3.一开始开辟较小的空间,不够了再扩容

本文采用方案2,直接调用107.【C语言】数据结构之二叉树求总节点和第K层节点的个数文章的TreeSize函数

奇怪的参数returnSize

在int* preorderTraversal(struct TreeNode* root, int* returnSize)传了一个int*类型的参数returnSize,

LeetCode规定返回数组时要不仅仅要求返回首元素的地址还要返回数组的大小returnSize

由于形参的改变不影响实参,因此需要传returnSize的地址,因此为int*类型的参数

做法

return a;之前先将数组的大小传给*returnSize

代码框架

cpp 复制代码
int TreeSize(struct TreeNode* root)
{
    return root==NULL ? 0 : TreeSize(root->left)+TreeSize(root->right)+1;
}

int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{
    *returnSize=TreeSize(root);
    int* a=(int*)malloc(*returnSize*sizeof(int));
    //......
    //遍历并写入数组
    //......
    return a;
}

4.代码

106.【C语言】数据结构之二叉树的三种递归遍历方式文章的PreOrder函数的代码

cpp 复制代码
void PreOrder(BTNode* root)
{
	//先判断是否为空树(叶节点的左节点和右节点均为空树)
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
 
	//按根-->左子树-->右子树的顺序遍历
	printf("%d ",root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

稍加改造上方PreOrder函数即可

cpp 复制代码
void PreOrder(struct TreeNode* root,int* a,int* i)
{
    if (root==NULL)
        return;
    //写入数组
    a[(*i)++]=root->val;
    PreOrder(root->left,a,i);
    PreOrder(root->right,a,i);
}

int TreeSize(struct TreeNode* root)
{
    return root==NULL ? 0 : TreeSize(root->left)+TreeSize(root->right)+1;
}

int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{
    *returnSize=TreeSize(root);
    int* a=(int*)malloc(*returnSize*sizeof(int));
    int i=0;
    PreOrder(root,a,&i);
    return a;
}

提交结果

如果将代码的*returnSize=TreeSize(root);注释掉会报错

5.PreOrder函数常见的错误写法

cpp 复制代码
void PreOrder(struct TreeNode* root,int* a,int i)
{
    if (root==NULL)
        return;
    //写入数组
    a[i++]=root->val;
    PreOrder(root->left,a,i);
    PreOrder(root->right,a,i);
}

//省略TreeSize
int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{
    //前面内容省略
    PreOrder(root,a,0);
    //后面内容省略
}

运行结果:不完全通过

以下面这个用例分析

画递归展开图

由于CSDN会压缩图片画质,无损bmp图片(大小7.32M)链接见https://pan.baidu.com/s/1OIrE-cGvefJs_SFZ75w84w?pwd=gq37

解决方法:1.传址调用 2.使用全局变量

备注:不建议使用全局变量,LeetCode有多个测试用例会反复调用函数,导致全局变量无法清零

相关推荐
Doubbbbbbble云9 分钟前
区间合并问题的常见算法模式与优化思路4
java·数据结构·算法
David猪大卫13 分钟前
【C++修炼】哈希表的实现
数据结构·c++·笔记·学习·算法·哈希算法·散列表
江湖人称菠萝包26 分钟前
【Windows】《深入浅出Windows API程序设计:核心编程篇》笔记-Chapter6-动态链接库
windows·笔记
宵时待雨1 小时前
linux笔记归纳18:传输层协议TCP
linux·网络·笔记·网络协议·tcp/ip
逆境不可逃1 小时前
Pi Agent 学习笔记:一次提问背后的工具调用循环
java·笔记·学习
hahaha60161 小时前
HLS高层次综合设计技巧--数组
开发语言·嵌入式硬件·算法·fpga开发
不会就选b1 小时前
算法日常・每日刷题--<贪心>10
算法
南京兴帝文化传媒有限公司1 小时前
本地生活服务商户GEO优化技术实践:AI大模型收录机制与地图POI权重算法拆解
大数据·人工智能·算法·生活·geo优化实操·csdn运营技巧·ai内容收录
Ztt6666666662 小时前
紫釉高筒壶向上收紧,修长器身更显精神
经验分享·笔记·其他·百度·微信公众平台
疯狂打码的少年2 小时前
【计算机网络】UDP协议与TCP/UDP对比(面向连接vs无连接)
笔记·tcp/ip·计算机网络·udp