根據二叉樹的前序和中序構建二叉樹

有了二叉樹的前序和中序或者中序和後序遍歷序列就可以利用這些信息來重構一棵二叉樹了,這是編程之美3.9裏面的一個題目。

java實現中遇到的難點:

java的值傳遞機制

當一個對象被當作參數傳遞到一個方法後,此方法可改變這個對象的屬性,並可返回變化後的結果,那麼這裏到底是值傳遞還是引用傳遞?
    答:是值傳遞。Java 編程語言只有值傳遞參數。當一個對象實例作爲一個參數被傳遞到方法中時,參數的值就是該對象的引用一個副本。指向同一個對象,對象的內容可以在被調用的方法中改變,但對象的引用(不是引用的副本)是永遠不會改變的。


Java參數,不管是原始類型還是引用類型,傳遞的都是副本(有另外一種說法是傳值,但是說傳副本更好理解吧,傳值通常是相對傳址而言)。

    如果參數類型是原始類型,那麼傳過來的就是這個參數的一個副本,也就是這個原始參數的值,這個跟之前所談的傳值是一樣的。如果在函數中改變了副本的 值不會改變原始的值.
    如果參數類型是引用類型,那麼傳過來的就是這個引用參數的副本,這個副本存放的是參數的地址。如果在函數中沒有改變這個副本的地址,而是改變了地址中的 值,那麼在函數內的改變會影響到傳入的參數。如果在函數中改變了副本的地址,如new一個,那麼副本就指向了一個新的地址,此時傳入的參數還是指向原來的 地址,所以不會改變參數的值。

本問題書中的返回值是void,但是由於書中是c++代碼,而java又有值傳遞機制,所以返回值改爲TreeNode39,尤其需要注意,第44行和第48行的左右子樹重新賦值操作。函數執行完畢在最後返回proot。

public class Test_3_9 {

	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		String preorder = "abdcef";
		String inorder = "dbaecf";
		int len = preorder.length();
		TreeNode39 proot =null;
		
		inorder(ReBuild(preorder,inorder,len,proot));

	}
	//根據中序和前序序列,重建二叉樹
	public static TreeNode39 ReBuild(String preorder,String inorder,int len,TreeNode39 proot){
		if(preorder==null||inorder==null)return null;
		TreeNode39 temp = new TreeNode39();
		temp.setValue(preorder.charAt(0));
		temp.setLeft(null);
		temp.setRight(null);
		if(proot == null)proot =temp; 
		if(len ==1){
			return proot;
		}
		//尋找子樹長度
		//int templen =0;
		int i =0;
		while(preorder.charAt(0)!=inorder.charAt(i)){
			i++;
			if(i>=len)break;
			
		}
		//左子樹長度
		int leftlen=i;
		//右子樹長度
		int rightlen = len -leftlen-1;
		
		//重建左子樹
		if(leftlen>0){
			//java的值傳遞機制,此時要重新給proot.left賦值,
			proot.setLeft(ReBuild(preorder.substring(1),inorder,leftlen,proot.getLeft()));
		}
		//重建右子樹
		if(rightlen>0){
			proot.setRight(ReBuild(preorder.substring(leftlen+1),inorder.substring(leftlen+1),rightlen,proot.getRight()));
		}
		return proot;
		
	}
	//中序遍歷
	public static void inorder(TreeNode39 root){
		if(root!=null){
			inorder(root.getLeft());
			System.out.println(root.getValue());
			inorder(root.getRight());
		}
	}

}
class TreeNode39{
	private TreeNode39 left;
	private TreeNode39 right;
	private char value;
	public TreeNode39 getLeft() {
		return left;
	}
	public void setLeft(TreeNode39 left) {
		this.left = left;
	}
	public TreeNode39 getRight() {
		return right;
	}
	public void setRight(TreeNode39 right) {
		this.right = right;
	}
	public char getValue() {
		return value;
	}
	public void setValue(char value) {
		this.value = value;
	}
}


 

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