面试题:序列化二叉树
题目:
请实现两个函数,分别用来序列化和反序列化二叉树
序列化二叉树:将二叉树按一定的遍历顺序保存为字符串,例如,按先序遍历,将树存储为一个字符串,其中值结尾用!,空值用#(符号可自选)
反序列化二叉树:将一个二叉树序列化后的字符串,转化为一颗二叉树
序列化思路:
使用先序遍历,遍历时往字符串中添加值
反序列化思路:
(基于先序遍历)
每次递归时,先将字符串中的第一个字符(非#)创建为节点,删除字符串中第一个和第二个字符(包含!),递归地进行其左节点和右节点的构造
反序列化方法二:
(这个序列是没有!结尾的,只包含数字和代表null的#)
用循环的方法
使用一个栈来存储下一个节点的父节点
如果连续读到两个##,说明该父节点没有子结点,从栈中跳出
如果连续读到三个###,说明该父节点的父节点也没有另外的子结点,也从栈中跳出
具体用flag变量来记录,如果遇到#则flag=1,如果遇到#时flag==1,则表示需要从栈中跳出节点
如果flag=1时,遇到数字,则表示该数字是栈顶元素的右节点
【代码】
// 树 先序 序列化
public static String treeToList(BinaryTreeNode head) {
String str = "";
str = toList(head, str);
return str;
}
public static String toList(BinaryTreeNode head,String str) {
if(head!=null) {
str = str+head.val+"!";
str = toList(head.left, str);
str = toList(head.right, str);
}else {
str = str + "#!";
}
return str;
}
// 树 先序 反序列化
public static BinaryTreeNode listToTree(String str) {
StringBuffer s = new StringBuffer(str);
BinaryTreeNode head=null;
head = toTree(head, s);
return head;
}
public static BinaryTreeNode toTree(BinaryTreeNode node,StringBuffer str) {
char temp = str.charAt(0);
str = str.deleteCharAt(0);
str = str.deleteCharAt(0);
if(temp!='#') {
node = new BinaryTreeNode(temp);
toTree(node.left,str);
toTree(node.right, str);
}
return node;
}
// 反序列化
// 方法二 2019-06-25
public static BinaryTreeNode listToTree(String s) {
if(s=="" || s==null) {
return null;
}
BinaryTreeNode root = new BinaryTreeNode(s.charAt(0)-'0');
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
stack.push(root);
int flag = 0;
for(int i=1;i<s.length();i++) {
if(s.charAt(i)=='#') {
if(flag==1) {
stack.pop();
}else {
flag=1;
}
}else {
int t = s.charAt(i)-'0';
BinaryTreeNode temp = new BinaryTreeNode(t);
if(flag==0) {
stack.peek().left = temp;
}else {
stack.peek().right = temp;
}
stack.push(temp);
flag = 0;
}
}
return root;
}
// 对应的序列化方法
public static String treeToList(BinaryTreeNode root) {
String s = "";
s = toList(root,s);
return s;
}
public static String toList(BinaryTreeNode root, String s) {
if(root!=null) {
s = s + ""+ root.val;
s = toList(root.left, s);
s = toList(root.right, s);
}else {
s = s + "#";
}
return s;
}
【main函数和树构造】
public class Q37 {
public static void main(String[] args) {
BinaryTreeNode head = getTree();
String s = treeToList(head);
System.out.println(s);
BinaryTreeNode temp = listToTree(s);
temp.Too(head);
}
// 得到树
public static BinaryTreeNode getTree() {
BinaryTreeNode node1 = new BinaryTreeNode(1);
BinaryTreeNode node2 = new BinaryTreeNode(2);
BinaryTreeNode node3 = new BinaryTreeNode(3);
BinaryTreeNode node4 = new BinaryTreeNode(4);
BinaryTreeNode node5 = new BinaryTreeNode(5);
BinaryTreeNode node6 = new BinaryTreeNode(6);
BinaryTreeNode node7 = new BinaryTreeNode(7);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node3.left = node5;
node3.right = node6;
node4.right = node7;
return node1;
}
}