撸代码之二叉树算法

二叉树节点定义:

    class Node {
        public int val;
        public Node left;
        public Node right;

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

        public static Node buildTree() {
            Node root = new Node(1);
            Node node1 = new Node(2);
            Node node2 = new Node(3);
            root.left = node1;
            root.right = node2;
            node1.left = new Node(4);
            node1.right = new Node(5);
            node2.left = new Node(6);
            node2.right = new Node(7);
            return root;
        }
    }

先序遍历:

public static void preOrder1(Node root) {
        if (root == null)
            return;
        System.out.print(root.val + "  ");
        preOrder1(root.left);
        preOrder1(root.right);
    }
    
    public static void preOrder2(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        while (node != null || !stack.isEmpty()) {
            while (node != null) {// 一路向左
                System.out.print(node.val + "  ");
                stack.push(node);
                node = node.left;
            }
            //此处可以理解为递归遍地右子树
            node = stack.pop().right;
        }
    }



    public static void preOrder3(Node node) {
        Stack<Node> s = new Stack<>();
        while (node != null || !s.isEmpty()) {
            if (node != null) {
                System.out.print(node.val + "  ");
                node = node.left;
            } else {
                node = s.pop();
                s.push(node);
            }
        }
    }

中序遍历:

    /**
     * 跟前序遍历很相似,就是打印节点值的位置不同
     * @param node
     */
    public static void inOrder(Node node) {
        Stack<Node> s = new Stack<>();
        while (node != null || !s.isEmpty()) {
            while (node != null) {
                s.push(node);
                node = node.left;
            }
            node = s.pop();
            System.out.print(node.val + "  ");
            node = node.right;
        }
    }

后序遍历:

package bintree;


import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.Stack;

class Node {

    public int val;
    public Node left;
    public Node right;


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Node node = (Node) o;
        return val == node.val &&
                Objects.equals(left, node.left) &&
                Objects.equals(right, node.right);
    }

    @Override
    public int hashCode() {
        return Objects.hash(val, left, right);
    }

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

    public static Node buildTree() {
        Node root = new Node(1);
        Node node1 = new Node(2);
        Node node2 = new Node(3);
        root.left = node1;
        root.right = node2;
        node1.left = new Node(4);
        node1.right = new Node(5);
        node2.left = new Node(6);
        node2.right = new Node(7);
        return root;
    }
}


public class Main {

    public static void main(String[] args) {

        Node node = Node.buildTree();
        post(node);
        System.out.println();
        postTree(node);

    }

    public static void postTree(Node node) {
        if (Objects.isNull(node)) {
            return;
        }
        // 用于回溯的栈
        Stack<Node> stack = new Stack<>();
        // 用于存储已经遍历过的节点
        Set<Node> visited = new HashSet<>();//重写Node hashcode与equals方法
        stack.push(node);
        // 后序遍历打印节点的值都是打印的栈中的,因此只要判断栈不空则就是没有遍历结束
        while (!stack.isEmpty()) {
            node = stack.peek();
            // 当前节点的左节点不空而且该节点没有被遍历过
            while (Objects.nonNull(node.left) && !visited.contains(node.left)) {
                //存储到栈中,继续向下走
                stack.push(node.left);
                node = node.left;
            }
            // 此时已经走到了最左边了,开始回溯一个节点向右子树走
            node = stack.peek();
            // 右节点不空而且没有遍历过则添加到队列中
            if (Objects.nonNull(node.right) && !visited.contains(node.right)) {
                node = stack.peek().right;
                stack.push(node);
                // 此时可以将右节点看做一颗子树,从新开始以后序遍历的方式遍历该子树
                continue;
            }
            //左右子树为空或者左右子树已经遍历完毕
            node = stack.pop();
            visited.add(node);
            System.out.print(node.val + "   ");
        }
    }

    public static void post(Node node) {
        if (Objects.isNull(node)) {
            return;
        }
        post(node.left);
        post(node.right);
        System.out.print(node.val + "   ");
    }
}

 

转载于:https://my.oschina.net/daxin/blog/1822104

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值