力扣第102题 - 二叉树的层序遍历

news2024/12/15 3:33:16

力扣第102题: 二叉树的层序遍历


题目描述

给你一个二叉树,请你返回其按 层序遍历 的结果(即逐层从左到右访问所有节点)。

示例:

输入:

    3
   / \
  9  20
     /  \
    15   7

输出:

[
  [3],
  [9,20],
  [15,7]
]

解题思路

层序遍历的关键在于使用一个队列:

  1. 初始时,将根节点入队。
  2. 每次处理队列中的一个层次:
    • 获取当前队列长度 level_size(表示当前层节点数)。
    • 依次弹出队列中的 level_size 个节点,并将它们的值存入一个列表 level
    • 如果节点有左、右子节点,则将它们入队。
  3. 将当前层的列表 level 添加到结果列表 result 中。

实现代码(C语言)

结构体定义

为了实现层序遍历,使用一个队列结构。

#include <stdio.h>
#include <stdlib.h>

/**
 * Definition for a binary tree node.
 */
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};

// 队列节点
struct QueueNode {
    struct TreeNode *node;
    struct QueueNode *next;
};

// 队列操作
void enqueue(struct QueueNode **front, struct QueueNode **rear, struct TreeNode *node) {
    struct QueueNode *newNode = (struct QueueNode *)malloc(sizeof(struct QueueNode));
    newNode->node = node;
    newNode->next = NULL;
    if (*rear == NULL) {
        *front = *rear = newNode;
    } else {
        (*rear)->next = newNode;
        *rear = newNode;
    }
}

struct TreeNode *dequeue(struct QueueNode **front, struct QueueNode **rear) {
    if (*front == NULL) return NULL;
    struct QueueNode *temp = *front;
    struct TreeNode *node = temp->node;
    *front = (*front)->next;
    if (*front == NULL) *rear = NULL;
    free(temp);
    return node;
}

层序遍历实现
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
    if (root == NULL) {
        *returnSize = 0;
        *returnColumnSizes = NULL;
        return NULL;
    }

    // 初始化队列
    struct QueueNode *front = NULL, *rear = NULL;
    enqueue(&front, &rear, root);

    // 动态分配初始空间
    int capacity = 10; // 初始容量
    int** result = (int**)malloc(capacity * sizeof(int*));
    *returnColumnSizes = (int*)malloc(capacity * sizeof(int));
    *returnSize = 0;

    while (front != NULL) {
        int level_size = 0;
        struct QueueNode *temp = front;

        // 统计当前层节点数量
        while (temp != NULL) {
            level_size++;
            temp = temp->next;
        }

        // 如果超过当前容量,扩展空间
        if (*returnSize >= capacity) {
            capacity *= 2;
            result = (int**)realloc(result, capacity * sizeof(int*));
            *returnColumnSizes = (int*)realloc(*returnColumnSizes, capacity * sizeof(int));
            if (result == NULL || *returnColumnSizes == NULL) {
                fprintf(stderr, "内存分配失败\n");
                exit(EXIT_FAILURE);
            }
        }

        // 存储当前层的节点值
        result[*returnSize] = (int*)malloc(level_size * sizeof(int));
        if (result[*returnSize] == NULL) {
            fprintf(stderr, "内存分配失败\n");
            exit(EXIT_FAILURE);
        }
        (*returnColumnSizes)[*returnSize] = level_size;

        for (int i = 0; i < level_size; i++) {
            struct TreeNode *node = dequeue(&front, &rear);
            result[*returnSize][i] = node->val;
            if (node->left != NULL) enqueue(&front, &rear, node->left);
            if (node->right != NULL) enqueue(&front, &rear, node->right);
        }

        (*returnSize)++;
    }

    return result;
}


测试代码

#include <stdio.h>
#include <stdlib.h>

// 创建二叉树节点
struct TreeNode* createNode(int val) {
    struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    newNode->val = val;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

// 打印二维数组
void printResult(int** result, int returnSize, int* returnColumnSizes) {
    printf("[\n");
    for (int i = 0; i < returnSize; i++) {
        printf("  [");
        for (int j = 0; j < returnColumnSizes[i]; j++) {
            printf("%d", result[i][j]);
            if (j < returnColumnSizes[i] - 1) printf(", ");
        }
        printf("]");
        if (i < returnSize - 1) printf(",");
        printf("\n");
    }
    printf("]\n");
}

// 主函数
int main() {
    struct TreeNode* root = createNode(3);
    root->left = createNode(9);
    root->right = createNode(20);
    root->right->left = createNode(15);
    root->right->right = createNode(7);

    int returnSize;
    int* returnColumnSizes;
    int** result = levelOrder(root, &returnSize, &returnColumnSizes);

    printf("层序遍历结果:\n");
    printResult(result, returnSize, returnColumnSizes);

    // 释放内存
    for (int i = 0; i < returnSize; i++) {
        free(result[i]);
    }
    free(result);
    free(returnColumnSizes);

    return 0;
}

复杂度分析

  1. 时间复杂度

    • 每个节点访问一次,复杂度为 (O(n)),其中 (n) 是节点总数。
  2. 空间复杂度

    • 队列的大小取决于树的最大宽度,最坏情况是 (O(n))。

输出示例

输入:

    3
   / \
  9  20
     /  \
    15   7

输出:

层序遍历结果:
[
  [3],
  [9, 20],
  [15, 7]
]

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

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

相关文章

论文概览 |《IJAEOG》2024.08 Vol.132(下)

本次给大家整理的是《International Journal of Applied Earth Observation and Geoinformation》杂志2024年08月第132期的论文的题目和摘要&#xff0c;一共包括88篇SCI论文&#xff01;由于论文过多&#xff0c;我们将通过两篇文章进行介绍&#xff0c;本篇文章介绍第45--第8…

「数据结构详解·十五」树状数组

「数据结构详解一」树的初步「数据结构详解二」二叉树的初步「数据结构详解三」栈「数据结构详解四」队列「数据结构详解五」链表「数据结构详解六」哈希表「数据结构详解七」并查集的初步「数据结构详解八」带权并查集 & 扩展域并查集「数据结构详解九」图的初步「数据结构…

【sgFileLink】自定义组件:基于el-link、el-icon标签构建文件超链接组件,支持垃圾桶删除、点击预览视频/音频/图片/PDF格式文件

sgFileLink源代码 <template><div :class"$options.name"><el-link click.stop"clickFile(data)"><img :src"getSrc(data)" /><span>{{ getFileNameAndSize(data) }}</span></el-link><el-linkcl…

电机驱动模块L9110S详解

电机驱动模块是一种用于控制和驱动电机的设备&#xff0c;它能够将控制信号转化为适合电机操作的电流和电压。通过电机驱动模块&#xff0c;可以实现对电机的速度、方向等参数进行精确控制。 今天我们要介绍的 L9110S 电机驱动适合大学生、工程师、个人DIY、电子爱好者们学习和…

Unity 获取鼠标点击位置物体贴图颜色

实现 Ray ray Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) {textureCoord hit.textureCoord;textureCoord.x * textureMat.width;textureCoord.y * textureMat.height;textureColor textureMat.GetPixel(Mathf.Flo…

openlayers+vite+vue3实现在地图上画线(四)

在前几期实现离线地图初始化以及规划某一特定区域、打点、出现弹窗的基础上&#xff0c;本文主要阐述如何实现在所规划的区域地图上画线&#xff0c;如果你实现了打点的效果&#xff0c;其实这个相对来说还是算比较简单的&#xff0c;因为和打点的代码大差不差。使用openlayers…

游戏引擎学习第45天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们刚刚开始研究运动方程&#xff0c;展示了如何处理当人物遇到障碍物时的情况。有一种版本是角色会从障碍物上反弹&#xff0c;而另一版本是角色会完全停下来。这种方式感觉不太自然&#xff0c;因为在游戏中&#xff0c;…

类与对象以及ES6的继承

认识class定义类 类的声明用的比较多 类与构造函数的异同 类的构造函数 类的实例方法 类的访问器方法 在类里面写拦截方法 类的静态方法 通过类名直接访问 es6类的继承-extends super关键字 子类可以重写父类方法包括父类的静态方法也可以继承父类的静态方法 babel可以将新的代…

通过IKE协商方式建立IPSec隧道

我们前面学习了H3C的IPsec VPN配置&#xff08;为什么IPsec两端内网的网段能不能重复&#xff1f;分明可以实现&#xff01;&#xff09;&#xff0c;学习了Juniper的IPsec VPN配置&#xff0c;学习了Windows的IPsec VPN配置&#xff08;配置Juniper虚墙vSRX基于策略的IPsec VP…

文献分享: EMVB——PLAID后期交互引擎的进一步优化

&#x1f449;前情提要&#xff1a; 神经网络自然语言模型概述 Transformer \text{Transformer} Transformer与注意力机制概述 &#x1f4da;相关论文&#xff1a; BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding \text{BERT: Pre-train…

vue2+element-ui实现多行行内表格编辑

效果图展示 当在表格中点击编辑按钮时:点击的行变成文本框且数据回显可以点击确定按钮修改数据或者取消修改回退数据: 具体实现步骤 1. 行数据定义编辑标记 行数据定义编辑标记 当在组件中获取到用于表格展示数据的方法中,针对每一行数据添加一个编辑标记 this.list.f…

介绍几个Linux下的杀毒软件

一&#xff1a;chkrootkit 是一个用于检测Linux系统下可能被攻击者植入的后门程序或恶意代码的扫描工具。 &#xff08;1&#xff09;安装方法&#xff08;ubuntu) sudo apt update sudo apt install chkrootkit &#xff08;2&#xff09;使用方法&#xff1a; chkrootkit -…

JS 中请求队列与锁的巧妙结合

一、引言 在 JavaScript 开发中&#xff0c;尤其是在涉及到异步操作和对共享资源的并发访问时&#xff0c;有效地控制请求顺序和资源访问权限至关重要。例如&#xff0c;在多个网络请求同时针对一个有限制访问频率的 API 或者多个异步任务竞争同一个文件写入权限的场景下&#…

MYSQL索引的分类和创建

目录 1、聚簇索引和非聚簇索引 tips&#xff1a; 小问题&#xff1a;主键为什么建议使用自增id? 2、普通索引 &#xff08;常规索引&#xff09;(normal) 3、唯一索引&#xff08;UNIQUE &#xff09; 唯一索引和主键的区别&#xff1a; 唯一约束和唯一索引的区别&#…

Oracle最佳实践-优化硬解析

前段时间参加oracle CAB&#xff0c;oracle高级服务部门做了一个数据库最佳实践的报告&#xff0c;其中就有一项就是解决未使用绑定变量但执行次数很多的SQL&#xff1b; 对于一个数据库来说如果不知道该如何优化&#xff0c;那么最简单最有效的优化就是减少硬解析&#xff0c;…

AI Agent:重塑业务流程自动化的未来力量(2/30)

《AI Agent&#xff1a;重塑业务流程自动化的未来力量》 摘要&#xff1a;整体思路是先介绍 AI Agent 的基本情况&#xff0c;再深入阐述其实现业务流程自动化的方法和在不同领域的应用&#xff0c;接着分析其价值和面临的挑战&#xff0c;最后得出结论&#xff0c;为读者全面…

哈默纳科Harmonic谐波减速机机器人精准高效动力传递的核心力量

在当今科技飞速发展的时代&#xff0c;机器人技术正以惊人的速度改变着我们的生产与生活方式。而在机器人的精密机械结构中&#xff0c;哈默纳科 Harmonic 谐波减速机扮演着不可或缺的角色&#xff0c;成为机器人精准高效动力传递的关键所在。 1.高精度与灵活性&#xff1a;哈默…

【开源项目】经典开源项目数字孪生体育馆—开源工程及源码

飞渡科技数字孪生体育馆管理平台&#xff0c;融合物联网IOT、BIM数据模型、三维GIS等技术&#xff0c;实现体育馆的全方位监控和实时全局掌握&#xff0c;同时&#xff0c;通过集成设备设施管理、人员管理等子系统&#xff0c;减少信息孤岛&#xff0c;让场馆“可视、可控、可管…

长短期记忆神经网络(LSTM)介绍

1、应用现状 长短期记忆神经网络&#xff08;LSTM&#xff09;是一种特殊的循环神经网络(RNN)。原始的RNN在训练中&#xff0c;随着训练时间的加长以及网络层数的增多&#xff0c;很容易出现梯度爆炸或者梯度消失的问题&#xff0c;导致无法处理较长序列数据&#xff0c;从而无…

SQL server学习03-创建和管理数据表

目录 一&#xff0c;SQL server的数据类型 1&#xff0c;基本数据类型 2&#xff0c;自定义数据类型 二&#xff0c;使用T-SQL创建表 1&#xff0c;数据完整性的分类 2&#xff0c;约束的类型 3&#xff0c;创建表时创建约束 4&#xff0c;任务 5&#xff0c;由任务编写…