Java实现二叉树

数据结构


Java实现二叉树

前言

本篇主要介绍二叉树的概念、二叉树的表示、二叉树的操作(三种遍历方式实现、求二叉树的子树、求节点的父节点、二叉树高度…这些方式都是通过递归发方式实现的


//二叉树的数据结构
public class BinaryTreeNode<T> {
    private T data;
    private BinaryTreeNode<T> leftChild;    //左孩子
    private BinaryTreeNode<T> rightChild;   //右孩子

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public BinaryTreeNode getLeftChild() {
        return leftChild;
    }

    public BinaryTreeNode getRightChild() {
        return rightChild;
    }

    public void setLeftChild(BinaryTreeNode<T> leftChild) {
        this.leftChild = leftChild;
    }

    public void  setRightChild(BinaryTreeNode<T> rightChild) {
        this.rightChild = rightChild;
    }
}
public class BinaryTree<T> {

    private BinaryTreeNode<T> root; //根结点

    /**
     * 初始化二叉树
     * @param root
     */
    public BinaryTree (BinaryTreeNode<T> root) {
        this.root = root;
    }

    public void setRoot(BinaryTreeNode<T> root) {
        this.root = root;
    }

    public BinaryTreeNode<T> getRoot() {
        return root;
    }

    /**
     * 二叉树的清空
     * 1.递归遍历清空每个结点
     * 2.直接删除树根
     */
    public void clear(BinaryTreeNode node) {
        if (node != null) {
            clear(node.getLeftChild());
            clear(node.getRightChild());
            node = null;    //删除结点
        }
    }

    public void clear() {
        clear(root);
    }

    //判空树
    public boolean isEmpty() {
        return root == null;
    }

    /**
     * 求二叉树的高度
     * 首先要一种获取以某个节点为子树的高度的方法,使用递归调用。
     * 如果一个节点为空,那么这个节点肯定是一颗空树,高度为0;
     * 如果不为空,那么我们要遍历地比较它的左子树高度和右子树高度,
     * 高的一个为这个子树的最大高度然后加上自己本身的高度就是了
     * 获取二叉树的高度,只需要调用第一种方法,即传入根节点
     */
    public int height() {
        return height(root);
    }

    private int height(BinaryTreeNode<T> node) {
        if (node == null) {
            return 0;
        } else {
            //递归获取左子树的高度
            int leftHeight = height(node.getLeftChild());

            //递归获取右子树的高度
            int rightHeight = height(node.getRightChild());

            //要算上自身的这一层
            return leftHeight > rightHeight ? (leftHeight+1) : (rightHeight+1);
        }
    }

    /**
     * 获取二叉树的结点树
     * 需要获取以某个节点为根的子树的节点数实现,
     * 如果节点为空,则个数肯定为0;如果不为空,
     * 则算上这个节点之后,继续递归计算所有子树的节点数,全部相加即可
     */
    public int size() {
        return size(root);
    }

    private int size(BinaryTreeNode<T> node) {
        if (node == null) {
            return 0;
        } else {
            //要计算本结点,因此需要+1,
            return 1+size(node.getLeftChild()) +size(node.getRightChild());
        }
    }

    /**
     * 返回左右子树
     */
    public BinaryTreeNode<T> getLeftTree(BinaryTreeNode<T> node) {
        return node.getLeftChild();
    }

    public BinaryTreeNode<T> getRightTree(BinaryTreeNode<T> node) {
        return node.getRightChild();
    }

    /**
     * 二叉树结点的插入
     * 值得指出的是,当这个节点本身有子节点时,这样的插入也会覆盖原来在这个位置上的节点。
     * 另外,虽然插入的是子节点,但是子节点也可以代表一颗子树。
     * 因为但从这个节点来看并不知道这个节点是否有左右子树存在,所以虽然插入的是一个节点,但有可能
     * 插入可很多节点(插入的是一颗子树)
     */
    public void insertLeftNode(BinaryTreeNode<T> parent, BinaryTreeNode<T> node) {
        parent.setLeftChild(node);
    }

    public void insertRightNode(BinaryTreeNode<T> parent, BinaryTreeNode<T> node) {
        parent.setRightChild(node);
    }

    /**
     * 二叉树的遍历
     * 1.先序遍历   (根左右)
     * 2.中序遍历   (左根右)
     * 3.后序遍历   (左右根)
     */
    public void PreOrder(BinaryTreeNode<T> node) {
        if (node != null) {
            System.out.print(node.getData()+","); //先访问根结点
            PreOrder(node.getLeftChild());      //先根遍历左子树
            PreOrder(node.getRightChild());     //先根遍历右子树
        }
    }

    public void InOrder(BinaryTreeNode<T> node) {
        if (node != null){
            PreOrder(node.getLeftChild());      //先根遍历左子树
            System.out.print(node.getData()+","); //先访问根结点
            PreOrder(node.getRightChild());     //先根遍历右子树
        }
    }

    public void PostOrder(BinaryTreeNode<T> node) {
        if (node != null) {
            PreOrder(node.getLeftChild());      //先根遍历左子树
            PreOrder(node.getRightChild());     //先根遍历右子树
            System.out.print(node.getData()+","); //先访问根结点
        }
    }

    public static void main(String[] args) {
        BinaryTreeNode<String> nodeA = new BinaryTreeNode<>();
        nodeA.setData("A");

        BinaryTreeNode<String> nodeB = new BinaryTreeNode<>();
        nodeB.setData("B");
        nodeA.setLeftChild(nodeB);

        BinaryTreeNode<String> nodeC = new BinaryTreeNode<>();
        nodeC.setData("C");
        nodeA.setRightChild(nodeC);

        BinaryTreeNode<String> nodeD = new BinaryTreeNode<>();
        nodeD.setData("D");
        nodeB.setLeftChild(nodeD);

        BinaryTreeNode<String> nodeE = new BinaryTreeNode<>();
        nodeE.setData("E");
        nodeB.setRightChild(nodeE);

        BinaryTreeNode<String> nodeF = new BinaryTreeNode<>();
        nodeF.setData("F");
        nodeC.setLeftChild(nodeF);

        BinaryTreeNode<String> nodeG = new BinaryTreeNode<>();
        nodeG.setData("G");
        nodeC.setRightChild(nodeG);

        BinaryTree<String> tree = new BinaryTree<>(nodeA);
        System.out.println("这个树的的高度是: "+tree.height());

        System.out.print("先序遍历的结果是: ");
        tree.PreOrder(nodeA);

        System.out.print("\n"+"中序遍历的结果是: ");
        tree.InOrder(nodeA);

        System.out.print("\n"+"后序遍历的结果是: ");
        tree.PostOrder(nodeA);
    }
}

Alt

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值