我的编程空间,编程开发者的网络收藏夹
学习永远不晚

go语言实现二叉树的序例化与反序列化

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

go语言实现二叉树的序例化与反序列化

二叉树的反序列化

反序列化

树的反序列化故名知意就是将一个序列化成字符串或者其它形式的数据重新的生成一颗二叉树,如下这颗二叉树将它序列化成字符串后的结果[5,4,null,null,3,2,1],而现在要做的是要将这个字符串重新的生成一颗二叉树(生成下面这颗树,因为这个字符串就是通过这颗树序列化来的)。

解题思路

  • 首先,应该先拿到一个序列化后数据,可能是队列、栈、字符串(中间会有字符将其分割),或其它形式的数据
  • 当一个节点下面没有数据的时候,我这里采用的是用null来表示的空,比如上面节点2下面没有数据,在字符串中就用了null来表示
  • 这里我将字符串转换成了队列的形式,当然使用字符串的形式也可以的,例如:通过split方法来分割成数组
  • 创建一个队列,把要进行处理的节点放和主到队列里面,比如,每次循环的时候将左右分支放到这个队列里面,因为队列有FIFO的特性,在处理完左支的时候能够放便的拿到右支的node
  • 接下来分析代码

TreeNode结构体

这个里面的数据很容易就看懂,val是当前节点的数据;left ,right分别保存的是左支和右支的数据

针对每个数据生成对应的TreeNode

func GenerateNode(str string) *TreeNode {
	if str == "null" {
		return nil
	}
	return &TreeNode{val: str}
}

这个方法主要是生成TreeNode对象的方法,上面说到当节点下面没有子节点的时候就会用null来表不,所以这里接收到的形参如果是null的话就会反回一个空指针,相反如果不是null就会反回一个创建的TreeNode对象,并将val属性赋值

反序列化方法

func DeserializationTb(dataQueue []string) (resultNode *TreeNode) {
	if len(dataQueue) == 0 {
		return nil
	}
	var tempNodeQueue []*TreeNode
	resultNode = generateNode(dataQueue[len(dataQueue) - 1])
	dataQueue = dataQueue[:len(dataQueue) - 1]
	if resultNode != nil {
		tempNodeQueue = append(tempNodeQueue,resultNode)
	}
	var tempNode *TreeNode
	for len(tempNodeQueue) != 0 {
		tempNode = tempNodeQueue[0]
		tempNodeQueue = tempNodeQueue[1:]
		if len(dataQueue) > 0 {
			tempNode.left = generateNode(dataQueue[len(dataQueue) - 1])
			dataQueue = dataQueue[:len(dataQueue) - 1]
			tempNode.right = generateNode(dataQueue[len(dataQueue) - 1])
			dataQueue = dataQueue[:len(dataQueue) - 1]
		}
		if tempNode.left != nil {
			tempNodeQueue = append(tempNodeQueue,tempNode.left)
		}
		if tempNode.right != nil {
			tempNodeQueue = append(tempNodeQueue,tempNode.right)
		}
	}
	return
}

代码解读

这个方法的代码比较多,这里就会块来说一下:

if len(dataQueue) == 0 {
		return nil
}

这几行代码无非就是一个边界条件的判断的问题,当传来的队列没有数据的时候就返回一个空,为啥是队列?因为我将字符串转成了队列

var tempNodeQueue []*TreeNode
resultNode = generateNode(dataQueue[len(dataQueue) - 1])
dataQueue = dataQueue[:len(dataQueue) - 1]
if resultNode != nil {
	tempNodeQueue = append(tempNodeQueue,resultNode)
}

var tempNodeQueue []*TreeNode:这里创建一个TreeNode指针数组的原因是存储要操作节点的数据,因为我将序列化后的数据转成了队列,所以在这个数组中最后一个元素应该是先出来的数组,同样第一个出来的数据是这颗二叉树的根节点,将这个节点保存到了这个队列里面,然后这个队列将在下面的for循环中使用到,其余的下面再说.

resultNode = generateNode(dataQueue[len(dataQueue) - 1]):这里便是将出队列,并通过generateNode生成一个TreeNode对象

dataQueue = dataQueue[:len(dataQueue) - 1]:因为有一个数组已经出了队列,就要将其去掉

tempNodeQueue = append(tempNodeQueue,resultNode):经过一个判空处理,便将这个节点保存到了上面提到的队列里面

for len(tempNodeQueue) != 0 {
    tempNode = tempNodeQueue[0]
    tempNodeQueue = tempNodeQueue[1:]
    if len(dataQueue) > 0 {
        tempNode.left = generateNode(dataQueue[len(dataQueue) - 1])
        dataQueue = dataQueue[:len(dataQueue) - 1]
        tempNode.right = generateNode(dataQueue[len(dataQueue) - 1])
        dataQueue = dataQueue[:len(dataQueue) - 1]
    }
    if tempNode.left != nil {
        tempNodeQueue = append(tempNodeQueue,tempNode.left)
    }
    if tempNode.right != nil {
        tempNodeQueue = append(tempNodeQueue,tempNode.right)
    }
}

当进入For循环后,也就证明现在这个队列里面有数据,不管三七二十一,先将里面的数据弹出,因为只有有了数据才可以进行下面的操作(无数据,不编程)

tempNodeQueue = tempNodeQueue[1:]:因为前一行代码将数据在这个队列里面弹出了, 所以一行代码是将已弹出的数据去除

tempNode.left = generateNode(dataQueue[len(dataQueue) - 1]):当传来序列化二叉树的存在数据的时候就将其节点的left , right分支进么赋值,下一行代码就是将弹出的数据去除,接下来的两行便是对right节点的处理,同left一样

tempNodeQueue = append(tempNodeQueue,tempNode.left):如果tempNode的左节点存在的时候就将其保存到队列中,遍历tempNodeQueue队列,再次执行上面的步骤.

可能有小伙伴存在疑问?

所返回的resultNode变量只赋值过一次,那子节点是如何赋值的呢?因为所有的TreeNode的节点我都是通过指针来处理的,

而在For里面的第一行代码所弹出的数据指向的地址正是resultNode的地址,所以在生成完树之后,我只要抓住这颗树的根节点就好了

二叉树的序列化

介绍

树的序列化又是怎么一回事呢?我可以将这颗树转换成一定格式的数据结构,比如:转换成一段文本可以持久化到硬盘中。

那有什么作用呢?比如Redis中的数据是在内存中的,它有一个功能是每隔一段 时间可以将数据保存到硬盘中以防止突发的断电导至数据的丢失

这里说的树的序列化你也可以这样的理解,我要将一颗二叉树里面的数据序列化保存到硬盘,以便下次使用这里面的数的据的时候可以直接生成这颗树

解题思路

  • 参于解这种题,想到的是通过对二叉树的按层来遍历来解决,当一个节点没有子节点的时候,将其视为空, 我这里用null来表示的
  • 在这个里面序列化时我是先处理的左子节点,然后在处理右子节点
  • 同反序列化一样,暂存数据的结构我使用的是队列的方式,还需要将获得的数据也要保存到一个队列里面
  • 在程序的开始如果所给的头节点不为空,就将头节点加入到队列
  • 在对队列遍历的时候弹出队列里面的数据(注:队列有FIFO的特性),将本节点的val放到保存数据的队列里面
  • 依次将本节点的左子节点和右子节点放到队列里面,在次执行上述步骤

代码


func SerializationTb(bt *TreeNode) (saveSerData []string) {
	root := bt
	var tempQueue []*TreeNode
	if root != nil {
		tempQueue = append(tempQueue, root)
	}
	var tempNode *TreeNode
	for len(tempQueue) != 0 {
		tempNode = tempQueue[0]
		if tempNode != nil {
			saveSerData = append(saveSerData, tempNode.val)
		} else {
			saveSerData = append(saveSerData, "null")
		}
		tempQueue = tempQueue[1:]
		if tempNode != nil {
			tempQueue = append(tempQueue, tempNode.left)
			tempQueue = append(tempQueue, tempNode.right)
		}
	}
	return
}

代码解读

这些代码还是很好看懂的,这里就说下for里面的代码吧~~

tempNode = tempQueue[0]:在队列里面弹出一个数据

saveSerData = append(saveSerData, tempNode.val):将tempNode的val属性保存到saveSerData队列里面

下面的if就是判断当这个节点为空或者是不为空的时候需要分别怎么处理数据,上面说到如果一个节点下面没有子节点,这里就用null来表示,所以当没有子节点的时候就用将null添加到队列里面

tempQueue = tempQueue[1:]:对队列重新赋值,将弹出的那个数据去掉

tempQueue = append(tempQueue, tempNode.left):将左节点加入到队列里面,下一行同理

运行结果

到此这篇关于go语言实现二叉树的序例化与反序列化的文章就介绍到这了,更多相关go序例化内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

go语言实现二叉树的序例化与反序列化

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

go语言怎么实现二叉树的序例化与反序列化

本篇内容主要讲解“go语言怎么实现二叉树的序例化与反序列化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go语言怎么实现二叉树的序例化与反序列化”吧!二叉树的反序列化反序列化树的反序列化故名知意
2023-06-30

Go语言中实现对象的序列化与反序列化方法

Golang中实现对象序列化和反序列化的方法,需要具体代码示例序列化和反序列化是将对象转化为可存储或传输的格式,以及将存储或传输的格式转化为对象的过程。在Golang中,可以通过一些内置的库和方法来实现对象的序列化和反序列化操作。一、使
Go语言中实现对象的序列化与反序列化方法
2024-01-29

Java的序列化与反序列化怎么实现

本篇内容介绍了“Java的序列化与反序列化怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java对象的序列化Java平台允许我们在内
2023-07-04

Go语言中Json序列化反序列化及文件读写的示例分析

这篇文章主要介绍Go语言中Json序列化反序列化及文件读写的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!概述JSON(JavaScript Object Notation,JavaScript对象表示法)是
2023-06-25

Java对象的XML序列化与反序列化实例解析

上一篇文章我们介绍了java实现的各种排序算法代码示例,本文我们看看Java对象的xml序列化与反序列化的相关内容,具体如下。XML是一种标准的数据交换规范,可以方便地用于在应用之间交换各类数据。如果能在Java对象和XML文档之间建立某种
2023-05-30

学习Go语言文档中的json.Unmarshal函数实现JSON反序列化

学习Go语言文档中的json.Unmarshal函数实现JSON反序列化在Go语言中,序列化和反序列化是非常常见的操作。反序列化是将JSON数据转换为Go语言中的结构体或其他数据类型的过程,而序列化则是将Go语言中的数据类型转换为JSON字
学习Go语言文档中的json.Unmarshal函数实现JSON反序列化
2023-11-04

C语言中如何实现二叉树的后序遍历

小编给大家分享一下C语言中如何实现二叉树的后序遍历,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!首先我们从两个方面讲解二叉树的后序遍历(递归+迭代)一.二叉树的后序遍历.(递归)思想:首先我们从二叉树的根节点开始先遍历其左
2023-06-29

在Java中,如何实现对象的序列化与反序列化?(请描述Java对象序列化和反序列化的过程及其用途。)

Java对象的序列化是一种将对象转换为二进制流的过程,用于存储或传输。反序列化则是将二进制流还原为对象的逆过程。序列化过程包括将对象状态和类型信息写入二进制流,而反序列化过程从二进制流中读取信息并重建对象。Java序列化和反序列化广泛用于持久化、网络传输、轻量级通信、配置管理和缓存。可序列化的对象必须实现java.io.Serializable接口,并可定义serialVersionUID字段以确保跨版本兼容性。
在Java中,如何实现对象的序列化与反序列化?(请描述Java对象序列化和反序列化的过程及其用途。)
2024-04-02

模板类与模板函数序列化和反序列化的实现方式?

模板类和模板函数的序列化和反序列化可以通过多种方式实现,包括使用二进制归档、自有序列化、函数指针和函数对象。使用二进制归档可将模板类直接写入/读取到文件,自有序列化则定义自定义序列化/反序列化方法。对于模板函数,可使用函数指针或函数对象对其
模板类与模板函数序列化和反序列化的实现方式?
2024-04-24

PHP数据结构:序列化与反序列化的艺术,实现数据持久化与传输

在 php 中,序列化将数据结构转换为字符串,而反序列化将字符串还原为数据结构,实现数据的持久化和传输。序列化函数 serialize 将数据结构转换为字符串,而 unserialize 函数从字符串中还原序列化后的数据。序列化可用于数据持
PHP数据结构:序列化与反序列化的艺术,实现数据持久化与传输
2024-05-14

队列技术在PHP与MySQL中的消息序列化和反序列化的实现方法

在Web开发中,队列技术被广泛应用于处理异步任务和消息传递,能够提高系统的性能和可扩展性。PHP作为一种流行的服务器端编程语言,与MySQL数据库结合使用,可以实现优秀的Web应用。本文将介绍队列技术在PHP与MySQL中的消息序列化和反序
2023-10-21

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录