剑指offer:序列化二叉树

题目描述
请实现两个函数,分别用来序列化和反序列化二叉树

# -*- coding: utf-8 -*-
# @Time         : 2019-07-07 15:48
# @Author       : Jayce Wong
# @ProjectName  : job
# @FileName     : serializeBinaryTree.py
# @Blog         : https://blog.51cto.com/jayce1111
# @Github       : https://github.com/SysuJayce

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

class Solution:
    """
    用先序遍历将二叉树序列化下来,然后再反序列化即可。因为这里的关键在于如何定位到根节点,虽然用后
    序遍历也可以定位根节点,但是在反序列化的时候就不容易实现。
    """
    def Serialize(self, root):
        """
        序列化的时候正常先序遍历二叉树即可,但是为了准确定位到叶子节点,我们需要
        **将空节点也序列化下来**
        """
        def helper(pRoot, curSerial):
            if not pRoot:
                # 这里我们用‘$‘表示空节点
                curSerial.append(‘$‘)
                return

            # 用递归方法进行序列化,先将根节点序列化,然后遍历左子树、右子树
            curSerial.append(pRoot.val)
            helper(pRoot.left, curSerial)
            helper(pRoot.right, curSerial)

        if not root:
            return ‘‘

        serialization = []
        helper(root, serialization)
        return ‘,‘.join(map(str, serialization))

    def Deserialize(self, s):
        """
        在反序列化的时候,由于构造一个节点的时候默认左右子节点都是空,因此如果字符串中遇到了‘$‘,
        可以直接忽略。也就是只需要处理非空节点
        """
        def helper(curStr, curRoot):
            # 递归出口
            if not curStr:
                return curRoot
            # 这里由于我们使用一个列表保存节点信息,因此可以用pop()来保存剩余待反序列化的节点
            curVal = curStr.pop(0)
            # 如果是‘$‘,即该节点为空,那么这时候由于输入的curRoot也为空,直接返回即可
            if curVal != ‘$‘:
                # 从整体来看,我们需要先构造根节点,然后分别构造其左右子节点。
                # 递归在确定了出口条件之后,就只需要将整体逻辑写出来就行了。
                curRoot = TreeNode(int(curVal))
                curRoot.left = helper(curStr, curRoot.left)
                curRoot.right = helper(curStr, curRoot.right)

            return curRoot

        if not s:
            return None
        s = s.split(‘,‘)
        root = helper(s, None)
        return root

def printTree(root: TreeNode):
    if not root:
        return
    print(root.val)
    printTree(root.left)
    printTree(root.right)

def main():

    solution = Solution()
    root = TreeNode(10)
    root.left = TreeNode(6)
    root.right = TreeNode(14)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(8)
    root.right.left = TreeNode(12)
    root.right.right = TreeNode(16)
    s = solution.Serialize(root)
    print(s)
    printTree(solution.Deserialize(s))

if __name__ == ‘__main__‘:
    main()

原文地址:https://blog.51cto.com/jayce1111/2417881

时间: 2024-08-27 04:01:16

剑指offer:序列化二叉树的相关文章

剑指Offer——序列化二叉树

题目描述: 请实现两个函数,分别用来序列化和反序列化二叉树 分析: 先序遍历可以用来序列化二叉树,序列化过程中,我们用"0xFFFFFFFF"表示结点为NULL. 反序列化便很简单,遇到"0xFFFFFFFF"就返回NULL,其他时候就直接产生一个结点. 代码: 1 /* 2 struct TreeNode { 3 int val; 4 struct TreeNode *left; 5 struct TreeNode *right; 6 TreeNode(int x

【剑指offer】二叉树的镜像

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25915971 题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点的个数(节点从1开始编号).接下来一行有n个数字,代表第i个二叉树节点的元素的值.接下来有n行,每行有一个字母Ci.Ci='d'表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号.C

剑指OFFER之二叉树的镜像(九度OJ1521)

题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点的个数(节点从1开始编号).接下来一行有n个数字,代表第i个二叉树节点的元素的值.接下来有n行,每行有一个字母Ci.Ci='d'表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号.Ci='l'表示第i个节点有一个左孩子,紧接着是左孩子的编号.Ci='r'表示第i个节点有一个右孩子,紧接着是右孩子的编号.C

剑指offer (19) 二叉树镜像 对称二叉树

题目: 输入一个二叉树,输出其镜像. BinTreeNode* ReverseTree(BinTreeNode* pRoot) { if (pRoot == NULL) return NULL; BinTreeNode* pLeftReverse = ReverseTree(pRoot->left); BinTreeNode* pRightReverse = ReverseTree(pRoot->right); pRoot->left = pRightReverse; pRoot->

剑指offer (39) 二叉树深度

题目:输入一棵二叉树的根节点,求该树的深度 题解分析: 二叉树具有天然的递归性,首先应该想递归解法 /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int maxDept

剑指Offer:二叉树打印成多行【23】

剑指Offer:二叉树打印成多行[23] 题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 题目分析 Java题解 package tree; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; public class PrintByLevel { public static void main(String[] args) { TreeNode t1 = n

剑指offer-37 序列化二叉树

剑指offer-37 序列化二叉树 题目: 思路: 自己解答: 这个有错误 public class Solution { String Serialize(TreeNode root) { if(root == null) return "#!"; StringBuilder bd = new StringBuilder(); serializeCore(root, bd); return bd.toString(); } private void serializeCore(Tre

[剑指offer] 重建二叉树,根据前中,输出后,根据中后,输出前

参考:<剑指offer>纪念版 情况1.:给出树的前序序列和中序序列,输出后序序列 情况2 :给出树的后序序列和中序序列,输出前序序列 解决方法:根据所给出的两个序列,构造出(重建)二叉树,然后按要求再遍历输出. 重建二叉树主要利用了递归的思想,最重要的是找出序列的范围(函数传参),这个要非常仔细,很容易出错.一定要在纸上画出图,然后根据图来确定范围. 用到的两个函数: 以情况1为例: 主要用到了两个函数: BinaryTreeNode* Construct(char* preorder, c

【Java】 剑指offer(7) 二叉树的下一个结点

本文参考自<剑指offer>一书,代码采用Java语言. 题目 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. 思路 首先自己在草稿纸上画图,进行分析(不再展开).可以发现下一个结点的规律为: 1.若当前结点有右子树时,其下一个结点为右子树中最左子结点: 2.若当前结点无右子树时, (1)若当前结点为其父结点的左子结点时,其下一个结点为其父结点: (2)若当前结点为其父结点的右子结点时,继续向上遍

【Java】 剑指offer(34) 二叉树中和为某一值的路径

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 思路 1.假设找到了其中一条路径,达到叶结点后,由于没有指向父结点的指针,所以必须提前创建一个链表存储前面经过的结点. 2.由于是从根结点出发,所以要想到使用前序遍历 3.利用链表存储结点,在该结点完成左右子树的路径搜索后(即递归函数结束,返回