劍指Offer面試題62:序列化二叉樹

題目:序列化二叉樹
        請實現兩個函數,分別用來序列化和反序列化二叉樹。
算法分析
        通過分析解決前面的面試題6.我們知道可以從前序遍歷和中序遍歷構造出一棵二叉樹。受此啓發,我們可以先把一棵二叉樹序列化成一個前序遍歷序列和一箇中序序列,然後再反序列化時通過這兩個序列重構出原二叉樹。
  這個思路有兩個缺點。一個缺點是該方法要求二叉樹中不能用有數值重複的結點。另外只有當兩個序列中所有數據都讀出後才能開始反序列化。如果兩個遍歷序列的數據是從一個流裏讀出來的,那就可能需要等較長的時間。
  實際上如果二叉樹的序列化是從根結點開始的話,那麼相應的反序列化在根結點的數值讀出來的時候就可以開始了。因此我們可以根據前序遍歷的順序來序列化二叉樹,因爲前序遍歷是從根結點開始的。當在遍歷二叉樹碰到NULL指針時,這些NULL指針序列化成一個特殊的字符(比如‘$’)。另外,結點的數值之間要用一個特殊字符(比如’,’)隔開。
根據以上規則,下圖二叉樹被序列化成字符串後的結果爲:“1,2,4,$,$,$,3,5,$,$,6,$,$”


算法源程序:
/**************************************************************      
* Copyright (c) 2016, 
* All rights reserved.                   
* 版 本 號:v1.0                   
* 題目描述:序列化二叉樹
*		       請實現兩個函數,分別用來序列化和反序列化二叉樹。
* 輸入描述:無
* 程序輸出:序列化二叉樹後的輸出爲:1,2,4,8,#,#,9,#,#,5,#,#,3,6,#,#,7,#,#,
*			反序列化後的輸出爲:1
* 問題分析: 無
* 算法描述:實際上如果二叉樹的序列化是從根結點開始的話,那麼相應的反序列化在根結點的數值讀出來的時候就可以開始了。
* 			因此我們可以根據前序遍歷的順序來序列化二叉樹,因爲前序遍歷是從根結點開始的。當在遍歷二叉樹碰到NULL指針時,
* 			這些NULL指針序列化成一個特殊的字符(比如‘$’)。另外,結點的數值之間要用一個特殊字符(比如’,’)隔開。
*			根據以上規則,下圖二叉樹被序列化成字符串後的結果爲:“1,2,4,$,$,$,3,5,$,$,6,$,$”
*							1
*						2		3
*					4		  5   6
* 完成日期:2016-10-17
***************************************************************/

package org.marsguo.offerproject62;

class TreeNode{
	int val;
	public TreeNode left = null;
	public TreeNode right = null;
	public TreeNode(int val){
		this.val = val;
	}
	public String toString(){
		return val + "";
	}
}

class SolutionMethod1{
	public int index = -1;
	String Serialize(TreeNode root){
		StringBuffer sb = new StringBuffer();
		if(root == null){
			sb.append("#,");
			return sb.toString();
			
		}
		sb.append(root.val + ",");
		sb.append(Serialize(root.left));			//遞歸調用
		sb.append(Serialize(root.right));			//遞歸調用
		return sb.toString();
	}
	
	TreeNode Deserialize(String str){
		index++;
		int len = str.length();
		if(index >= len){
			return null;
		}
		String[] strr = str.split(",");
		TreeNode node = null;
		if(!strr[index].equals("#")){
			node = new TreeNode(Integer.valueOf(strr[index]));
			node.left = Deserialize(str);
			node.right = Deserialize(str);
		}
		return node;
	}
}

public class SerializeAndDeserialize {
	public static void main(String[] args){
		SolutionMethod1 solution1 = new SolutionMethod1();
		
		TreeNode n1 = new TreeNode(1);
		TreeNode n2 = new TreeNode(2);
		TreeNode n3 = new TreeNode(3);
		TreeNode n4 = new TreeNode(4);
		TreeNode n5 = new TreeNode(5);
		TreeNode n6 = new TreeNode(6);
		TreeNode n7 = new TreeNode(7);
		TreeNode n8 = new TreeNode(8);
		TreeNode n9 = new TreeNode(9);
		
		n1.left = n2;
		n1.right = n3;
		
		n2.left = n4;
		n2.right = n5;
		
		n3.left = n6;
		n3.right = n7;
		
		n4.left = n8;
		n4.right = n9;
		
		String str = solution1.Serialize(n1);
		System.out.println("序列化二叉樹後的輸出爲:" + str);

		System.out.println("反序列化後的輸出爲:" + solution1.Deserialize(str));
	}
}




程序運行結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章