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

序列化二叉树

  • 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),需要存储队列中的节点以及序列化后的字符串。

总结

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

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

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

相关文章

Go学习:类型转换需注意的点 以及 类型别名

目录 1. 类型转换 2. 类型别名 1. 类型转换 在从前的学习中&#xff0c;知道布尔bool类型变量只有两种值true或false&#xff0c;C/C、Python、JAVA等编程语言中&#xff0c;如果将布尔类型bool变量转换为整型int变量&#xff0c;通常采用 “0为假&#xff0c;非0为真”的方…

CF 766A.Mahmoud and Longest Uncommon Subsequence(Java实现)

题目分析 (小何同学语文不太好&#xff0c;看这个题弯弯绕绕&#xff0c;看不懂一点&#xff0c;哈哈哈。)在尝试示例中分析之后&#xff0c;题目的意思大概就是&#xff0c;两个字符串相同就输出-1&#xff0c;不同就输出最长的那个字符串长度 思路分析 数据输入存值之后&…

大数据相关职位介绍之一(数据分析,数据开发,数据产品经理,数据运营)

大数据相关职位介绍之一 随着大数据、人工智能&#xff08;AI&#xff09;和机器学习的快速发展&#xff0c;数据分析与管理已经成为各行各业的重要组成部分。从互联网公司到传统行业的数字转型&#xff0c;数据相关职位在中国日益成为推动企业创新和提升竞争力的关键力量。以…

【力扣系列题目】最后一块石头的重量 分割回文串 验证回文串 等差数列划分{最大堆 背包 动态规划}

文章目录 七、最后一块石头的重量最后一块石头的重量【堆】[最后一块石头的重量 II](https://leetcode.cn/problems/last-stone-weight-ii/)【背包】 八、分割回文串分割回文串【分割子串方案数量】[分割回文串 II](https://leetcode.cn/problems/omKAoA/)【最少分割次数】[分割…

go gin配置air

一、依赖下载 安装最新&#xff0c;且在你工作区下进行安装&#xff0c;我的是D:/GO是我的工作区&#xff0c;所有项目都在目录下的src&#xff0c; go install github.com/air-verse/airlatest 如果出现类似报错&#xff1a; 将图中第三行 github.com/air-verse/air 替换最…

读书笔记--分布式服务架构对比及优势

本篇是在上一篇的基础上&#xff0c;主要对共享服务平台建设所依赖的分布式服务架构进行学习&#xff0c;主要记录和思考如下&#xff0c;供大家学习参考。随着企业各业务数字化转型工作的推进&#xff0c;之前在传统的单一系统&#xff08;或单体应用&#xff09;模式中&#…

openRv1126 AI算法部署实战之——ONNX模型部署实战

在RV1126开发板上部署ONNX算法&#xff0c;实时目标检测RTSP传输。视频演示地址 rv1126 yolov5 实时目标检测 rtsp传输_哔哩哔哩_bilibili 一、准备工作 1.从官网下载YOLOv5-v7.0工程&#xff08;YOLOv5的第7个版本&#xff09; 手动在线下载&#xff1a; Releases ultraly…

【C++题解】1055. 求满足条件的整数个数

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1055. 求满足条件的整数个数 类型&#xff1a;简单循环 题目描述&#xff1a; 在 1∼n 中&#xff0c;找出能同时满足用 3 除余 2 &#xff0c;用 5 除余 3 &#xff0c;用 7 除余…

亚博microros小车-原生ubuntu支持系列:17 gmapping

前置依赖 先看下亚博官网的介绍 Gmapping简介 gmapping只适用于单帧二维激光点数小于1440的点&#xff0c;如果单帧激光点数大于1440&#xff0c;那么就会出【[mapping-4] process has died】 这样的问题。 Gmapping是基于滤波SLAM框架的常用开源SLAM算法。 Gmapping基于RBp…

R语言统计分析——ggplot2绘图4——刻面

参考资料&#xff1a;R语言实战【第2版】 如果组在途中并排出现而不是重叠为单一的图形&#xff0c;关系就是清晰的。我们可以使用facet_wrap()函数和facet_grid()函数创建网格图形&#xff08;在ggplot2中也称刻面图&#xff09;&#xff0c;相关语法如下&#xff1a; 语法结…

AI大模型开发原理篇-9:GPT模型的概念和基本结构

基本概念 生成式预训练模型 GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型 是由 OpenAI 开发的基于 Transformer 架构的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;专门用于文本生成任务。它的设计理念在于通过大规模的预训练来学习语言模…

使用Edu邮箱申请一年免费的.me域名

所需材料&#xff1a;公立Edu教育邮箱一枚&#xff08;P.S&#xff1a;该服务不支持所有的Edu教育邮箱&#xff0c;仅支持比较知名的院校&#xff09; 说到域名&#xff0c;.me这个后缀可谓是个性十足&#xff0c;适合个人网站、博客等。.me是黑山的国家顶级域名&#xff08;c…

【RocketMQ 存储】- RocketMQ存储类 MappedFile

文章目录 1. 前言2. ReferenceResource3. MappedFile3.1 核心参数3.2 构造器3.3 消息追加3.4 消息刷盘3.5 消息提交3.6 截取一段 ByteBuffer3.7 cleanup 释放堆外内存3.8 destroy 销毁 mappedFile3.9 warmMappedFile 4. 小结 本文章基于 RocketMQ 4.9.3 1. 前言 上一篇文章中我…

Autosar-Os是怎么运行的?(时间保护)

写在前面&#xff1a; 入行一段时间了&#xff0c;基于个人理解整理一些东西&#xff0c;如有错误&#xff0c;欢迎各位大佬评论区指正&#xff01;&#xff01;&#xff01; 1.功能概述 AUTOSAR OS 的四大可定制类型凸显了时间保护&#xff08;Timing Protection&#xff09;…

Linux环境基础开发工具的使用(apt, vim, gcc, g++, gbd, make/Makefile)

目录 什么是软件包 Linux 软件包管理器 apt 认识apt 查找软件包 安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件 Linux编辑器 - vim vim的基本概念 vim下各模式的切换 vim命令模式下各指令汇总 vim底行模式个指令汇总 Linux编译器 - gcc/g gcc/g的作…

计算机网络 (62)移动通信的展望

一、技术发展趋势 6G技术的崛起 内生智能&#xff1a;6G将强调自适应网络架构&#xff0c;通过AI驱动的智能算法提升通信能力。例如&#xff0c;基于生成式AI的6G内生智能架构将成为重要研究方向&#xff0c;实现低延迟、高效率的智能通信。信息编码与调制技术&#xff1a;新型…

【卫星通信】链路预算方法

本文介绍卫星通信中的链路预算方法&#xff0c;应该也适用于地面通信场景。 更多内容请关注gzh【通信Online】 文章目录 下行链路预算卫星侧参数信道参数用户侧参数 上行链路预算链路预算计算示例 下行链路预算 卫星侧参数 令卫星侧天线数为 M t M_t Mt​&#xff0c;每根天线…

详细解释java当中的所有知识点(前言及数据类型及变量)(第一部分)

会将java当中的所有的知识点以及相关的题目进行分享&#xff0c;这是其中的第一部分&#xff0c;用红色字体标注出重点&#xff0c;以及加粗的方式进行提醒 目录 一、Java语言概述 1.Java语言简介 2.语言优势 二、main方法 1.Java程序结构组成 2.运行Java程序 3.注释 4.…

MYSQL 商城系统设计 商品数据表的设计 商品 商品类别 商品选项卡 多表查询

介绍 在开发商品模块时&#xff0c;通常使用分表的方式进行查询以及关联。在通过表连接的方式进行查询。每个商品都有不同的分类&#xff0c;每个不同分类下面都有商品规格可以选择&#xff0c;每个商品分类对应商品规格都有自己的价格和库存。在实际的开发中应该给这些表进行…

【竞技宝】LOL:两大赛区胜率达到78.6!

北京时间1月29日&#xff0c;英雄联盟2025新赛季正在如火如荼的进行之中&#xff0c;目前由于新春佳节的到来&#xff0c;LCK和LPL赛区都进行了短暂的休赛期。在新春佳节之前的比赛中&#xff0c;由于新版本以及全局BP&#xff08;LPL&#xff09;的到来&#xff0c;很多英雄都…