当前位置: 首页 > news >正文

每日一题——序列化二叉树

序列化二叉树

  • BM39 序列化二叉树
    • 题目描述
      • 序列化
      • 反序列化
    • 示例
      • 示例1
      • 示例2
    • 解题思路
      • 序列化过程
      • 反序列化过程
    • 代码实现
    • 代码说明
    • 复杂度分析
    • 总结

BM39 序列化二叉树

题目描述

请实现两个函数,分别用来序列化和反序列化二叉树。二叉树的序列化是将二叉树按照某种遍历方式转换为字符串格式,而反序列化则是根据字符串重建出原二叉树。

序列化

二叉树的序列化(Serialize)是指将二叉树转换为字符串,通常我们使用层序遍历的方式将树的节点值逐个保存。在序列化的过程中,用某种符号表示空节点(如#),例如:层序序列化的结果为"{1,2,3,#,#,6,7}"

反序列化

二叉树的反序列化(Deserialize)是指根据序列化后的字符串重建出二叉树。例如,给定序列化字符串"{1,2,3,#,#,6,7}",我们可以重新构造出与原二叉树相同的树结构。

示例

在这里插入图片描述

示例1

输入:

{1,2,3,#,#,6,7}

返回值:

{1,2,3,#,#,6,7}

示例2

在这里插入图片描述

输入:

{8,6,10,5,7,9,11}

返回值:

{8,6,10,5,7,9,11}

解题思路

序列化过程

  1. 使用层序遍历的方式遍历二叉树。
  2. 将每个节点的值转化为字符串,并用#表示空节点。
  3. 将结果以逗号连接形成最终的字符串。

反序列化过程

  1. 将序列化后的字符串按逗号分割。
  2. 按照层序的顺序,逐个构建二叉树的节点。
  3. 使用队列来辅助构建树的结构,按照层序遍历的方式将节点插入到对应的位置。

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义二叉树节点
struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;
};// 定义队列节点
typedef struct QueueNode {struct TreeNode* treeNode;struct QueueNode* next;
} QueueNode;// 定义队列
typedef struct {QueueNode* front;QueueNode* rear;
} Queue;// 创建队列
Queue* createQueue() {Queue* q = (Queue*)malloc(sizeof(Queue));q->front = q->rear = NULL;return q;
}// 判断队列是否为空
int isEmpty(Queue* q) {return q->front == NULL;
}// 入队
void enqueue(Queue* q, struct TreeNode* node) {QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));newNode->treeNode = node;newNode->next = NULL;if (q->rear != NULL) {q->rear->next = newNode;}q->rear = newNode;if (q->front == NULL) {q->front = newNode;}
}// 出队
struct TreeNode* dequeue(Queue* q) {if (isEmpty(q)) {return NULL;}QueueNode* temp = q->front;struct TreeNode* node = temp->treeNode;q->front = q->front->next;if (q->front == NULL) {q->rear = NULL;}free(temp);return node;
}// 释放队列
void freeQueue(Queue* q) {while (!isEmpty(q)) {dequeue(q);}free(q);
}// 序列化二叉树
char* Serialize(struct TreeNode* root) {if (root == NULL) {return "#";}Queue* q = createQueue();enqueue(q, root);char* result = (char*)malloc(10000 * sizeof(char)); // 假设字符串长度足够char* buffer = (char*)malloc(100 * sizeof(char));int len = 0;while (!isEmpty(q)) {struct TreeNode* node = dequeue(q);if (node == NULL) {len += sprintf(result + len, "#,");} else {len += sprintf(result + len, "%d,", node->val);enqueue(q, node->left);enqueue(q, node->right);}}// 去掉最后一个逗号if (len > 0 && result[len - 1] == ',') {result[len - 1] = '\0';} else {result[len] = '\0';}free(buffer);freeQueue(q);return result;
}// 反序列化二叉树
struct TreeNode* Deserialize(char* data) {if (strcmp(data, "#") == 0) {return NULL;}char* token = strtok(data, ",");struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->val = atoi(token);root->left = root->right = NULL;Queue* q = createQueue();enqueue(q, root);while ((token = strtok(NULL, ",")) != NULL) {struct TreeNode* parent = dequeue(q);if (strcmp(token, "#") != 0) {struct TreeNode* leftNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));leftNode->val = atoi(token);leftNode->left = leftNode->right = NULL;parent->left = leftNode;enqueue(q, leftNode);}token = strtok(NULL, ",");if (token == NULL) {break;}if (strcmp(token, "#") != 0) {struct TreeNode* rightNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));rightNode->val = atoi(token);rightNode->left = rightNode->right = NULL;parent->right = rightNode;enqueue(q, rightNode);}}freeQueue(q);return root;
}

代码说明

  1. 队列实现:为了方便按层次遍历二叉树,我们使用队列来存储树的节点。
  2. 序列化函数 Serialize:使用层序遍历对树进行遍历,将节点值加入到结果字符串中。如果节点为空,则用#表示。
  3. 反序列化函数 Deserialize:将序列化后的字符串按逗号分割,依次创建节点并建立左右子树。

复杂度分析

  • 时间复杂度:O(n),其中n是树的节点数。每个节点在序列化和反序列化过程中只被访问一次。
  • 空间复杂度:O(n),需要存储队列中的节点以及序列化后的字符串。

总结

本题考察了二叉树的序列化与反序列化,使用层序遍历来实现序列化和反序列化的方法,保证了在时间和空间复杂度上都能满足要求。这题的整体难度还是不小的,但是最主要的是队列的实现,这个完成,任务就完成一半。至于后面函数的实现,就是研究递归了。

相关文章:

每日一题——序列化二叉树

序列化二叉树 BM39 序列化二叉树题目描述序列化反序列化 示例示例1示例2 解题思路序列化过程反序列化过程 代码实现代码说明复杂度分析总结 BM39 序列化二叉树 题目描述 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。二叉树的序列化是将二叉树按照某种遍历方式…...

Transformer+vit原理分析

目录 一、Transformer的核心思想 1. 自注意力机制&#xff08;Self-Attention&#xff09; 2. 多头注意力&#xff08;Multi-Head Attention&#xff09; 二、Transformer的架构 1. 整体结构 2. 编码器层&#xff08;Encoder Layer&#xff09; 3. 解码器层&#xff08;Decoder…...

「AI学习笔记」深度学习的起源与发展:从神经网络到大数据(二)

深度学习&#xff08;DL&#xff09;是现代人工智能&#xff08;AI&#xff09;的核心之一&#xff0c;但它并不是一夜之间出现的技术。从最初的理论提出到如今的广泛应用&#xff0c;深度学习经历了几乎一个世纪的不断探索与发展。今天&#xff0c;我们一起回顾深度学习的历史…...

【漫话机器学习系列】069.哈达马乘积(Hadamard Product)

哈达马乘积&#xff08;Hadamard Product&#xff09; 哈达马乘积&#xff08;Hadamard Product&#xff09;是两个矩阵之间的一种元素级操作&#xff0c;也称为逐元素乘积&#xff08;Element-wise Product&#xff09;。它以矩阵的对应元素相乘为规则&#xff0c;生成一个新…...

2025一区新风口:小波变换+KAN!速占!

今天给大家分享一个能让审稿人眼前一亮&#xff0c;好发一区的idea&#xff1a;小波变换KAN&#xff01; 一方面&#xff1a;KAN刚中稿ICLR25&#xff0c;正是风口上&#xff0c;与小波变换的结合还处于起步阶段&#xff0c;正是红利期&#xff0c;创新空间广阔。 另一方面&a…...

相同的树及延伸题型(C语言详解版)

从LeetCode 100和101看二叉树的比较与对称性判断 今天要讲的是leetcode100.相同的树&#xff0c;并且本文章还会讲到延伸题型leetcode101.对称二叉树。本文章编写用的是C语言&#xff0c;大家主要是学习思路&#xff0c;学习过后可以自己点击链接测试&#xff0c;并且做一些对…...

【Redis】 String 类型的介绍和常用命令

1. 介绍 Redis 中的 key 都是字符串类型Redis 中存储字符串是完全按照二进制流的形式保存的&#xff0c;所以 Redis 是不处理字符集编码的问题&#xff0c;客户端传入的命令中使用的是什么编码就采用什么编码&#xff0c;使得 Redis 能够处理各种类型的数据&#xff0c;包括文…...

LLM - 大模型 ScallingLaws 的设计 100B 预训练方案(PLM) 教程(5)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/145356022 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 Scaling Laws (缩放法则) 是大模型领域中,用于描述 模型性能(Loss) 与…...

Docker/K8S

文章目录 项目地址一、Docker1.1 创建一个Node服务image1.2 volume1.3 网络1.4 docker compose 二、K8S2.1 集群组成2.2 Pod1. 如何使用Pod(1) 运行一个pod(2) 运行多个pod 2.3 pod的生命周期2.4 pod中的容器1. 容器的生命周期2. 生命周期的回调3. 容器重启策略4. 自定义容器启…...

32、【OS】【Nuttx】OSTest分析(1):stdio测试(二)

背景 接上篇wiki 31、【OS】【Nuttx】OSTest分析&#xff08;1&#xff09;&#xff1a;stdio测试&#xff08;一&#xff09; 继续stdio测试的分析&#xff0c;上篇讲到标准IO端口初始化&#xff0c;单从测试内容来说其实很简单&#xff0c;没啥可分析的&#xff0c;但这几篇…...

git push到远程仓库时无法推送大文件

一、错误 remote: Error: Deny by project hooks setting ‘default’: size of the file ‘scientific_calculator’, is 164 MiB, which has exceeded the limited size (100 MiB) in commit ‘4c91b7e3a04b8034892414d649860bf12416b614’. 二、原因 本地提交过大文件&am…...

Vue.js路由管理与自定义指令深度剖析

Vue.js 是一个强大的前端框架,提供了丰富的功能来帮助开发者构建复杂的单页应用(SPA)。本文将详细介绍 Vue.js 中的自定义指令和路由管理及导航守卫。通过这些功能,你可以更好地控制视图行为和应用导航,从而提升用户体验和开发效率。 1 自定义指令详解 1.1 什么是自定义…...

NVIDIA GPU介绍:概念、序列、核心、A100、H100

概述 入职一家大模型领域创业公司&#xff0c;恶补相关知识。 概念 一些概念&#xff1a; HPC&#xff1a;High Performance Computing&#xff0c;高性能计算SoC&#xff1a;System on Chip&#xff0c;单片系统FLOPS&#xff1a;Floating Point Operations Per Second&am…...

【PyTorch】6.张量运算函数:一键开启!PyTorch 张量函数的宝藏工厂

目录 1. 常见运算函数 个人主页&#xff1a;Icomi 专栏地址&#xff1a;PyTorch入门 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术&…...

C语言练习(31)

有5个学生&#xff0c;每个学生有3门课程的成绩&#xff0c;从键盘输入以上数据&#xff08;包括学号、姓名、3门课程成绩&#xff09;&#xff0c;计算出平均成绩&#xff0c;将原有数据和计算出的平均分数存放在磁盘文件stud中。 设5名学生的学号、姓名和3门课程成绩如下&am…...

什么是长短期记忆网络?

一、概念 长短期记忆网络&#xff08;Long Short-Term Memory, LSTM&#xff09;是一种特殊的循环神经网络&#xff08;RNN&#xff09;&#xff0c;旨在解决标准RNN在处理长序列时的梯度消失和梯度爆炸问题。LSTM通过引入三个门&#xff08;输入门、遗忘门和输出门&#xff09…...

git中有关old mode 100644、new mode 10075的问题解决小结

在 Git 版本控制系统中&#xff0c;文件权限变更是一种常见情况。当你看到类似 old mode 100644 和 new mode 100755 的信息时&#xff0c;这通常表示文件的权限发生了变化。本文将详细解析这种情况&#xff0c;并提供解决方法和注意事项。 问题背景 在 Git 中&#xff0c;文…...

Jenkins上生成的allure report打不开怎么处理

目录 问题背景&#xff1a; 原因&#xff1a; 解决方案&#xff1a; Jenkins上修改配置 通过Groovy脚本在Script Console中设置和修改系统属性 步骤 验证是否清空成功 进一步的定制 也可以使用Nginx去解决 使用逆向代理服务器Nginx&#xff1a; 通过合理调整CSP配置&a…...

JSR303校验教学

1、什么是JSR303校验 JSR是Java Specification Requests的缩写&#xff0c;意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR&#xff0c;以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。…...

使用DeepSeek技巧:提升内容创作效率与质量

一、引言 在当今快节奏的数字时代&#xff0c;内容创作的需求不断增加&#xff0c;无论是企业营销、个人博客还是学术研究&#xff0c;高效且高质量的内容生成变得至关重要。DeepSeek作为一款先进的人工智能写作助手&#xff0c;凭借其强大的语言生成能力&#xff0c;为创作者…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...