算法:打印二叉树的边界节点:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Allen_jinjie/article/details/88862566

打印二叉树的边界节点有两个标准,这里只看标准一:

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);
	}
}

猜你喜欢

转载自blog.csdn.net/Allen_jinjie/article/details/88862566
今日推荐