算法第二週作業02

Description

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

Solutions

某顆樹的先序遍歷:ABCDEFG,中序遍歷:CBDAFGE。首先由先序遍歷的第一個節點A可以得知(先序遍歷的特點):這棵樹的根節點爲A;

根據中序遍歷可以得到A節點左邊的節點BCD爲左子樹節點(先序BCD,中序CBD),A節點右邊的節點EFG爲右子樹節點(先序EFG,中序FGE)。

對於左子樹BCD,左子樹的根節點爲B,由中序遍歷得知B節點左邊的節點C屬於左子樹,右邊節點D屬於右子樹;

以此類推。。。。。。採用深度遞歸方式構造整棵樹。

Code

數的結構:

class TreeNode {
	int val;
	TreeNode left;
	TreeNode right;

	TreeNode(int x) {
		val = x;
	}
}


算法如下:

public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
		// 輸入數據合法性校驗
		if (pre == null || in == null || pre.length != in.length) {
			return null;
		}
		// 進入構造樹的遞歸函數
		return buildTree(pre, in);
	}

	public TreeNode buildTree(int[] pre, int[] in) {
		// 每次創建子樹的根節點
		TreeNode result = new TreeNode(pre[0]);
		// 如果該子樹只有一個節點則直接返回該樹
		// 否則需要遞歸設置左右子樹
		if (pre.length != 1) {
			int i = 0;
			for (; i < in.length; i++) {
				if (pre[0] == in[i]) {
					break;
				}
			}
			// 如果有左子樹,則構造左子樹,其中Arrays.copyOfRange用於避免索引越界判斷麻煩,
			// 當然也可以使用左右邊界索引代替copyOfRange,這樣的話輸入參數會很多
			// 例如:buildTree(int[] pre, int[] in, int start1, int end1, int start2, int end2)
			if (i > 0) {
				result.left = buildTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
			}
			if (i < pre.length - 1) {
				result.right = buildTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
			}
		}
		return result;
	}


發佈了40 篇原創文章 · 獲贊 13 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章