[2020.4.1]二叉树的非递归中序遍历

我们知道递归遍历树的方式:对于树的访问先是从根节点开始进行的,递归左子树和右子树,对于左子树和右子树又可以看成是一棵子树继续递归下去,访问根节点的时候它不是直接处理根节点的而是需要等待它的左子树调用完之后那么才进行处理的,左子树也是一样,当访问到它的左子树的时候也需要等待它的左子树处理完毕才处理自己。

这也就是先访问,后出现的特点,与一种数据结构的特点是类似的,那就是栈,栈也是 "先进后出" 的特点,其实递归来说其实就是一种隐式的栈,所以当我们采用非递归形式的时候我们可以自己声明一个栈,模仿递归求解的过程来进行处理

非递归算法思想:

   (1)设置一个栈S存放所经过的根结点(指针)信息;初始化S;

  (2)第一次访问到根结点并不访问,而是入栈;

   (3)中序遍历它的左子树,左子树遍历结束后,第二次遇到根结点,就将根结点(指针)退栈,并且访问根结点;然后中序遍历它的右子树。

  (4) 当需要退栈时,如果栈为空则结束。

图解:

 


public static void main(String[] args) {

        Test t = new Test();
        Node node1 = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        Node node4 = new Node(4);
        Node node5 = new Node(5);
        Node node6 = new Node(6);
        Node node7 = new Node(7);
        node4.left = node2;
        node4.right = node6;
        node2.left = node1;
        node2.right = node5;
        node6.left = node3;
        node6.right = node7;
        t.midOrder(node4);


    }

/*                10
            8            12
          5   9       11   15
         3                    
          
*/
 public void midOrder(Node root) {
            if (root == null) {
                return;
            }
            Stack<Node> stack = new Stack<>();
            Node p = root;
            while (p != null || !stack.isEmpty()) {
//            p不为空压栈
                if (p != null) {//不断将左子树结点都压进去
                    stack.push(p);
                    p = p.left;
                } else {// p为空stack不为空出栈并访问
                    Node poll = stack.pop();//从最后的左子树结点开始访问
                    System.out.println(poll.value);
                    //一旦poll右结点不为空,继续将其放入栈中,接着找到右结点全部的左子结点,即中序遍历poll的右子树
                    p = poll.right;
                }

            }
//        while 循环退出时,p为空,stack为空,全部都遍历了一边

    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值