数据结构与算法(Java) 32:二叉树遍历

题目 实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式。

思路 递归:过于简单,不需要表述。

        非递归:(1)先序遍历【根左右】,设置一个辅助栈,先将根节点放到栈中。栈非空时,遍历剩余部分。遍历时,先弹出栈顶元素,输出,并判断该元素的右孩子节点是否为空,若非空则压入栈中;再判断左孩子节点是否为空,若非空则压入栈中。

                       (2)中序遍历【左根右】,设置一个辅助栈,当栈非空或者当前节点(起始为根节点)非空时,开始遍历。遍历时先判断当前节点左孩子节点是否为空,若非空则将左孩子节点压入栈中,并将左孩子节点设为当前节点;再判断栈是否为空,若非空则将栈顶元素赋值给当前节点,弹出栈顶元素并输出,并将当前节点的右孩子节点设为当前节点。

                       (3)后序遍历【左右根】①:设置两个辅助栈stack1,stack2。利用先序遍历实现后序遍历。因为先序遍历顺序为根左右,将左右互换位置并逆序,得到左右根,即为后序遍历。所以类似于先序遍历(需要的顺序是根右左),先将根节点放到stack1中,若stack1非空,则进行下面的遍历,先弹出stack1的栈顶元素,并将其压入stack2中。接下来判断当前节点的左孩子是否为空,若非空则将其入stack1栈;再判断当前节点的有孩子是否为空,若非空则将其入stack1栈。遍历完成后,依次弹出stack2中的元素,便可以得到后序遍历结果。

                       (4)后序遍历【左右根】②:设置一个辅助栈,先将根节点放到栈中。设置一个辅助指针。栈非空时开始遍历。遍历时,辅助指针先指向栈顶元素,然后开始判断辅助指针指向的节点的左孩子是否为空,同时判断辅助指针指向节点的左孩子和右孩子是否等于当前节点(head),若左孩子不为空,且左孩子和右孩子不等于当前节点,则将左孩子压入栈中;再判断辅助指针指向节点的左孩子是否等于当前节点,同时判断辅助指针指向节点的右孩子是否为空,若右孩子不为空,且左孩子不等于当前节点,则将有孩子压入栈中;否则将辅助指针指向的元素,即栈顶元素,赋给当前节点,并弹出栈顶元素,输出。

package algorithm.section5;

import java.util.Stack;

public class PreInPosTraversal {
    public static class Node{
        public int value;
        public Node left;
        public Node right;

        public Node(int value){
            this.value = value;
        }
    }

    public static void preOrderRecur(Node head){
        if (head == null) return;
        System.out.print(head.value + " ");
        preOrderRecur(head.left);
        preOrderRecur(head.right);
    }

    public static void inOrderRecur(Node head){
        if (head == null) return;
        inOrderRecur(head.left);
        System.out.print(head.value + " ");
        inOrderRecur(head.right);
    }

    public static void posOrderRecur(Node head){
        if (head == null) return;
        posOrderRecur(head.left);
        posOrderRecur(head.right);
        System.out.print(head.value + " ");
    }

    public static void preOrderUnRecur(Node head){
        if (head == null) return;
        Stack<Node> stack = new Stack<>();
        stack.push(head);
        while (!stack.isEmpty()){
            head = stack.pop();
            System.out.print(head.value + " ");
            if (head.right != null)
                stack.push(head.right);
            if (head.left != null)
                stack.push(head.left);
        }
    }

    public static void inOrderUnRecur(Node head){
        if (head == null) return;
        Stack<Node> stack = new Stack<>();
        while (!stack.isEmpty() || head != null){
            if (head != null){
                stack.push(head);
                head = head.left;
            } else {
                head = stack.pop();
                System.out.print(head.value + " ");
                head = head.right;
            }
        }
    }

    public static void posOrderUnRecur1(Node head){
        if (head == null) return;
        Stack<Node> stack1 = new Stack<>();
        Stack<Node> stack2 = new Stack<>();
        stack1.push(head);

        while (!stack1.isEmpty()){
            head = stack1.pop();
            stack2.push(head);
            if (head.left != null)
                stack1.push(head.left);
            if (head.right != null)
                stack1.push(head.right);
        }
        while (!stack2.isEmpty())
            System.out.print(stack2.pop().value + " ");
    }

    public static void posOrderUnRecur2(Node head){
        if (head == null) return;
        Stack<Node> stack = new Stack<>();
        stack.push(head);

        Node flag;

        while (!stack.isEmpty()){
            flag = stack.peek();
            if (flag.left != null && head != flag.right && head != flag.left){
                stack.push(flag.left);
            } else if (head != flag.right && flag.right != null){
                stack.push(flag.right);
            } else {
                head = flag;
                System.out.print(flag.value + " ");
                stack.pop();
            }
        }
    }

    public static void main(String[] args){
        Node head = new Node(5);
        head.left = new Node(3);
        head.right = new Node(8);
        head.left.left = new Node(2);
        head.left.right = new Node(4);
        head.left.left.left = new Node(1);
        head.right.left = new Node(7);
        head.right.left.left = new Node(6);
        head.right.right = new Node(10);
        head.right.right.left = new Node(9);
        head.right.right.right = new Node(11);

        System.out.println("==============recursive==============");
        System.out.print("pre-order: ");
        preOrderRecur(head);
        System.out.println();
        System.out.print("in-order: ");
        inOrderRecur(head);
        System.out.println();
        System.out.print("pos-order: ");
        posOrderRecur(head);
        System.out.println();

        // unrecursive
        System.out.println("============unrecursive=============");
        preOrderUnRecur(head);
        System.out.println();
        inOrderUnRecur(head);
        System.out.println();
        posOrderUnRecur1(head);
        System.out.println();
        posOrderUnRecur2(head);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值