二叉树


在这里插入图片描述
对上面的二叉树完成以下操作:
1.前序遍历(递归)
2.中序遍历(递归)
3.后续遍历(递归)
4.中序遍历非递归(借助栈)
5.按照层次遍历(借助队列)
6.在二叉树中查找某个值
7.二叉树的高/深度
8.二叉树的节点数量


代码实现

接口,待实现的方法

package cn.helele.algorithm;

public interface BinaryTree {

    /**
     * 节点是否为空
     * @return
     */
    boolean isEmpty();

    /**
     * 前序遍历:根-左子树-右子树
     */
    void preOrderTraverse();

    /**
     * 中序遍历:左子树-根-右子树
     */
    void inOrderTraverse();

    /**
     * 后序遍历:左子树-右子树-根
     */
    void postOrderTraverse();

    /**
     * 获取二叉树的高度
     */
    int getBinaryTreeHeight();

    /**
     * 二叉树的节点数量
     * @return
     */
    int getSize();

    /**
     * 在二叉树中查找某个值
     * @param i
     * @return
     */
    Node findKey(int i);

    void levelOrderByStack();

    /**
     * 中序遍历非递归(借助栈)
     */
    void inOrderByStack();
}

需要的实体类

package cn.helele.algorithm;

public class Node {
    private Object value;
    private Node leftChild;//左子树
    private Node rightChild;//右子树

    public Node() {
    }

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

    public Node(Object value, Node leftChild, Node rightChild) {
        this.value = value;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
    }

    public Object getValue() {
        return value;
    }

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

    public Node getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(Node leftChild) {
        this.leftChild = leftChild;
    }

    public Node getRightChild() {
        return rightChild;
    }

    public void setRightChild(Node rightChild) {
        this.rightChild = rightChild;
    }

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

核心实现类

package cn.helele.algorithm;

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

public class LinkedBinaryTree implements BinaryTree {

    private Node node;

    public Node getNode() {
        return node;
    }

    public void setNode(Node node) {
        this.node = node;
    }

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

    @Override
    public boolean isEmpty() {
        return this.node.getValue() == null;
    }

    @Override
    public void preOrderTraverse() {
        if (node != null) {
            // 根-左子树-右子树

            // 1.输出当前节点的值
            System.out.print(node.getValue() + " ");

            // 2.对左子树进行遍历
            // 构建一棵左子树
            BinaryTree leftChild = new LinkedBinaryTree(node.getLeftChild());
            leftChild.preOrderTraverse();

            // 3.对右子树进行遍历
            // 构建一棵右子树
            BinaryTree rightChild = new LinkedBinaryTree(node.getRightChild());
            rightChild.preOrderTraverse();
        }

        // 重构之后的代码
//        preOrderTraverse(node);
    }

    private void preOrderTraverse(Node node) {
        if (node != null) {
            System.out.print(node.getValue() + " ");

            preOrderTraverse(node.getLeftChild());

            preOrderTraverse(node.getRightChild());
        }
    }

    @Override
    public void inOrderTraverse() {
        System.out.println("\n中序遍历:");
        this.inOrderTraverse(node);
        System.out.println();
    }

    private void inOrderTraverse(Node node) {
        if (node != null) {
            // 左子树-根-右子树

            // 左子树
            this.inOrderTraverse(node.getLeftChild());

            // 根
            System.out.print(node.getValue() + " ");

            // 右子树
            this.inOrderTraverse(node.getRightChild());
        }
    }

    @Override
    public void postOrderTraverse() {
        System.out.println("\n后序遍历:");
        postOrderTraverse(node);
    }

    private void postOrderTraverse(Node node) {
        if (node != null) {
            // 后序遍历:左子树-右子树-根
            // 遍历左子树
            postOrderTraverse(node.getLeftChild());

            // 遍历右子树
            postOrderTraverse(node.getRightChild());

            // 根
            System.out.print(node.getValue() + " ");
        }
    }

    @Override
    public int getBinaryTreeHeight() {
        System.out.println("\n\n二叉树的高度是:");
        return getBinaryTreeHeight(node);
    }

    private int getBinaryTreeHeight(Node node) {
        if (node == null) {
            return 0;
        } else {
            // 获取左子树的高度
            int nodeLeft = getBinaryTreeHeight(node.getLeftChild());
            // 获取右子树的高度
            int nodeRight = getBinaryTreeHeight(node.getRightChild());
            // 返回左子树、右子树较大高度+1
            return nodeLeft > nodeRight ? nodeLeft + 1 : nodeRight + 1;
        }
    }

    @Override
    public int getSize() {
        System.out.println("\n二叉树的节点数量是:");
        return getSize(node);
    }

    private int getSize(Node node) {
        if (node == null) {
            return 0;
        } else {
            int nodeLeft = getSize(node.getLeftChild());
            int nodeRight = getSize(node.getRightChild());
            return nodeLeft + nodeRight + 1;
        }
    }

    @Override
    public Node findKey(int i) {
        System.out.println("\n\n在二叉树中查找:" + i);
        return findKey(i, node);
    }

    private Node findKey(int i, Node node) {
        if (node == null) {
            return null;
        } else {
            int nodeValue = ObjToInt(node.getValue());
            if (nodeValue == i) {
                return node;
            }
            Node nodeLeft = findKey(i, node.getLeftChild());
            Node nodeRight = findKey(i, node.getRightChild());
            if (nodeLeft != null && ObjToInt(nodeLeft.getValue()) == i) {
                return nodeLeft;
            }
            if (nodeRight != null && ObjToInt(nodeRight.getValue()) == i) {
                return nodeRight;
            }
        }
        return null;
    }

    private int ObjToInt(Object value) {
        return Integer.valueOf(value.toString());
    }

    @Override
    public void levelOrderByStack() {
        System.out.println("\n\n按照层次遍历(借助队列):");
        if(node == null) return;
        Queue<Node> queue = new LinkedList<Node>();
        queue.add(node);
        while(queue.size()!=0){
            int len = queue.size();
            // 队列长度是多少就循环几次
            for(int i = 0;i < len;i++){
                Node temp = queue.poll(); //poll 出队
                System.out.print(temp.getValue() + " ");
                if(temp.getLeftChild()!=null) queue.add(temp.getLeftChild());
                if(temp.getRightChild()!=null) queue.add(temp.getRightChild());
            }
        }
    }

    @Override
    public void inOrderByStack() {
        System.out.println("\n\n中序非递归遍历:");
        // 创建栈
        Deque<Node> stack = new LinkedList<Node>();
        Node current = node;
        while(current!=null||!stack.isEmpty()){
            while(current!=null){
                stack.push(current);
                current = current.getLeftChild();
            }

            if(!stack.isEmpty()){
                current = stack.pop();
                System.out.print(current.getValue() + " ");
                current = current.getRightChild();
            }
        }
    }

}


测试类

package cn.helele.algorithm;

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 node3 = new Node(3, null, null);
        Node node7 = new Node(7, null, null);
        Node node6 = new Node(6, null, node7);
//        Node node6 = new Node(6, null, null);
        Node node2 = new Node(2, node3, node6);
        Node node1 = new Node(1, node4, node2);

//        先序遍历DLR: 1 4 5 2 3 6 7
//        中序遍历LDR: 4 5 1 3 2 6 7
//        后序遍历LRD: 5 4 3 7 6 2 1

        BinaryTree binaryTree = new LinkedBinaryTree(node1);

        //判断二叉树是否为空
        boolean isEmpty = binaryTree.isEmpty();
        System.out.println("是否是一棵空树:" + isEmpty);

        //先序遍历递归
        System.out.println("前序遍历:");
        binaryTree.preOrderTraverse();
        System.out.println();

        //中序遍历递归
        binaryTree.inOrderTraverse();

        //后续遍历递归
        binaryTree.postOrderTraverse();

        // 中序遍历非递归(借助栈)
        binaryTree.inOrderByStack();

        // 按照层次遍历(借助队列)
        binaryTree.levelOrderByStack();

        // 在二叉树中查找某个值
        System.out.println(binaryTree.findKey(4));

        // 二叉树的高度
        int binaryTreeHeight = binaryTree.getBinaryTreeHeight();
        System.out.println(binaryTreeHeight);

        // 二叉树的节点数量
        int size = binaryTree.getSize();
        System.out.println(size);
    }
}

结果值

在这里插入图片描述

分析

按照层次遍历(借助队列)

结果:1 4 2 5 3 6 7
poll 出队
add 入队
在这里插入图片描述
在这里插入图片描述

中序遍历非递归(借助栈)

结果:4 5 1 3 2 6 7
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值