Java不使用递归完成二叉树的先中后序遍历
【题⽬】
按照⼆叉树的先序遍历打印⼆叉树,并且不能使⽤递归。
先序遍历
-
⼆叉树的先序遍历顺序是根-左-右。我们可以采⽤⼀个栈来辅助,我们把先序遍历的结果放到⼀个ArrayList 容器中作为返回值,具体步骤如下:
1、把⼆叉树的根节点 root 放进栈。
2、如果栈不为空,从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦树不为空,则把有节点放⼊栈;如果该节点的左⼦树不为空,则把左⼦树放⼊栈中。
3、⼀直重复步骤 2 ,直到栈为空,此时遍历结束,代码如下:
static List<Integer> preOderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if(root == null)
return result;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode tmp = stack.pop();
result.add(tmp.value);
if(tmp.right != null)
stack.push(tmp.right);
if(tmp.left != null)
stack.push(tmp.left);
}
return result;
}
中序遍历
⼆叉树的中序遍历顺序是左-根-右。我们可以采⽤⼀个栈来辅助,我们把中序遍历的结果放到⼀个ArrayList 容器中作为返回值,具体步骤如下:
1、进⼊ while 循环,接着把根节点及其所有左⼦节点放⼊栈中。
2、从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦节点不为空,则把右⼦节点及其右⼦节点的所有左⼦节点放⼊队列。
3、⼀直重复步骤 2 ,直到栈为空并且当前节点也为空则退出循环。
可能看解释反⽽有点乱,直接看代码吧,配合代码就容易懂了。
public List<Integer> inOderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
if (root != null) {
stack.push(root);
root = root.left;
}
else {
root = stack.pop();
res.add(root.val);
root = root.right;
}
}
return res;
}
后序遍历
⼆叉树的后序遍历顺序是左-右-根。我们可以采⽤⼀个栈来辅助,不过它和前序遍历以及中序遍历还是有点区别的,我们把后序遍历的结果放到⼀个 LinkedList 容器中作为返回值,具体步骤如下:
1、把⼆叉树的根节点 root 放进栈。
2、如果栈不为空,从栈中取出⼀个节点,把该节点插⼊到容器的头部。;如果该节点的左⼦树不为空,则把该左⼦树放⼊栈中;如果该节点的右⼦树不为空,则把右⼦树放⼊栈中。
注意,之前的前序遍历和中序遍历,我们都是⽤ ArrayList 容器,并且是把节点插⼊到容器的尾部,这就是后序遍历的不同点。
3、⼀直重复步骤 2 ,直到栈为空,此时遍历结束,代码如下:
// 后序遍历
public List<Integer> postOderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();// 注意,采⽤链表
Stack<TreeNode> stack = new Stack<>();
if(root == null)
return res;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode tmp = stack.pop();
// 注意,是放在第⼀个位置
//一直顶栈
res.addFirst(tmp.val);
if(tmp.left != null)
stack.push(tmp.left);
if(tmp.right != null)
stack.push(tmp.right);
}
return res;
}