二叉树按层遍历打印换行

时间:2022-07-27 11:11:04

我们都知道,广度优先遍历——对二叉树来说就是按层遍历,需要借助队列。代码也很简单,就几行。但是为什么要借助队列呢? 

粗鲁分析:

二叉树的按层遍历是这样:从左到右,从上到下访问每个节点。而二叉树本身给出的信息是其下一行的左右节点的,所以在访问某一行节点时,就要保存其含有的信息——下一行节点。

如果某行有n个节点,从1访问到n时,需要保存1的左右节点,2的左右节点,,,n的左右节点,遍历下行时的顺序是1的左右,2的左右,,,n的左右。

这不就是先进(先保存)先出(先访问)吗?

算法伪码:

1.root进队(每个元素都要进队,别直接访问)

2.开始循环:队首出队,其左右节点进队。(当然你也可以左右节点先进队,再队首出队,但是这样比较不舒服!——老子还没出去,儿子就进来了)

 循环条件是队非空。

简单的代码:

	public void visitTree(TreeNode root) {
		Queue<TreeNode> queue = new LinkedList<TreeNode>();
		queue.offer(root);
		TreeNode cur;
		while(!queue.isEmpty()) {
			cur = queue.poll();//出队
			System.out.println(cur.val);//访问这个出队的
			if (cur.left != null) {
				queue.offer(cur.left);
				nlast = cur.left;
			}
			if (cur.right != null) {
				queue.offer(cur.right);
				nlast = cur.right;
			}
		}
	}
=======================分割线===================================


然鹅,事情并不总是这么简单。现在要求在每行结束后打印换行,该如何?

第一行的换行很简单啊,root后直接换行。

那么你已经知道了第一行的换行,你就知道了第二行的换行位置啊,毕竟第二行都是第一行的“映射”

所以呢,跟刚才一样,在访问第n行的时候就要保存第n+1行的最右信息,反正n+1行的最右就是从第n行的左节点(第n+1行的最左)开始迭代。

-----

现在需要2个变量,一个保存当前行的最右设为last,一个保存下一行的最右nlast。

last刚开始为root,当前行即第一行,第一行最右即root,已知的最右,没毛病

当访问到cur==last时,打印换行,且此时nlast必定已经迭代到下一行的最右了,所以在把nlast赋给last,进入下一行的访问。


代码依旧很简单

	public void visitTree(TreeNode root) {
		Queue<TreeNode> queue = new LinkedList<TreeNode>();
		queue.offer(root);
		TreeNode cur;
		TreeNode last = root;	//当前行的最后一个节点——初始值,root
		TreeNode nlast;	//下一行的最后一个节点
		while(!queue.isEmpty()) {
			cur = queue.poll();
			System.out.println(cur.val);
			if (cur.left != null) {
				queue.offer(cur.left);
				nlast = cur.left;//迭代的nlast
			}
			if (cur.right != null) {
				queue.offer(cur.right);
				nlast = cur.right;//迭代的nlast
			}
			if (cur == last) {//当前节点是当前最右时,nlast的迭代也就结束了,它已经是最右了,赋给last
				System.out.println("---------");//直接都用println了,用----假装换行,重在思路,不要在意细节
				last = nlast;
			}//这个判断为什么要放到左右节点进队之后呢,因为还要迭代nlast呢,很关键
		}
	}