参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:序列化与反序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树。
主要思路:
序列化:用前序遍历序列化二叉树,保存当前节点值到字符串中,并添加”,”用于分割字符串。若当前节点为空,则使用一个特殊符号(比如”%”)来代替空节点。
反序列化:先分割字符串,保存节点值到数组中。按前序遍历特点,先获取根节点,再获取左子树,最后获取右子树。若节点值为特殊符号,则该节点为空。递归该过程,直到遍历完数组。
关键点:递归,前序遍历
时间复杂度:O(n)
public class SerializeTree
{
private static StringBuilder serializeString;
private static int index;
public static void main(String[] args)
{
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
TreeNode root = TreeNode.generateBinaryTree();
String result = serializeTree(root);
TreeNode deserializeTree = deserializeTree(result);
print(deserializeTree);
}
//前序遍历打印
private static void print(TreeNode root)
{
if (root == null) return;
System.out.println(root.val);
print(root.left);
print(root.right);
}
//序列化二叉树
private static String serializeTree(TreeNode root)
{
serializeString = new StringBuilder();
serialize(root);
return serializeString.toString();
}
private static void serialize(TreeNode root)
{
if (root == null)
{
serializeString.append("%,"); //空节点为%
return;
}
//前序遍历
serializeString.append(root.val).append(",");
serialize(root.left);
serialize(root.right);
}
//反序列化二叉树
private static TreeNode deserializeTree(String str)
{
String[] records = str.split(",");
index = 0;
return deserialize(records);
}
private static TreeNode deserialize(String[] records)
{
if (index >= records.length) return null;
//当前节点为空
if (records[index].equals("%"))
{
index++;
return null;
}
int number = Integer.valueOf(records[index++]);
//先获取根节点
TreeNode root = new TreeNode(number);
//再获取左子树,最后获取右子树
root.left = deserialize(records);
root.right = deserialize(records);
return root;
}
}
class TreeNode
{
int val;
TreeNode left;
TreeNode right;
TreeNode(int x)
{
val = x;
}
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
/**
* 生成二叉搜索树
* @return
*/
public static TreeNode generateBinaryTree()
{
TreeNode root = new TreeNode(10);
TreeNode node6 = new TreeNode(6);
TreeNode node14 = new TreeNode(14);
TreeNode node4 = new TreeNode(4);
TreeNode node8 = new TreeNode(8);
TreeNode node12 = new TreeNode(12);
TreeNode node16 = new TreeNode(16);
connectNode(root, node6, node14);
connectNode(node6, node4, node8);
connectNode(node14, node12, node16);
return root;
}
private static void connectNode(TreeNode root, TreeNode left, TreeNode right)
{
root.left = left;
root.right = right;
}
}