标签:blog ret 表示 tree java index imp core class
http://blog.csdn.net/qq_27703417/article/details/70958692
先序遍历二叉树,如果遇到空节点,就在str的末尾加上“#!”,“#”表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,“!”表示一个值的结束。如果遇到不为空的节点,假设节点值为3,就在str的末尾加上“3!”。现在请你实现树的先序序列化。
先序遍历
反序列化
所谓反序列化是根据一个字符串重新建立一棵二叉树,反序列化是序列化的逆过程,对于一个字符串,首先按照分隔符!将其分割为字符串数组,每个字符串元素代表一个结点,然后开始重建二叉树。由于每个结点再字符串中只保留了一个val值,因此需要根据结点的值val重新构建TreeNode结点对象,并且为这个结点对象的left和right进行赋值。
反序列化比序列化要难,其实代码实现是类似的,只也是使用递归,只是这时候是反向的递归,比较抽象,要逐渐理解。已知一个用!分割的字符串是某个二叉树按照先序遍历顺序序列化得到的字符串,将其反序列化建立一棵二叉树,注意,要进行反序列化必须要知道这个字符串是按照什么顺序序列化得到的,只有按照相同的遍历顺序对其进行反序列化才能恢复正确的二叉树。一般使用先序遍历顺序进行序列化和反序列化。在反序列化时,首先得到一个字符串数组strs[]表示字符串序列拆分得到的字符串数组,数组的每个元素字符串对应一个结点的值,可以是3!或者是#!,分别表示一个非空的结点或者是空结点。即要求实现的功能是:根据给定的字符串数组strs[],重建一棵二叉树并返回这棵二叉树的头结点root。
分析:对于字符串数组strs[],第1个元素是根结点,第2个元素是左结点,第3个元素可能是第2个结点的左结点或者是第1个结点的右结点,要根据第2个结点是否为null来确定,即对于strs[],里面的元素必然是按照:根结点à左结点à左结点à左结点(null)à右结点à左结点à左结点(null)à右结点的顺序来排列的,因此总是先递归地恢复建立左结点,当遇到null时,说明这条路径结束了,node结点的left为null,应该返回到node结点并开始恢复一个右结点,此时相当于一个新的重复的过程,可以把这个右结点当做root开始新的递归过程。
即要求实现一个递归方法private TreeNode deSerialize(String[] strs);对于一个(或者部分)字符串数组,恢复一棵二叉树,并返回这棵二叉树的根结点。
逐个遍历数组strs[],当遇到“#”说明这是一个空结点,在这个根结点的后面不可能建立二叉树,于是相当于建立子树工作完成,返回根结点即返回null即可;如果遇到的是非空的字符串,例如“3”,表明这是一个非空的结点,首先建立这个结点TreeNode newNode=new TreeNode(3);但是此时仅仅恢复了一个结点,还要恢复它的子树,并且是先恢复左子树,再恢复右子树。如何恢复左子树?显然要根据数组strs[]的下一个元素开始的数组部分来恢复一棵二叉树,这就是这个递归函数的功能(根据一个或者部分字符串数组来建立一棵二叉树),于是调用自身这个递归函数即可,只是此时使用的字符串向后面移动了1个元素而已。
调用完这个函数后,就要认为结点③的左子树已经恢复完毕了,于是开始恢复结点③的右子树newNode.right;恢复右子树的过程还是一样的,也是相同的逻辑(根据一个或者部分字符串数组来建立一棵二叉树),只是此时恢复的二叉树连接到的不是newNode.left上面而是newNode.right上面,当调用完这个函数后,就认为结点newNode的右子树已经恢复完成了,于是整个newNode的val有了,left、right都有了值,于是整棵二叉树就建立了,此时根据函数功能的要求,要返回这棵建立起来的二叉树的根结点,于是返回newNode即可。
常识:没有构造方法时默认有参数为空的构造函数可以不写;当写有含参的构造方法时,如果不写参数为空的构造方法,就不能再使用TreeNode newNode=new TreeNode()这种构造方法,如果要用就必须显示地定义参数为空的构造方法。
标签:blog ret 表示 tree java index imp core class
原文地址:http://www.cnblogs.com/joshsung/p/7407016.html