算法:打印二叉樹的邊界節點:

打印二叉樹的邊界節點有兩個標準,這裏只看標準一:

1. 頭節點爲邊界節點

2. 葉節點爲邊界節點

3. 如果節點在其所在的層中是最左或最右的,那麼也是邊界節點

左程雲的《程序員代碼面試指南》裏面的解法如下:

1. 遞歸遍歷樹,找到樹的最大高度,然後定義保存每層最左最右邊界節點的二維數組

2. 遞歸找出每層最左最右邊界節點(如果該層只有一個節點,那麼會重複保存)

3. 先從上往下打印左邊界節點,然後遞歸找到每層的葉子節點並打印,最後從下往上打印最右邊界節點

代碼上遞歸用的比較多,而且要好幾次DFS遍歷樹,我給出的解法做了一點優化:

1. 使用一次BFS層遍歷樹,就可以找出所有需要的節點

2. 不用計算樹的高度,並且無遞歸代碼

算法代碼如下:

public void printEdgeNodes(TreeNode head){
	Deque<TreeNode> q = new LinkedList<>(); 
	List<TreeNode> lefts = new ArrayList<>(); // 保存最左邊界節點
	Stack<TreeNode> rights = new Stack<>(); // 保存最右邊界節點,因爲是從下往上打印,所以用棧
	List<TreeNode> leafs = new ArrayList<>(); // 保存每層的葉子節點
	
	q.addLast(head); // 預先放入頭節點
	while (!q.isEmpty()){
		int size = q.size();
		for (int i = 0; i < size; i++){
			TreeNode cur = q.removeFirst();
			// if - else 保證節點不會重複出現在不同集合裏
			if (i == 0){
				lefts.add(cur);
			} else if (i == size - 1){
				rights.push(cur);
			} else if (cur.left == null && cur.right == null){
				leafs.add(cur);
			}
			// 添加當前節點的左右節點到隊列
			if (cur.left != null)
				q.addLast(cur.left);
			if (cur.right != null)
				q.addLast(cur.right);
		}
	}
	// 先打印左邊界
	for (TreeNode cur : lefts){
		System.out.println(cur.value);
	}
	// 再打印葉子節點
	for (TreeNode cur : leafs){
		System.out.println(cur.value);
	}
	// 最後打印有邊界
	while (!rights.isEmpty()){
		System.out.println(rights.pop().value);
	}
}

 

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