二叉树遍历

二叉树

 

①前序遍历:先访问根节点,再访问左节点,若左节点的左节点不为空,则继续向下访问,直到左节点为空,然后在从下往上访问右节点。

  先访问F,F的左节点不为空,则访问其左节点C;同理访问A,A的左节点为空则访问其右节点,右节点也为空,则访问与A有同一父节点的右节点也就是D节点;D的左节点不为空,则访问其左节点B;B左节点,右节点都是空,则会去访问D的右节点,D的右节点为空,则去访问与C同一父节点的E;同理访问完右子树。 

遍历结果: F>C>A>D>B>E>H>G>M

②中序遍历:先访问左节点,再访问父节点,最后访问右节点

中序则是从最左节点开始访问即A节点,然后再访问其父节点C,接着访问C节点的右子树,对其右子树依然采取 左>中>右的顺序,所以接下来会访问B节点,然后是D节点。根节点的左子树访问完成则会访问根节点F,最后访问根节点右子树;对右子树的访问顺序与访问左子树的顺序相同,依然采取 左>中>右的顺序;

遍历结果:A>C>B>D>F>H>E>M>G

③后序遍历:先访问左节点,再访问右节点,最后访问父节点

后序遍历同样是从最左节点开始,若最左节点有右子树,则需先访问其右子树;不过先访问右节点再访问父节点,参考中序遍历;

遍历结果:A>B>D>C>H>M>G>E>F

另一种对顺序理解:将每个节点的左右节点补全,比如A补全左右两个节点,D只需补全一个右节点;然后从根节点开始,沿着树的外轮廓向下走:

节点第一次被遇到就输出该节点 输出结果与前序遍历相同 ;

节点第二次被遇到就输出该节点 输出结果与中序遍历相同 ;

节点第三次被遇到就输出该节点 输出结果与后序遍历相同 ;

1 通过递归实现

 

 //前序遍历
    public void preorder(MyNode Node) {
        if (Node != null) {
            System.out.print(Node.key + " ");//优先访问输出父节点
            preorder(Node.LeftMyNode);       //访问左节点
            preorder(Node.RightMyNode);      //访问右节点

        }
    }

    //中序遍历
    public void inorder(MyNode Node) {
        if (Node != null) {
            inorder(Node.LeftMyNode);            //优先访问左节点
            System.out.println(Node.key + " ");  //访问父节点
            inorder(Node.RightMyNode);           //访问右节点
        }
    }

    //后续遍历
    public void postorder(MyNode Node) {
        if (Node != null) {
            postorder(Node.LeftMyNode);         //先访问左节点
            postorder(Node.RightMyNode);        //再访问右节点
            System.out.print(Node.key + " ");   //最后访问父节点
        }
    }

2 通过栈实现

   //前序遍历 
   public void preorder(Node node ) { 
        Stack<Node> stack = new Stack<Node>();
        while (node != null || stack.size() > 0) {    //将所有左孩子压栈
            if (node != null) {                       //压栈之前先访问
                printNode(node);
                stack.push(node);
                node = node.getLeftNode();
            } else {
                node = stack.pop();
                node = node.getRightNode();
            }
        }
    }
    
    //中序遍历
    public void inorder(Node node ) {                 
        Stack<Node> stack = new Stack<Node>();
        while (node != null || stack.size() > 0) {
            if (node != null) {
                stack.push(node);                     //直接压栈
                node = node.getLeftNode();
            } else {
                node = stack.pop();                   //出栈并访问
                printNode(node);
                node = node.getRightNode();
            }
        }
    }

    //后序遍历
    public void postorder(Node node ) {                
        Stack<Node> stack = new Stack<Node>();
        Stack<Node> stack2 = new Stack<Node>();       
        while (node != null || stack.size() > 0) {
            if (node != null) {
                stack2 .push(node);
                stack.push(node);
                node = node.getRightNode();
            } else {
                node = stack.pop();
                node = node.getLeftNode();
            }
        }
        // System.out.println(stack2 .size());
        while (stack2 .size() > 0) {
            printNode(stack2 .pop());
        }
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值