当前位置:   article > 正文

二叉树的前序,中序,后序遍历(递归和非递归写法)_非递归后序周游

非递归后序周游

一、前序遍历

        前序遍历是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右

        前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根节点,然后遍历左子树,最后遍历右子树。

        若二叉树为空则结束返回,否则:

        (1)访问根结点。

        (2)前序遍历左子树

        (3)前序遍历右子树 。

        如图所示,前序遍历的结果为:ABDECFG

 

递归实现:

  1. public class TreeNode {//定义二叉树节点
  2. TreeNode leftnode;
  3. TreeNode rightnode;
  4. String v;
  5. public TreeNode(String v){
  6. this.v=v;
  7. }
  8. //递归前序
  9. public void preOrder(TreeNode root){
  10. if(root != null){
  11. System.out.print(root.v);//打印根节点
  12. preOrder(root.leftnode);//访问左节点
  13. preOrder(root.rightnode);//访问右节点
  14. }
  15. }
  16. }

测试代码,下同

  1. public class Test {
  2. public static void main(String[] args) {
  3. TreeNode n1=new TreeNode("A");
  4. TreeNode n2=new TreeNode("B");
  5. TreeNode n3=new TreeNode("C");
  6. TreeNode n4=new TreeNode("D");
  7. TreeNode n5=new TreeNode("E");
  8. TreeNode n6=new TreeNode("F");
  9. TreeNode n7=new TreeNode("G");
  10. n1.leftnode=n2;
  11. n1.rightnode=n3;
  12. n2.leftnode=n4;
  13. n2.rightnode=n5;
  14. n3.leftnode=n6;
  15. n3.rightnode=n7;
  16. n1.preOrder(n1);
  17. }
  18. }

测试结果:

非递归实现:

        根节点存入栈中打印根节点,然后访问这个根节点的左子树,左子树也是将左子树的根存入栈中打印根节点,依次往下直到左子树为空,再取出栈顶元素,栈顶元素(访问完左子树的根节点)作为新的根节点去访问右子树。

 

  1. public class TreeNode {//定义二叉树节点
  2. TreeNode leftnode;
  3. TreeNode rightnode;
  4. String v;
  5. public TreeNode(String v){
  6. this.v=v;
  7. }
  8. //非递归前序
  9. public void preOrder(TreeNode root){
  10. Stack<TreeNode> stack =new Stack<>();//定义一个栈用于存放节点
  11. while (root!=null || !stack.isEmpty()){//判断二叉树是否遍历完
  12. while (root!=null){//往左走
  13. stack.push(root);//根节点入栈
  14. System.out.print(root.v);//打印根节点
  15. root=root.leftnode;//访问根节点的左节点
  16. }
  17. root=stack.pop();//取出根节点
  18. root=root.rightnode;//访问根节点的右节点
  19. }
  20. }
  21. }

测试结果:

二、中序遍历 

        中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。可记作左跟右

        中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。

        若二叉树为空则结束返回,否则:

        (1)中序遍历左子树

        (2)访问根结点

        (3)中序遍历右子树

如图所示,中序遍历的结果为:DBEAFCG

递归实现:

  1. public class TreeNode {//定义二叉树节点
  2. TreeNode leftnode;
  3. TreeNode rightnode;
  4. String v;
  5. public TreeNode(String v){
  6. this.v=v;
  7. }
  8. //递归中序
  9. public void preOrder(TreeNode root){
  10. if(root != null){
  11. preOrder(root.leftnode);//访问左节点
  12. System.out.print(root.v);//打印根节点
  13. preOrder(root.rightnode);//访问右节点
  14. }
  15. }
  16. }

 测试结果:

 非递归方式

        与前序方式基本相同,不同的是不先打印根节点,而是先访问左子树,在打印根节点,在访问右子树。

  1. public class TreeNode {//定义二叉树节点
  2. TreeNode leftnode;
  3. TreeNode rightnode;
  4. String v;
  5. public TreeNode(String v){
  6. this.v=v;
  7. }
  8. //非递归中序
  9. public void preOrder(TreeNode root){
  10. Stack<TreeNode> stack =new Stack<>();//定义一个栈用于存放节点
  11. while (root!=null || !stack.isEmpty()){//判断二叉树是否遍历完
  12. while (root!=null){//往左走
  13. stack.push(root);//根节点入栈
  14. root=root.leftnode;//访问根节点的左节点
  15. }
  16. root=stack.pop();//取出根节点
  17. System.out.print(root.v);//打印根节点
  18. root=root.rightnode;//访问根节点的右节点
  19. }
  20. }
  21. }

测试结果:

 

后序遍历

        后序遍历(LRD)是二叉树遍历的一种,也叫做后根遍历、后序周游,可记做左右根。  

        后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。即:

若二叉树为空则结束返回,否则:

        (1)后序遍历左子树

        (2)后序遍历右子树

        (3)访问根结点

 如图所示,中序遍历的结果为:DEBFGCA\

 递归方法

  1. public class TreeNode {//定义二叉树节点
  2. TreeNode leftnode;
  3. TreeNode rightnode;
  4. String v;
  5. public TreeNode(String v){
  6. this.v=v;
  7. }
  8. //递归后序
  9. public void preOrder(TreeNode root){
  10. if(root != null){
  11. preOrder(root.leftnode);//访问左节点
  12. preOrder(root.rightnode);//访问右节点
  13. System.out.print(root.v);//打印根节点
  14. }
  15. }
  16. }

 测试结果:

非递归方法 

  1. public class TreeNode {//定义二叉树节点
  2. TreeNode leftnode;
  3. TreeNode rightnode;
  4. String v;
  5. public TreeNode(String v){
  6. this.v=v;
  7. }
  8. //非递归后序
  9. public void preOrder(TreeNode root){
  10. Stack<TreeNode> stack =new Stack<>();//定义一个栈用于存放节点
  11. TreeNode node =root;
  12. TreeNode p=null;
  13. while (node!=null || !stack.isEmpty()){//判断二叉树是否遍历完
  14. while (node!=null){//往左走
  15. stack.push(node);//根节点入栈
  16. node=node.leftnode;//访问根节点的左节点
  17. }
  18. node=stack.peek();//判断栈顶元素
  19. if (node.rightnode==null || node.rightnode==p){
  20. node=stack.pop();//打印根节点,并出栈,将打印过的节点从栈中删除
  21. System.out.print(node.v);
  22. p=node;//记录prev,表示以当前prev为根的子树已经访问过了
  23. node=null;//node置null就不会再次访问以node为根节点的左右子树,这里的node既然已经打印,说明它的左右子树早已访问完毕
  24. }else {
  25. node=node.rightnode;//访问右子树
  26. }
  27. }
  28. }
  29. }

测试结果:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/625892
推荐阅读
相关标签
  

闽ICP备14008679号