二叉树的序列化与反序列化
来源:互联网 发布:决对争锋网络剧百度云 编辑:程序博客网 时间:2024/04/29 00:09
前序+中序 –> 二叉树
Construct Binary Tree from Preorder and Inorder Traversal
# Definition for a binary tree TreeNode.# class TreeNode(object):# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Solution(object): def buildTree(self, preorder, inorder): """ :type preorder: List[int] :type inorder: List[int] :rtype: TreeNode """ return self.getRoot(preorder, inorder) def getRoot(self, preorder, inorder): """假定前序和中序序列都是正确的""" if len(preorder)==0: return None # 这是一个临时节点, pre.next指向root pre = TreeNode(None) self.f(pre, preorder, inorder, 0, 0, len(preorder), True) return pre.left def f(self,parent,pre,ino,i,k,l,isleft): """ parent: 当前子树的父节点 pre: 整棵树的前序遍历序列 ino: 整棵树的中序遍历序列 i: 当前子树的前序序列在a中的起始位置 k: 当前子树的中序序列在b中的起始位置 l: 当前子树的节点数目 isleft: 标志当前子树是父节点的左子树还是右子树 """ current = TreeNode(pre[i]) if isleft==True: parent.left = current else: parent.right = current # 已到达叶子节点 if l==1: return # 当前子树的左子树的节点数目 num = ino.index(pre[i])-k # 当前子树的左子树非空 if num!=0: self.f(current,pre,ino,i+1,k,num,True) # 当前子树的右子树的节点数目不为0, 即非空 if l-num-1!=0: self.f(current,pre,ino,i+num+1,k+num+1,l-num-1,False)
注意到num = ino.index(pre[i])-k
可以进行优化,提前生成中序序列的元素和索引号的map,可提高查询速度,在getRoot中添加下面的代码:
inomap = {}for i in range(len(inorder)): inomap[inorder[i]] = i
将调用f时,用inomap替换ino,然后将num = ino.index(pre[i])-k
改为num = inomap[pre[i]]-k
。
现在只有4.42%的提交结果的执行时间比这个少。
中序+后序 –> 二叉树
Construct Binary Tree from Inorder and Postorder Traversal
和上面类似,稍稍改动即可:
# Definition for a binary tree node.# class TreeNode(object):# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Solution(object): def buildTree(self, inorder, postorder): """ :type inorder: List[int] :type postorder: List[int] :rtype: TreeNode """ return self.getRoot(postorder,inorder) def getRoot(self, postorder, inorder): if len(postorder)==0: return None pre = TreeNode(None) self.f(pre, postorder, inorder, 0, 0, len(postorder), True) return pre.left def f(self,parent,post,ino,i,k,l,isleft): current = TreeNode(post[i+l-1]) if isleft==True: parent.left = current else: parent.right = current if l==1: return num = ino.index(post[i+l-1])-k if num!=0: self.f(current,post,ino,i,k,num,True) if l-num-1!=0: self.f(current,post,ino,i+num,k+num+1,l-num-1,False)
二叉树的反序列化
leetcode上二叉树的序列化方法:
注意,结尾的若干个#直接省略掉。
我完成了反序列化的过程,不过没经过足够多的用例测试:
class node: def __init__(self, data=None): self.val = data self.left = None self.right = None'''二叉树的某行有n个元素(不包括-1), 下一行一定有2n个元素(包括-1)这个函数用来处理每一行的元素, 如果序列结尾有省略掉的-1, 会触发IndexError, 直接忽略即可'''def layer(q, begin, prelist): # q序列 # begin当前段的开始位置 # prelist上一段的节点列表 # curlist是当前段的节点列表 curlist = [] try: # 依次遍历prelist中每个节点 for i in range(len(prelist)): # i节点的左孩子节点 if q[begin+2*i]>0: t = node(q[begin+2*i]) prelist[i].left = t curlist.append(t) # i节点的右孩子节点 if q[begin+2*i+1]>0: t = node(q[begin+2*i+1]) prelist[i].right = t curlist.append(t) except IndexError: pass return curlist# 输入一个二叉树序列, 构建一个二叉树, 返回根节点def buildBinaryTree(q): if len(q)==0: return None root = node(q[0]) lists = [root] begin = 1 while len(lists)>0: next = begin+2*len(lists) lists = layer(q, begin, lists) begin = next return root
二叉树的序列化
与上节刚好相反,代码也有些类似。
class node: def __init__(self, data=None): self.val = data self.left = None self.right = None"""prelist上一层的节点列表curlist这一层的节点列表"""def once(result, prelist): curlist = [] for i in prelist: if i.left!=None: curlist.append(i.left) result.append(i.left.val) else: result.append(-1) if i.right!=None: curlist.append(i.right) result.append(i.right.val) else: result.append(-1) return curlist# 并没有删去结尾的若干-1def serialize(root): result = [root.val] lists = [root] while len(lists)>0: lists = once(result,lists) return result
前序遍历
Binary Tree Preorder Traversal
上面的序列化和反序列化实际上是BFS(Breadth-First-Search),下面是用栈实现二叉树的前序遍历,这是个DFS(Depth-First-Search):
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> preorderTraversal(TreeNode* root) { vector<int> result; if(!root) return result; stack<TreeNode*> valstk; valstk.push(root); while(!valstk.empty()) { TreeNode *p = valstk.top(); valstk.pop(); result.push_back(p->val); if(p->right) valstk.push(p->right); if(p->left) valstk.push(p->left); } return result; }};
非递归的后序遍历
Binary Tree Postorder Traversal
vector<int> postorderTraversal(TreeNode* root) { vector<int> result; if(!root) return result; stack<TreeNode*> valstk; valstk.push(root); TreeNode *pre = root; while(!valstk.empty()) { TreeNode *p = valstk.top(); if(p->left==NULL && p->right==NULL || p->left==pre || p->right==pre) { valstk.pop(); result.push_back(p->val); pre = p; } else { if(p->right) valstk.push(p->right); if(p->left) valstk.push(p->left); } } return result;}
参考
0 0
- 二叉树的序列化与反序列化
- 二叉树的序列化与反序列化
- 二叉树的序列化与反序列化
- 二叉树的序列化与反序列化
- 二叉树的序列化与反序列化
- 二叉树的序列化与反序列化
- 二叉树------序列化与反序列化二叉树
- 序列化/反序列化二叉树
- 序列化/反序列化二叉树
- 序列化/反序列化二叉树
- 序列化/反序列化二叉树
- 序列化反序列二叉树
- 题目:二叉树的序列化和反序列化
- 二叉树的序列化和反序列化
- 二叉树的序列化和反序列化
- 二叉树的序列化和反序列化
- 二叉树的序列化和反序列化
- 二叉树的序列化和反序列化
- 苹果证书
- IDEA的配置JDK,Tomcat,Maven
- 浏览器的各种长度宽度clientX clientY pageX pageY x y
- 多态与重载的区别
- 面试题 30
- 二叉树的序列化与反序列化
- H5学习之旅-H5的块标签的使用(9)
- Git使用详细教程
- nc工具
- 基础教程
- Unity3D研究院之利用缓存池解决Instantiate慢的问题
- Flex中添加大量组件时内存占用问题
- 适配iOS9遇到的一些问题_Scheme白名单_ Bitcode及解决办法
- 黑马程序员-Java基础学习第四天总结