- 前序非递归遍历基本思想:
- 首先从访问节点,
- 访问完后将节点入栈,
- 如果节点有左孩子,
- 则变量指向左孩子重复以上顺序
- 当左孩子为空时,则出栈,获得栈顶元素的右孩子(所有入栈的元素及其左孩子元素都是被访问过的),执行1-3步骤
- 代码:
//二叉树定义 class Btree { int value; Btree leftBtree; Btree rightBtree; } //前序遍历非递归实现 public void printPreOrder(Btree btree){ Stack<Btree> stack = new Stack<Btree>(); while(btree != null || !stack.isEmpty()){ while(btree != null){ System.out.println("node:"+btree.value); stack.push(btree); btree = btree.leftBtree; } if(!stack.isEmpty()){ btree = stack.pop().rightBtree; } } }
- 中序遍历非递归实现:
- 思想与前序类似,通过栈实现,不同的是把访问节点时机放到了出栈时
- 中序从根节点开始先入栈,左孩子不为空则左孩子入栈
- 然后出栈访问节点,再以节点的右孩子重复前面入栈操作
public void printInOrder(Btree btree){ Stack<Btree> stack = new Stack<Btree>(); while(btree != null || !stack.isEmpty()){ while(btree != null){ stack.push(btree); btree = btree.leftBtree; } if(!stack.isEmpty()){ btree = stack.pop(); System.out.println("node:"+btree.value); btree = btree.rightBtree; } } }
- 后续遍历非递归实现:
- 基本思想是入栈顺序是根节点、右孩子、左孩子,这样保重了出栈访问时的顺序
- 出栈时,访问一个节点的条件是:该节点没有左右孩子 或者 该节点左右孩子已被访问过(通过一个标记标量标定);即首先判断该节点是否有子节点,如果有,则判断该节点的子节点是否被访问过,如果子节点没有访问则应让子节点入栈(保重根节点后续访问嘛);否则,没有子节点或子节点已被访问过时可以出栈访问该节点
public void printPostOrder(Btree btree){ Btree cur = null,pre = null; Stack<Btree> stack = new Stack<Btree>(); stack.push(btree); while(!stack.isEmpty()){ cur = stack.peek(); if((cur.leftBtree==null && cur.rightBtree==null) || (pre != null && (pre == cur.leftBtree || pre == cur.rightBtree))){ System.out.println("node:"+cur.value); stack.pop(); pre = cur; } else { if(cur.rightBtree!=null) stack.push(cur.rightBtree); if(cur.leftBtree!=null) stack.push(cur.leftBtree); } } }