算法——二叉树的前序、中序、后序遍历算法 java实现

二叉树,大家都很熟悉,这里我就不解释咯。今天记录一下二叉树的三种遍历方法(递归实现和非递归实现)

首先我们先定一个棵树

代码如下:

public class Node {
    private String date;
    private Node left;
    private Node right;
    private int level = 0;      //层数

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public Node() {
    }


    public static void setTreeNodes(Node node, int level) {

        if (node.getLevel() >= 3) {
            return;
        }
        node.setDate(UUID.randomUUID().toString());
        Node left = new Node();
        left.setLevel(level + 1);

        Node right = new Node();
        right.setLevel(level + 1);

        left.setDate(UUID.randomUUID().toString());
        right.setDate(UUID.randomUUID().toString());
        node.setLeft(left);
        node.setRight(right);

        setTreeNodes(node.getLeft(), level + 1);
        setTreeNodes(node.getRight(), level + 1);

    }
    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }
}

改代码里面的静态方法是构造出一个又数据的二叉树。方便我们测试的时候使用。level属性是代表节点的层数,从0开始计算。

前序遍历:

(1)递归算法

  /**
     * 前序遍历(根 -> 左-> 右)时间复杂度为O(n),因为每个节点都要遍历。
     * @param node
     */
    public void preOrder(Node node) {
        if (node == null) {
            return;
        }
        System.out.println(node.getDate());
        //左
        preOrder(node.getLeft());
        //右
        preOrder(node.getRight());
    }

(1)非递归:

 public void preOrderNotRecursion(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        //节点入栈
        stack.push(node);
        //栈不会空的话,一直循环
        while (!stack.isEmpty()) {
            //节点出栈
            node = stack.pop();
            //因为树的叶子节点下面的左右节点为空,所有需要判断null
            if (node == null) {
                continue;
            }
            System.out.println(node.getDate());
            //左右儿子入栈
            stack.push(node.getLeft());
            stack.push(node.getRight());

        }
    }

中序遍历

(1)递归算法

  /**
     * 中序遍历 (左 -> 根 -> 右)
     * @param node
     */
    public void inOrder(Node node) {
        if (node == null) {
            return;
        }
        inOrder(node.getLeft());
        System.out.println(node.getDate());
        inOrder(node.getRight());
    }

(2)非递归

/**
     * 中序遍历非递归算法
     * @param node
     */
    public void inOrderNotRecursion(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        while (!stack.isEmpty() || node != null) {
            if (node != null) {
                stack.push(node);
                node = node.getLeft();
            }else{
                node = stack.pop();
                System.out.println(node.getDate());
                node = node.getRight();
            }
        }
    }

后序遍历

(1)递归算法

/**
     * 后序遍历
     * @param node
     */
    public void postOrder(Node node) {
        if (node == null) {
            return;
        }
        postOrder(node.getLeft());
        postOrder(node.getRight());
        System.out.println(node.getDate());
    }

(2)非递归算法

 public void postOrderNotRecursion(Node node) {
        if (node == null) {
            return;
        }
        //s2用于存放遍历后的节点(已排好顺序)
        Stack<Node> s1 = new Stack<>();
        Stack<Node> s2 = new Stack<>();
        s1.push(node);
        while (!s1.isEmpty()) {
            node = s1.pop();
            s2.push(node);
            if (node.getLeft() != null) {
                s1.push(node.getLeft());
            }
            if (node.getRight() != null) {
                s1.push(node.getRight());
            }
        }
        while (!s2.isEmpty()) {
            System.out.println(s2.pop().getDate());
        }

    }

测试代码:

public static void main(String[] args) {
        Node root = new Node();
        Node.setTreeNodes(root, 0);
        long start = System.currentTimeMillis();
        //new TreeOrder().preOrder(root);
        //new TreeOrder().preOrderNotRecursion(root);
        //new TreeOrder().inOrder(root);
        //new TreeOrder().inOrderNotRecursion(root);
        new TreeOrder().postOrder(root);
        System.out.println("-----------");
        new TreeOrder().postOrderNotRecursion(root);

        System.out.println("耗时:" + (System.currentTimeMillis() - start));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值