题目要求:
/**
* 二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,
* 从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,
* 序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)
*/
二叉树的序列化和反序列化,特别有意思的一个题目,最近突然发现用好递归真的可以非常优雅的写好代码!
那将是我毕生追求的目标!---------------->尽管现状并不尽如人意,可是多磨炼一下自己有什么不好呢?
之所以选这个题目进行整理,是因为二叉树的序列化和反序列化都用到了递归的思想,而且结合了二叉树的前序遍历,我觉得非常有意思,为了加强自己的记忆,写出来
大家一起交流吧!
首先画一个简单的树的模型一起看一下:
首先看序列化部分的代码:
String Serialize(TreeNode root) { if(root==null) return "#"; return root.val + " "+Serialize(root.left)+" "+Serialize(root.right); }
序列化部分的代码比较简单,我们画一幅树一下子就可以理解,我觉得树的前序遍历过程本身就是一个递归的思想,可以回顾一下我们脑子是如何写一棵树的前序遍历的
1--->2-->4-->5--->3-->6-->7 !就是树的完整的前序遍历的过程,当我们进到左子树的时候,本身也是将上一个的程序压如脑栈!然后左子树根节点为根节点,继续遵循中左右的原则进行排序吧!
所以序列化的代码其实很简单:
1先是递归结束的条件 ---> if(root==null) 那么就return"#";
2 如果根节点不是null的话,那么就遵循着前序遍历的条件输出 root.val+" "+Serialize(root.left)+" "+Serialize(root.right); !!!跟人写前序遍历的时候的思维完全一致!
接下来看反序列化的代码:
String dstr=""; TreeNode Deserialize(String str) { dstr = str; return deserialize(); } private TreeNode deserialize() { int index = dstr.indexOf(" "); String Node = index==-1?dstr:dstr.substring(0,index); dstr = index==-1?"":dstr.substring(index+1); if(Node.equals("#"))//一定要注意字符串的相等用equals来判断不能用== return null; int value = Integer.parseInt(Node); TreeNode t = new TreeNode(value); t.left = deserialize(); t.right = deserialize(); return t; }
反序列化的代码也用到了递归的思想,上面那棵树,我们写一下它的序列化的结构是:
1-->2-->4-->#-->#-->5-->#-->#-->3-->6-->#-->#-->7-->#-->#
#号代表的就是null!那么我们来分析一下这个代码,
首先需要明确 序列化之后的代码是用" "进行分隔的,所以我们就是要找int index= dstr.indexOf(" ");这样分成能找到和找不到两种情况
如果index=-1说明找不到,那么String Node = dstr,找不到说明只有一个Node全部是value,如果找到了就切分substring(0,index)--->index取不到刚好是一个value
然后我们需要将全局的dstr进行切分,也就是说如果你已经把1这个值取出来了,需要切掉!dstr = index==-1?"":dstr.substring(index+1);//从这个空格的下一个字符开始,刚好是下一个value;
之后就是新建TreeNode的节点,然后进行树的构造过程!
t.left = deserialize();
t.right = deserialize();
return t;
可以发现反序列化真的和序列化产生的字符串配合的十分恰当,让人 感叹递归的神奇之处!