java实现二叉树

参考:二叉树就这么简单数据结构(二)之二叉树

 

public class BinaryTree {
    //根节点
    private Node root;
    /**
     * 树的结点
     */
    private static class Node{
        //数据域
        private  int data;
        //左子结点
        private Node leftChild;
        //右子结点
        private Node rightChild;
        Node( int data){
            this.data = data;
        }
    }

    /**
     * 插入结点
     * @param data
     */
    public void insert( int data){
        Node newNode = new Node(data);
        Node currNode = root;
        Node parentNode;
        //如果是空树
        if(root == null){
            root = newNode;
            return;
        }
        while(true){
            parentNode = currNode;
            //向右搜寻
            if(data > currNode.data){
                currNode = currNode.rightChild;
                if(currNode == null){
                    parentNode.rightChild = newNode;
                    return;
                }
            }else{
                //向左搜寻
                currNode = currNode.leftChild;
                if(currNode == null){
                    parentNode.leftChild = newNode;
                    return;
                }
            }
        }

    }

    /**
     * 前序遍历
     * @param currNode
     */
    public void preOrder(Node currNode){
        if(currNode == null){
            return;
        }
        System.out.print(currNode.data+" ");
        preOrder(currNode.leftChild);
        preOrder(currNode.rightChild);
    }

    /**
     * 中序遍历
     * @param currNode
     */
    public void inOrder(Node currNode){
        if(currNode == null){
            return;
        }
        inOrder(currNode.leftChild);
        System.out.println(currNode.data+" ");
        inOrder(currNode.rightChild);

    }

    /**
     * 后序遍历
     * @param currNode
     */
    public void postOrder(Node currNode){
        if(currNode == null){
            return;
        }
        postOrder(currNode.leftChild);
        postOrder(currNode.rightChild);
        System.out.print(currNode.data+" ");
    }

    /**
     * 查找结点
     * @param data
     * @return
     */
    public Node find( int data){
        Node currNode = root;
        while(currNode!=null){
            if(data>currNode.data){
                currNode = currNode.rightChild;
            }else if(data<currNode.data){
                currNode = currNode.leftChild;
            }else{
                return currNode;
            }
        }
        System.out.println("无此节点"+data);
        return null;
    }

    /**
     * 删除结点 分为3种情况
     * 1.叶子结点
     * 2.该节点有一个子节点
     * 3.该节点有二个子节点
     * @param data
     */
    public boolean delete( int data){
        Node curr = root;
        //保持一个父节点的引用
        Node parent = curr;
        //删除结点是左子结点还是右子结点,
        boolean isLeft = true;
        while(curr != null && curr.data!=data){
            parent = curr;
            if(data > curr.data){
                curr = curr.rightChild;
                isLeft = false;
            }else{
                curr = curr.leftChild;
                isLeft = true;
            }
        }
        if(curr==null){
            System.out.println("要删除的结点"+data+"不存在");
        }
        //第一种情况,要删除的结点为叶子结点
        if(curr.leftChild == null && curr.rightChild == null){
            if(curr == root){
                root = null;
                return true;
            }
            if(isLeft){
                parent.leftChild = null;
            }else{
                parent.rightChild = null;
            }
        }else if(curr.leftChild == null){
            //第二种情况,要删除的结点有一个子节点且是右子结点
            if(curr == root){
                root = curr.rightChild;
                return true;
            }
            if(isLeft){
                parent.leftChild = curr.rightChild;
            }else{
                parent.rightChild = curr.rightChild;
            }
        }else if(curr.rightChild == null){
            //第二种情况,要删除的结点有一个子节点且是左子结点
            if(curr == root){
                root = curr.leftChild;
                return true;
            }
            if(isLeft){
                parent.leftChild = curr.leftChild;
            }else{
                parent.rightChild = curr.leftChild;
            }
        }else{
            //第三种情况,也是最复杂的一种情况,要删除的结点有两个子节点,需要找寻中序后继结点
            Node succeeder = getSucceeder(curr);
            if(curr == root){
                root = succeeder;
                return  true;
            }
            if(isLeft){
                parent.leftChild = succeeder;
            }else{
                parent.rightChild = succeeder;
            }


        }
        return true;
    }
    public Node getSucceeder(Node delNode){
        Node succeeder = delNode;
        Node parent = delNode;
        Node currNode = delNode.rightChild;
        //寻找后继结点
        while(currNode != null){
            parent = succeeder;
            succeeder = currNode;
            currNode = currNode.leftChild;
        }
        //如果后继结点不是要删除结点的右子结点
        if(succeeder != delNode.rightChild){
            parent.leftChild = succeeder.rightChild;
            //将后继结点的左右子结点分别指向要删除结点的左右子节点
            succeeder.leftChild = delNode.leftChild;
            succeeder.rightChild = delNode.rightChild;
        }else{
            //当后继结点为删除结点的右子结点
            succeeder.leftChild = delNode.leftChild;
        }
        return succeeder;

    }

    public int getHeight(Node treeNode) {

        if (treeNode == null) {
            return 0;
        } else {

            //左边的子树深度
            int left = getHeight(treeNode.leftChild);

            //右边的子树深度
            int right = getHeight(treeNode.rightChild);


            int max = left;

            if (right > max) {
                max = right;
            }
            return max + 1;
        }
    }

    /**
     * 找出树的最大值
     *
     * @param rootTreeNode
     */
    public  int  getMax(Node rootTreeNode) {

        if (rootTreeNode == null) {
            return -1;
        } else {
            //找出左边的最大值
            int left = getMax(rootTreeNode.leftChild);

            //找出右边的最大值
            int right = getMax(rootTreeNode.rightChild);

            //与当前根节点比较
            int currentRootValue = rootTreeNode.data;

            //假设左边的最大
            int max = left;


            if (right > max) {
                max = right;
            }
            if (currentRootValue > max) {
                max = currentRootValue;
            }

            return max ;


        }
    }

    public static void main(String []args) throws Exception {
        BinaryTree binaryTree = new BinaryTree();
        //插入操作
        binaryTree.insert(5);
        binaryTree.insert(3);
        binaryTree.insert(1);
        binaryTree.insert(8);
        //前序遍历
        System.out.println("前序遍历:");
        binaryTree.preOrder(binaryTree.root);
        System.out.println();
        //中序遍历
        System.out.println("中序遍历:");
        binaryTree.inOrder(binaryTree.root);
        System.out.println();
        //后序遍历
        System.out.println("后序遍历:");
        binaryTree.postOrder(binaryTree.root);
        System.out.println();
        //查找结点
        Node node = binaryTree.find(5);
        if(node!=null){
            System.out.println("找到结点,其值为:"+node.data);
        }
        //删除结点
        binaryTree.delete(5);
        System.out.println("删除结点,中序遍历:");
        binaryTree.inOrder(binaryTree.root);

        System.out.println("树的深度:"+binaryTree.getHeight(binaryTree.root));
        System.out.println("树的最大值:"+binaryTree.getMax(binaryTree.root));
    }
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值