二叉树的前序遍历/中序遍历/前序遍历(递归和非递归分别实现代码)

LinkedBinaryTree 具体实现代码
package c.cn.com.demo03;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

public class LinkedBinaryTree implements BinaryTree {

    private Node root;

    public LinkedBinaryTree(){
    }

    public LinkedBinaryTree(Node root) {
        this.root = root;
    }

    /**
     * 是否空树
     *
     * @return
     */
    @Override
    public boolean isEmpty() {
        return null == root;
    }

    /**
     * 树结点数量
     *
     * @return
     */
    @Override
    public int size() {
        return this.size(root);
    }

    private int size(Node node) {
        if(node == null){
            return 0;
        }
        int left = this.size(node.left);
        int right = this.size(node.right);
        return (left + right + 1);
    }

    /**
     * 获取二叉树的高度
     *
     * @return
     */
    @Override
    public int getHeight() {
        return getHeight(root);
    }

    private int getHeight(Node node) {
        if(null == node){
            return 0;
        }
        //获取左子树的高度
        int leftHeight = this.getHeight(node.left);
        //获取右子树的高度
        int rightHeight = this.getHeight(node.right);
        //返回左子树 右子树较大的高度并加1
        return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
    }

    /**
     * 查询指定值的结点
     *
     * @param value
     * @return
     */
    @Override
    public Node findKey(int value) {
        return findKey(value,root);
    }

    public Node findKey(int value, Node node) {
        if(null == node){
            return null;
        }else if(null != node && value == node.value){
            return node;
        }else{
            Node node1 = this.findKey(value, node.left);
            Node node2 = this.findKey(value, node.right);
            if(node1 != null && node1.value == value){
                return node1;
            }else if(node2 != null && node2.value == value){
                return node2;
            }else{
                return null;
            }
        }
    }

    /**
     * 前序递归遍历
     */
    @Override
    public void preOrderTraverse() {
        if(root != null){
            //输出根节点的value
            System.out.printf(root.value + " ");
            //对左子树进行遍历, 根是左子树的根
            LinkedBinaryTree left = new LinkedBinaryTree(root.left);
            left.preOrderTraverse();
            //对右子树进行遍历, 根是右子树的根
            LinkedBinaryTree right = new LinkedBinaryTree(root.right);
            right.preOrderTraverse();
        }
    }

    /**
     * 中序遍历递归操作
     */
    @Override
    public void inOrderTraverse() {
        System.out.println("中序遍历(递归): ");
        this.inOrderTraverse(root);
        System.out.println();
    }

    private void inOrderTraverse(Node node){
        if(node != null){
            //遍历左子树 根是左子树的根
            this.inOrderTraverse(node.left);
            //输出根节点的value
            System.out.print(node.value + " ");
            //遍历右子树 根是右子树的根
            this.inOrderTraverse(node.right);
        }
    }

    /**
     * 后序遍历递归操作
     */
    @Override
    public void postOrderTraverse() {
        System.out.println("后序遍历(递归): ");
        postOrderTraverse(root);
        System.out.println();
    }

    /**
     * 后序遍历递归操作
     * @param node 树根结点
     */
    @Override
    public void postOrderTraverse(Node node) {
        if( null != node ){
            //遍历左子树
            this.postOrderTraverse(node.left);
            //遍历右子树
            this.postOrderTraverse(node.right);
            //输出根节点值
            System.out.print(node.value + " ");
        }
    }

    /**
     * 二叉树结构
     *            1
     *        4      2
     *          5  3   6
     *                  7
     */
    /**
     * 中序遍历非递归操作
     * 1)对于任意节点current,若该节点不为空则将该节点压栈,并将左子树节点置为current,重复此操作,直到current为空。
     * 2)若左子树为空,栈顶节点出栈,访问节点后将该节点的右子树置为current
     * 3) 重复1、2步操作,直到current为空且栈内节点为空。
     */
    @Override
    public void inOrderByStack() {
        Deque<Node> stack = new LinkedList<>();
        Node current = root;
        while(current != null || !stack.isEmpty()){
            while(current != null){
                stack.push(current);
                current = current.left;
            } //代码执行到这的时候  stack中的值 :  4  1(栈底)
            if(!stack.isEmpty()){
                current = stack.poll();
                System.out.print(current.value + " ");
                current = current.right;
            }
        }
    }

    /**
     * 二叉树结构
     *            1
     *        4      2
     *          5  3   6
     *                  7
     */
    /**
     * 前序遍历非递归操作
     * 1)对于任意节点current,若该节点不为空则访问该节点后再将节点压栈,并将左子树节点置为current,重复此操作,直到current为空。
     * 2)若左子树为空,栈顶节点出栈,将该节点的右子树置为current
     * 3) 重复1、2步操作,直到current为空且栈内节点为空。
     */
    @Override
    public void preOrderByStack() {
        Deque<Node> stack = new LinkedList<>();
        Node current = root;
        while(current != null || !stack.isEmpty()){
            while(current != null){
                stack.push(current);
                System.out.print(current.value + " ");
                current = current.left;
            }
            if(!stack.isEmpty()){
                current = stack.poll();
                current = current.right;
            }
        }
    }

    /**
     * 后序遍历非递归操作
     * 1)对于任意节点current,若该节点不为空则访问该节点后再将节点压栈,并将左子树节点置为current,重复此操作,直到current为空。
     * 2)若左子树为空,取栈顶节点的右子树,如果右子树为空或右子树刚访问过,则访问该节点,并将preNode置为该节点
     * 3) 重复1、2步操作,直到current为空且栈内节点为空。
     */
    @Override
    public void postOrderByStack() {
        Deque<Node> stack = new LinkedList<>();
        Node current = root;
        Node preNode = null;
        while(current != null || !stack.isEmpty()){
            while(current != null){
                stack.push(current);
                current = current.left;
            }
            if(!stack.isEmpty()){
                current = stack.peek().right;
                if(current == null || current == preNode){
                    current = stack.poll();
                    System.out.print(current.value + " ");
                    preNode = current;
                    current = null;
                }
            }
        }

    }

    /**
     * 按照层次遍历二叉树
     */
    @Override
    public void levelOrderByStack() {
        if(root == null){
            return;
        }
        //创建队列
        Queue<Node> queue = new LinkedList<>();
        //将根节点 第一层加入 队列中
        queue.offer(root);
        while(queue.size() > 0){
            int len = queue.size();
            for(int i = 0;i < len;i++){
                //取出队列中的第一个值,并删掉
                Node node = queue.poll();
                System.out.print(node.value + " ");
                //如果这个节点的左节点不为空,则将该节点的左节点加入队列中
                if(node.left != null){
                    queue.offer(node.left);
                }
                //如果这个节点的右节点不为空,则将该节点的右节点加入队列中
                if(node.right != null){
                    queue.offer(node.right);
                }
            }
        }
        System.out.println();
    }
}

Node节点
package c.cn.com.demo03;

public class Node {

    int value;
    Node left;
    Node right;

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                ", left=" + left +
                ", right=" + right +
                '}';
    }

    public Node() {
    }

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

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

    public Object getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    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;
    }
}

Test测试
package c.cn.com.demo03;

import java.util.Arrays;

public class Test {

    public static void main(String[] args) {

        //1.创建二叉树
        //左子树
        Node node5 = new Node(5,null,null);
        Node node4 = new Node(4,null,node5);
        //右子树
        Node node7 = new Node(7,null,null);
        Node node6 = new Node(6, null,node7);
//        Node node6 = new Node("6", null,null);
        Node node3 = new Node(3,null,null);
        Node node2 = new Node(2,node3,node6);
        //根节点
        Node node1 = new Node(1,node4,node2);
//        Node node1 = new Node("1",null,null);
        LinkedBinaryTree tree = new LinkedBinaryTree(node1);

        //2.判断二叉树是否为空
        boolean empty = tree.isEmpty();
        System.out.println("二叉树是否为空: " + empty);

        //3.先序遍历(递归)  1 4 5 2 3 6 7
        System.out.println("先序遍历(递归): ");
        tree.preOrderTraverse();
        System.out.println();

        //4.中序遍历(递归)  4 5 1 3 2 6 7
        tree.inOrderTraverse();

        //5.后续遍历(递归)  5 4 3 7 6 2 1
        tree.postOrderTraverse();

        //6.树的高度
        System.out.println("树的高度: " + tree.getHeight());

        //7.树的节点个数
        System.out.println("树的节点个数: " + tree.size());

        //8.查询是否有某个节点
        Node node = tree.findKey(1);
        System.out.println(node);

        //9.按照层次遍历二叉树  1 4 2 5 3 6 7
        System.out.println("树按照层次遍历二叉树: ");
        tree.levelOrderByStack();

        //10.中序遍历非递归操作 左 根 右 4 5 1 3 2 6 7
        System.out.println("中序遍历非递归操作: ");
        tree.inOrderByStack();
        System.out.println();

        //11.前序遍历非递归操作 根 左 右 1 4 5 2 3 6 7
        System.out.println("先序遍历非递归操作: ");
        tree.preOrderByStack();
        System.out.println();

        //12.后序遍历非递归操作 左 右 根 5 4 3 7 6 2 1
        System.out.println("后序遍历非递归操作: ");
        tree.postOrderByStack();

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述 给定二叉树前序遍历输出,求二叉树中序遍历输出。 示例 输入:[3,9,20,null,null,15,7] 输出:[9,3,15,20,7] 解题思路 根据二叉树前序遍历中序遍历可以唯一确定一颗二叉树。因此,我们可以利用前序遍历找到根节点,然后在中序遍历中找到根节点的位置,以此划分出左子树和右子树的中序遍历,然后递归处理左右子树即可。 具体实现步骤如下: - 使用递归函数实现。 - 找到前序遍历的第一个节点作为根节点。 - 在中序遍历中找到根节点的位置,以此划分出左子树和右子树的中序遍历。 - 分别递归处理左子树和右子树,并将结果保存在一个 List 中。 - 最后返回 List。 Java 代码实现 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<Integer> inorderTraversal(int[] preorder) { if (preorder == null || preorder.length == 0) { return new ArrayList<>(); } List<Integer> res = new ArrayList<>(); TreeNode root = buildTree(preorder, 0, preorder.length - 1); inorder(root, res); return res; } private TreeNode buildTree(int[] preorder, int start, int end) { if (start > end) { return null; } TreeNode root = new TreeNode(preorder[start]); int index = start; while (index <= end && preorder[index] <= preorder[start]) { index++; } root.left = buildTree(preorder, start + 1, index - 1); root.right = buildTree(preorder, index, end); return root; } private void inorder(TreeNode root, List<Integer> res) { if (root == null) { return; } inorder(root.left, res); res.add(root.val); inorder(root.right, res); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值