二叉树的序列化(serialization)与反序列化(de-serialization)

news2025/1/20 5:46:59

目录

1. 概要

2. 用一维数组表示二叉树

3. python实现

3.1 二叉树节点的表示

3.2 串行化的python实现

3.3 反串行化的python实现

3.4 测试 


1. 概要

        本文简要介绍二叉树的序列化处理和反序列化处理及对应的python实现。

        二叉树通常为了方便而以一维数组(比如说python list)的格式进行存储,二叉树的序列化(serialization)就是指将二叉树转换成列表或者一维数组的形式。实际使用的时候再由列表的形式变换回二叉树的格式,这个就是反序列化(de-serialization)。

        序列化和反序列化是各种复杂的数据结构的实际存储和使用时都需要碰到的问题。

2. 用一维数组表示二叉树

        一个常见的误解是将二叉树进行层序遍历展开就得到了二叉树的一维数组表示。其实不是,单纯地对二叉树进行得到的列表无法还原成原始的二叉树。

        上图这个不完全的二叉树直接进行层序遍历得到的是[1,2,-3,-5,4],实际上它的一维数组表示为[1,2,-3,-5,null,4,null]。

        用一维数组表示二叉树的基本规则是(为了方便,记该数组为a,0-indexing,并且采用python slicing的方式表示子数组):

        (1) a[0]表示根节点

        (2) a[2**k-1 : 2**(k+1)-1]表示层k(1,2,...)的节点(假定根节点位于层0)

        (3) 每一层中的节点按从左到右排列

        (4) 不存在(作为完全二叉树应该有但是实际上不存在)的节点用None或者Null填充

        (5) 最后的连续的None可以去除 

 

3. python实现

3.1 二叉树节点的表示

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

        每个二叉树的节点最都有两个子节点,分别为左子节点和右子节点。以上类定义中,分别用left和right指向左子节点和右子节点。

3.2 串行化的python实现

         实现思路:to be added

def binTree2Lst(root):
    """ 
    binary tree serialization.
    Convert a binary tree with "root" as its root to a list.
    """
    if root == None:
        return []

    nodeLst = [root]
    valLst  = []
    
    while len(nodeLst) > 0:
        curNode = nodeLst.pop()
        if curNode != None:
            nodeLst.insert(0,curNode.left)
            nodeLst.insert(0,curNode.right)        
            valLst.append(curNode.val)
        else:
            valLst.append(None)

    # Throw away the trailing 'None'
    while valLst[-1] == None:
        valLst.pop()

    return valLst

3.3 反串行化的python实现

        实现思路:to be added

def lst2bintree(x:List[int]) -> Optional[TreeNode]:
    if len(x) == 0: # []
        root = None
    if x[0] == None: # [None]
        root = None

    x.reverse() # For the convenience of utilizing x.pop()
    nodeLoL = []        
    root = TreeNode(x.pop())
    nodeLoL.append([root])
    k = 0
    while(1):
        #print('k = {0}, {1}'.format(k, x))
        newLayer = []
        for node in nodeLoL[k]:
            #print(node.val)
            if node == None:
                pass
            else:
                if len(x) == 0:
                    break
                tmp = x.pop()
                if tmp != None:
                    newNode = TreeNode(tmp)
                    node.left = newNode
                    newLayer.append(newNode)

                if len(x) == 0:
                    break
                tmp = x.pop()
                if tmp != None:
                    newNode = TreeNode(tmp)
                    node.right = newNode
                    newLayer.append(newNode)

        if len(x) == 0:
            break
        nodeLoL.append(newLayer)
        k += 1
        
    return root

3.4 测试 

    x   = [3,9,20,None,None,15,7]
    root = lst2bintree(x)
    print(root.val)
    print(root.left.val)
    print(root.right.val)
    print(root.left.left)
    print(root.left.right)    
    print(root.right.left.val)
    print(root.right.right.val)  
    print(binTree2Lst(root))

    x = [1,2,-3,-5,None,4,None]
    root = lst2bintree(x)
    print(binTree2Lst(root))

        运行结果如下: 

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

[1, 2, -3, -5, None, 4]

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

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

相关文章

mysql 库的操作

文章目录 mysql 库的操作1. 创建数据库创建数据库案例 2. 字符集和校验规则查看系统默认的字符集合校验规则查看数据库支持的字符集查看数据库支持的字符集较验规则校验规则对数据库的影响 3. 操作数据库查看数据库显示创建语句修改数据库删除数据库查看数据库连接情况 mysql 库…

强化学习:值迭代和策略迭代

值迭代 通过上一章的学习,我们知道了贝尔曼最优方程的求解实际上分两部分,一是给定一个初始值 v k v_k vk​ 找到最优策略 π k 1 π_{k1} πk1​ ,二是更新 v k 1 v_{k1} vk1​   下面,我们将详细剖析这个算法&#xff0…

Java字节流battle字符流

目录 Java字节流(Byte Stream) FileInputStream和FileOutputStream Java字符流(Character Stream) FileReader和FileWriter 如何在使用是区分什么时候用输出什么时候用输入 Write方法 close方法 Java中的close方法本身抛出…

基本定时器工作模式

计数和定时 BasicTimer支持8位或16位向上计数模式。当计数值大于等于比较寄存器(CMPH、CMPL),会产生计数中断标志,并从自动重载寄存器(LOADH、LOADL)加载新的比较值。这样可以实时调整每个计数周期的计数长…

python自动化测试-最常用的自动化测试框架

在开始学习python自动化测试之前,先了解目前市场上的自动化测试框架有哪些? 随着技术的不断迭代更新,优胜劣汰也同样发展下来。从一开始工具型自动化,到现在的框架型;从一开始的能用,到现在的不仅能用&…

Qt6.5 grpc组件使用 + golang grpc server示例

1. 资料 1) Protobuf 开发文档 https://protobuf.dev/ 2) protobuf安装指南 https://grpc.io/docs/protoc-installation/ 3) protoc 下载 https://github.com/protocolbuffers/protobuf/releases/tag/v23.1 2. Qt grpc 组件 & 工具 1) Qt6.5 安装目录下 xx\Qt\6.5.…

实验7 多用户界面、菜单以及对话框程序设计

实验内容 1.设计一个具有两个页面的程序,第一个页面显示一张封面的图片,第二个页面显示“欢迎进入本系统”,这两个页面之间能相互切换。    2.设计一个具有3个选项的菜单程序,当单击每个选项时,分别跳转到3个不同的页面。 3.设…

快速搭建一个 Kubernetes+Crane 环境,以及如何基于 Crane 优化你的集群和应用初体验

文章目录 一、活动介绍二、环境搭建三、安装本地的 Kind 集群和 Crane 组件四、界面截图五、主要功能六、整体架构七、Crane的优势八、总结参考文献 一、活动介绍 Crane 是由腾讯云主导开源的国内第一个基于云原生技术的成本优化项目,遵循 FinOps 标准,…

零基础如何入门网络安全?一般人还真不行

前景 很多零基础朋友开始将网络安全作为发展的大方向,的确,现如今网络安全已经成为了一个新的就业风口,不仅大学里开设相关学科,连市场上也开始大量招人。 那么网络安全到底前景如何?大致从市场规模、政策扶持、就业…

信息收集-目录信息

(一)目录结构 网页的目录结构跟整个网站的布局有关,收集到的信息可以包括目录名称、目录结构、目录所包含的文件、文件类型、文件大小等。收集到的信息有助于评估网站的安全性、了解网站的架构和目录结构,甚至可能有助于发现敏感…

3个月出国|材料科学老师自费赴韩国访学

K老师指定韩国为访学的目标国家,希望专业匹配,尽快出国。最终我们获得了韩国庆北大学的邀请函,其学校名气、专业匹配度及导师影响力都符合K老师的要求。本案例从开始委托我们申请到最终出国,仅仅用时3个月。 K老师背景&#xff1a…

基于pytest的接口测试框架详解,一定有你想知道的

目录 需求一:一套用例可以测试多套环境 需求二: 可以被jenkins调度执行 需求三 拥有测试报告 需求四:接口中某些字段值在每次请求中不重复 需求五: 可以多接口关联测试 需求六 构造的表数据可以和接口字段数据关联 需求七 pytest用例和…

java内部类和异常类1

文章目录 一、Java内部类二、Java匿名类总结 一、Java内部类 成员变量和方法,实际上,类还有一种成员:内部类。在一个类中定义另一个类,我们把这样的类称作内部类,包含内部类的类称作内部类的外嵌类。 内部类和外嵌类…

编辑距离00

题目链接 爬楼梯 题目描述 注意点 word1 和 word2 由小写英文字母组成返回将 word1 转换成 word2 所使用的最少操作数 解答思路 本题本质上的操作只有三种:在单词 A 中插入一个字符;在单词 B 中插入一个字符;修改单词 A 的一个字符&…

OpenGL之元素缓冲对象

文章目录 EBO(元素缓冲对象)创建元素缓冲对象创建两个相邻不同颜色的三角形 EBO(元素缓冲对象) 素缓冲对象(Element Buffer Object,EBO),也叫索引缓冲对象(Index Buffer Object,IBO)。要解释元素缓冲对象的工作方式最好还是举个例子&#xf…

【Python redis】零基础也能轻松掌握的学习路线与参考资料

Python redis是一种非常流行的缓存数据库,对于Python Web应用程序开发非常有用,能快速地处理大量的数据请求。Python redis的学习路线需要对Python语言有深刻的理解,并了解使用redis的API。在掌握了Python redis的基本知识后,就可…

这个 希尔排序详解过程 我能吹一辈子!!!

文章目录 希尔排序概念希尔排序算法思路希尔排序实现 希尔排序概念 希尔排序(Shellsort)也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。希尔(Donald Shell)于1959…

关系数据库设计理论

关系数据库设计理论 目录 关系数据库设计理论是什么函数依赖完全函数依赖(Full Functional Dependency)部分函数依赖(Partial Functional Dependency)传递函数依赖(Transitive Functional Dependency) 异常插入异常(Insertion Anomaly)更新异常(Update Anomaly)删除异常(Deleti…

Mit6.006-problemSession04

4-1 序列旋转 下面是一个序列AVL树T。执行操作T.delete_at(8),该操作期间,每次旋转操作执行完后,画出该树。 4-2 Fick Nury Fick Nury领导n名超级英雄组成了精英团队——复仇者联盟。他听说:超人Sanos正在一个遥远星球上制造麻烦…

【JVM】7. 方法区

文章目录 7. 方法区7.1. 栈、堆、方法区的交互关系7.2. 方法区的理解7.2.1. 方法区在哪里?7.2.2. 方法区的基本理解7.2.3. HotSpot中方法区的演进 7.3. 设置方法区大小与OOM7.3.1. 设置方法区内存的大小7.3.2. 如何解决这些OOM 7.4. 方法区的内部结构7.4.1. 方法区&…