首先是一个二叉树结构:
class TreeNode{public int value;public TreeNode left;public TreeNode right;public TreeNode(){}public TreeNode(int v){value=v;}
非递归的二叉树遍历需要用到栈的先进后出。
先序遍历
步骤:
1、首先定义一个当前正在检索的结点curNode,将头结点入栈。
2、进入while循环,只有当栈中没有结点时才跳出循环。
3、弹出一个节点赋予curNode,打印这个结点的值。
4、判断当前结点是否有右孩子,有则入栈,判断当前节点是否有左孩子,有则入栈。(注意:此处先入栈右孩子的原因是栈先进后出的特性)
5、重复2~4的步骤直到循环结束。
代码实现:
//二叉树的非递归遍历 先序public static void unorderedTraverse(TreeNode head){if(head==null){return;}Stack<TreeNode> stack=new Stack<>();stack.push(head);TreeNode curNode;while (!stack.isEmpty()){curNode=stack.pop();System.out.print(curNode.value+" ");if(curNode.right!=null){stack.push(curNode.right);}if(curNode.left!=null){stack.push(curNode.left);}}}
结果:
后序遍历
为何先讲后序遍历是因为后序遍历和先序遍历很相似,先序遍历是头左右,后序遍历是左右头,那有人就想了,如果在左右孩子入栈的时候先入左孩子,再入右孩子,是不是就能实现后序遍历了?答案很接近了,如果按是上述实现,得到如下结果:
我们想要得到的结果是,4,5,2,6,7,3,1
刚好是反序,那我们只需要用一个数组存储下来再倒序输出就好了。
代码实现:
//二叉树的非递归遍历 后序public static void unorderedTraverse(TreeNode head){if(head==null){return;}Stack<TreeNode> stack=new Stack<>();stack.push(head);TreeNode curNode;//存储结果,让结果倒序输出;Stack<TreeNode> result=new Stack<>();while (!stack.isEmpty()){curNode=stack.pop();result.push(curNode);if(curNode.left!=null){stack.push(curNode.left);}if(curNode.right!=null){stack.push(curNode.right);}}//倒序输出while (!result.isEmpty()){System.out.print(result.pop().value+" ");}}
结果:
中序遍历:
步骤:
1、判断当前节点是否为null,不为null则入栈,让当前节点更新到当前节点的左孩子直到当前结点为null。
2、更新当前节点为其父节点,输出当前节点的值,让当前节点更新为其右孩子,再一直让当前结点的左孩子判断入栈。
4、重复2~3,直到栈空且当前节点为空。
代码实现:
//二叉树的非递归遍历 中序public static void unorderedTraverse(TreeNode head){if(head==null){return;}Stack<TreeNode> stack=new Stack<>();TreeNode curNode=head;while (!stack.isEmpty()||curNode!=null){if(curNode!=null){stack.push(curNode);curNode=curNode.left;}else {curNode=stack.pop();System.out.print(curNode.value+" ");curNode=curNode.right;}}}
结果: