【剑指offer】37、序列化二叉树

本文介绍了一种使用先序遍历方法来序列化和反序列化二叉树的有效策略。通过将二叉树转换为字符串,并从字符串重构二叉树,实现了数据的持久化存储和恢复。文章详细解释了实现过程,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

        请实现两个函数,分别用来序列化和反序列化二叉树。

解题思路

     通过先序遍历实现序列化和反序列化:

1、假设序列化的结果字符串为str,初始的时候str=""。

     先序遍历二叉树,如果遇到null节点,就在str的末尾加上“#!”,“#”表示这个节点为空,节点的值不存在,"!"表示值的结束。

     如果遇到不为空的节点,假设节点的值为3,就在str的末尾加上"!”,变为“3!”。。

2、重构二叉树,反序列化:

      把结果字符串str变成字符串类型的数组,记为values,数组代表一棵二叉树先序遍历的节点顺序。例如,str=”12!3!#!#!#!”,生成的values为[“12”,”3”,”#”,”#”,”#”],然后用values[0…4]按照先序遍历的顺序建立整棵树。 

      1)遇到”12”,生成节点值为12的节点(head),然后用values[0…4]建立节点12的左子树。

      2)遇到”3”,生成节点值为3的节点,它是节点12的左孩子,然后用values[2…4]建立节点3的左子树。 

      3)遇到”#”,生成null节点,它是节点3的左孩子,该节点为null,所以这个节点没有后续建立子树的过程。回到节点3后,继续用values[3…4]建立节点3的右子树。 

      4)遇到“#”,生成null节点,它是节点3的右孩子,该节点为null,所以这个节点没有后续建立子树的过程。回到节点3后,再回到节点1,用values[4]建立节点1的右子树。 

      5)遇到“#”,生成null节点,它是节点1的左孩子,该节点为null,所以这个节点没有后续建立子树的过程。整个过程结束。 

 

测试用例

     1.功能测试(一个结点;左右斜树;完全二叉树;普通二叉树)

   2.特殊测试(根结点为null)

代码

package myNewSwordOffer;

import java.util.LinkedList;
import java.util.Queue;

public class deserialize {
	public static class TreeNode{
		int val;
		TreeNode left;
		TreeNode right;
		
		public TreeNode(int val) {
			this.val = val;
		}
	}
	
	//序列化
	public static String Serialize(TreeNode root) {
		if(root == null) {
			return "$,";
		}
		String res = root.val + ",";
		res += Serialize(root.left);
		res += Serialize(root.right);
		return res;
	}
	
	//反序列化
	public static TreeNode DeSerialize(String str) {
		String[] values = str.split(",");
		Queue<String> queue = new LinkedList<String>();
		for(int i = 0; i < str.length(); i++) {
			queue.offer(values[i]);
		}
		
		return DeSerializeOrder(queue);
	}
	
	public static TreeNode DeSerializeOrder(Queue<String> queue) {
		String value = queue.poll();
		if(value.equals("#")) {
			return null;
		}
		TreeNode head = new TreeNode(Integer.valueOf(value));
		head.left = DeSerializeOrder(queue);
		head.right = DeSerializeOrder(queue);
		return head;
	}
	
	
//序列化
//		public static String Serialize(TreeNode root) {
//			StringBuilder sb = new StringBuilder();
//			
//			if(root == null) {
//				sb.append("$,");
//			}else {
//				sb.append(root.val + ",");
//				sb.append(Serialize(root.left));
//				sb.append(Serialize(root.right));
//			}
//			
//			return sb.toString();
//		}
//		
//		//反序列化1
//		static int index = 0;
//		public static TreeNode Deserialize(String str) {
//			TreeNode node = null;
//			if(str == null || str.length() == 0) {
//				return node;
//			}
//			int start = index;
//			while(str.charAt(index) != ',') {
//				index ++;
//			}
//			if(!str.substring(start, index).equals("$")) {
//				node = new TreeNode(Integer.parseInt(str.substring(start, index)));
//				index ++;
//				node.left = Deserialize(str);
//				node.right = Deserialize(str);
//			}else {
//				index++;
//			}
//			return node;
//		}
	
	
//反序列化1
//	static int index = 0;
//	public static TreeNode Deserialize(String str) {
//		TreeNode node = null;
//		if(str == null || str.length() == 0) {
//			return node;
//		}
//		int start = index;
//		while(str.charAt(index) != ',') {
//			index ++;
//		}
//		if(!str.substring(start, index).equals("$")) {
//			node = new TreeNode(Integer.parseInt(str.substring(start, index)));
//			index ++;
//			node.left = Deserialize(str);
//			node.right = Deserialize(str);
//		}else {
//			index++;
//		}
//		return node;
//	}
	
	
	//反序列化2
//	static int index = -1;
//	public static TreeNode Deserialize(String str) {
//		if(str == null || str.length() == 0) {
//			return null;
//		}
//		index ++;
//		int len = str.length();
//		if(index >= len) {
//			return null;
//		}
//		String[] strings = str.split(",");
//		TreeNode node = null;
//		if(!strings[index].equals("$")) {
//			node = new TreeNode(Integer.valueOf(strings[index]));//根
//			node.left = Deserialize(str);//左
//			node.right = Deserialize(str);//右
//		}
//		return node;
//	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值