[树结构]二叉树的重建和序列化

二叉树的重建

几乎所有的人都知道二叉树可以根据前序遍历+中序遍历或者后序遍历+中序遍历的方式重新建立原来的二叉树,并且结果是唯一的。下面就来看一下相关的方法。

前序+中序重建二叉树

给定一棵二叉树的前序和中序遍历序列,重新建立这棵二叉树。

注意:在前序中确定了根节点以后,要去中序里面查找这个根节点,这时的查找没必要从数组的0下面开始,从这个树的中序的第一个点开始。然后查找的个数为停止的下表减去中序开始的下表。

这里重建二叉树用的是递归的方法,要注意递归的出口。不然会死循环。

所以代码实现:

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
	int preStart = 0;
	int preLast = preorder.size() - 1;
	int inStart = 0;
	int inLast = inorder.size() - 1;

	return SubTreeBuild(preorder, preStart, preLast, inorder, inStart, inLast);
}

TreeNode* SubTreeBuild(vector<int>& preorder, int preStart, int preLast, vector<int>& inorder, int inStart, int inLast)
{
	if(preStart > preLast || inStart > inLast)
		return NULL;

	TreeNode *root = new TreeNode(preorder[preStart]);
	//search the root in the inorder
	int i = inStart;
	while(inorder[i] != preorder[preStart])
	{
		++i;
	}

	root->left = SubTreeBuild(preorder, preStart + 1, preStart + i - inStart, inorder, inStart, i - 1);
	root->right = SubTreeBuild(preorder, preStart + 1 + i - inStart, preLast, inorder, i + 1, inLast);

	return root;

}//SubTreeBuild

后序+中序重建二叉树

其实递归的方式并不是难点,重要的是定边界值。

TreeNode* SubTreeBuild(vector<int>& inorder, int ileft, int iright, vector<int>& postorder, int pleft, int pright)
{
	if(ileft > iright || pleft > pright)
		return NULL;

	TreeNode *root = new TreeNode(postorder[pright]);

	//search the root node in the inorder
	int i = ileft;
	while(inorder[i] != postorder[pright])
	{
		++i;
	}

	root->left = SubTreeBuild(inorder, ileft, i - 1, postorder, pleft, pleft + i - ileft - 1);
	root->right = SubTreeBuild(inorder, i + 1, iright, postorder, pleft + i - ileft, pright - 1);

	return root;
}

二叉树的序列化和反序列化

  

 

时间: 2024-11-05 17:14:35

[树结构]二叉树的重建和序列化的相关文章

hihoCoder - 1049 - 后序遍历 (二叉树的重建!!)

#1049 : 后序遍历 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在参与过了美食节之后,小Hi和小Ho在别的地方又玩耍了一阵子,在这个过程中,小Ho得到了一个非常有意思的玩具--一棵由小球和木棍连接起来的二叉树! 小Ho对这棵二叉树爱不释手,于是给它的每一个节点都标记了一个标号--一个属于A..Z的大写字母,并且没有任意两个节点的标号是一样的.小Hi也瞅准了这个机会,重新巩固了一下小Ho关于二叉树遍历的基础知识~就这样,日子安稳的过了两天. 这天,小Ho正好

[LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化

One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #. _9_ / 3 2 / \ / 4 1 # 6 / \ / \ / # # # # # # For exampl

二叉树的重建

class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } /**  * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.  * 假设输入的前序遍历和中序遍历的结果中都不含重复的数字.  * 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},  * 则重建二叉树并返回.  * @author user  *  *  *

6-3 二叉树的重建 uva536

已知先序和中序  求后序 可以有两种方式输出 一种是建好树按照树输出 一种是不建树  在遍历的过程中存入vector  再倒叙输出 #include<bits/stdc++.h> using namespace std; int ri[1000];int le[1000]; char xian[30],zhong[30];vector<char>ans; int built(int x1,int y1,int x2,int y2) { if(x2>y2||x1>y1)r

二叉树的序列化和反序列化

http://blog.csdn.net/qq_27703417/article/details/70958692 先序遍历二叉树,如果遇到空节点,就在str的末尾加上"#!","#"表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,"!"表示一个值的结束.如果遇到不为空的节点,假设节点值为3,就在str的末尾加上"3!".现在请你实现树的先序序列化. 先序遍历 import java.util.*; //使用递归

63.序列化二叉树

题目描述: ??实现两个函数.分别用来序列化和反序列化二叉树 思路分析: ??序列化指的就是,将二叉树转化为字符串序列,反序列化指的就是将字符串转化为二叉树.我们可以用先序遍历将二叉树转化为字符串,遇见节点为空记做 #!,不为空记做 num!.同样的我们可以用先序遍历的方法重建二叉树. 代码: import java.util.*; /* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = nul

【编程之美】java实现重建二叉树

package com.cn.binarytree.utils; /** * @author 刘利娟 [email protected] * @version 创建时间:2014年7月20日 下午2:03:30 类说明: */ class Node { Node left; Node right; char chValue; Node(char chValue) { left = null; right = null; this.chValue = chValue; } } public cla

九章算法面试题51 二叉树的序列化

九章算法官网-原文网址 http://www.jiuzhang.com/problem/51/ 题目 设计一个算法,序列化和反序列化一棵二叉树. 解释:序列化的意思是将内存中的一些特定的结构,变成有格式信息的字符串.如,对于链表而言,我们可以将1->2->3->NULL这样的链表序列化为"1,2,3".对于序列化算法,必须支持反序列化,及在约定的格式下,可以将满足格式要求的字符串重新构造为想要的结构.在本题中,你需要同时实现一个序列化函数和反序列化函数. 在线测试本题

利用层序遍历(不含None)和中序遍历重建二叉树 python

给定一颗二叉树的层序遍历(不含None的形式)和中序遍历序列,利用两个序列完成对二叉树的重建. 还是通过一个例子来说明整个过程,下图所示的二叉树,层序遍历结果为[a,b,c,d,e],中序遍历结果为[d,b,a,c,e],我们知道当我们找到根节点后,中序遍历能够提供给我们的信息就是左右子树分别包含哪些节点,而我们能否在层序遍历中找到根节点呢?很明显,层序遍历序列的第一个点是根节点,在中序遍历中找到左右子树分别包含哪些节点之后,我们就可以在层序遍历中区分出左右子树的层序遍历结果,然后就可以分别开始