非递归遍历二叉树是使用堆栈来进行保存,个人推荐使用双while结构,完全按照遍历顺序来进行堆栈的操作,当然在前序和后序的遍历过程中还有其他的压栈流程。
先序遍历(左右,add在while中)
先序遍历就是在第一次访问到节点的时候将其值进行打印,然后递归打印其左子树,最后递归打印其右子树。
解法一、双while
public void preorder(TNode node){
ArrayList<TNode> aList=new ArrayList<>();
Stack<TNode> stack=new Stack<>();
while (!stack.isEmpty()||node!=null) {
while (node!=null) {
stack.push(node);
aList.add(node);
node=node.leftChild;
}
node=stack.pop();
node=node.rightChild;
}
for (int i = 0; i < aList.size(); i++) {
System.out.print(aList.get(i)+" ");
}
}
可以使用一个栈来模拟这种操作:
首先将root压栈;
每次从堆栈中弹出栈顶元素,表示当前访问的元素,对其进行打印;
依次判断其右子树,左子树是否非空,并进行压栈操作,至于为什么先压栈右子树,因为先压栈的后弹出,左子树需要先访问,因此后压栈;
重复直到栈为空。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public void preorder(TNode node){
ArrayList<TNode> aList=new ArrayList<>();
Stack<TNode> stack=new Stack<>();
if (node==null) {
return ;
}
stack.push(node);
while(!stack.isEmpty()){
TNode curNode=stack.pop();
aList.add(curNode);
if (curNode.rightChild!=null) {
stack.push(curNode);
}
if (curNode.leftChild!=null) {
stack.push(curNode);
}
}
for (int i = 0; i < aList.size(); i++) {
System.out.print(aList.get(i)+" ");
}
}
中序遍历(左右,add在while外)
public void inorder(TNode node){
ArrayList<TNode> aList=new ArrayList<>();
Stack<TNode> stack=new Stack<>();
while (!stack.isEmpty()||node!=null) {
while(node!=null){
stack.push(node);
node=node.leftChild;
}
node=stack.pop();
aList.add(node);
node=node.rightChild;
}
for (int i = 0; i < aList.size(); i++) {
System.out.print(aList.get(i)+" ");
}
}
后序遍历(右左,add在while中且头插入)
后序遍历的非递归版本是最有技巧性的,难度相对高一点,但其实是可以转换成前序遍历的。
后序遍历的顺序是左右中,因此只需要按中右左遍历,再reverse一下即可。
public void inorder(TNode node){
ArrayList<TNode> aList=new ArrayList<>();
Stack<TNode> stack=new Stack<>();
while(!stack.isEmpty()||node!=null){
while (node!=null) {
stack.push(node);
aList.add(0,node);//将node一直插入到list的开头,即reverse
node=node.rightChild;
}
node=stack.pop();
node=node.leftChild;
}
for (int i = 0; i < aList.size(); i++) {
System.out.print(aList.get(i)+" ");
}
}