有关二叉树的学习

参考博客:https://www.cnblogs.com/ysocean/p/8032642.html
有关二叉树需要实现的功能:https://segmentfault.com/a/1190000008850005?utm_source=tag-newest


有关二叉树遍历的知识:
            中序遍历:左 -> 根 -> 右
             前序遍历:根 -> 左 -> 右
             后续遍历:左 -> 右 -> 根
在这里插入图片描述

一:定义节点类Node.java:

package xiaohongshu.ercha;

public class Node {
    int data;
    Node leftChild;
    Node rightChild;
    boolean isDelete;//表示该节点是否被删除

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

    //打印节点信息
    public void dispaly(){
        System.out.println(data);
    }
}

二:定义接口Tree.java(用来放需要实现的功能)

public interface Tree {
    //查找节点
    public Node find(int key);
    //插入新节点
    public boolean insert(int data);
    //中序遍历
    public void infixOrder(Node current);
    //前序遍历
    public void preOrder(Node current);
    //后续遍历
    public void postOrder(Node current);
    //查找最大值
    public Node findMax();
    //查找最小值
    public Node findMin();
    //删除节点
    public boolean delete(int key);
    //求树的深度
    public int getMaxDepth(Node node);
    //求某层的节点数
    public int get_cen_jieidan(Node node,int tree);
    //求二叉树的镜像
    public void qiujingxiang(Node node);
}

三:实现接口里的所有功能

public class BinaryTree implements Tree {
    //新建根节点
    private Node root;

    @Override
    public Node find(int key) {
        Node current = root;
        while (current != null) {
            if (current.data > key) {//当前值比查找的值大,搜索左子树
                current = current.leftChild;
            } else if (current.data < key) {//当前值比查找的值小,搜索右子数
                current = current.rightChild;
            } else {
                return current;
            }
        }
        return null;
    }

    /*
    插入原则:
        右子树比根大
        左子树比根小
     */
    @Override
    public boolean insert(int data) {
        Node newNode = new Node(data);
        //如果根为空则这个节点为根
        if (root == null) {
            root = newNode;
            return true;
        } else {
            Node current = root;//当前节点
            Node parentNode = null;
            while (current != null) {
                parentNode = current;
                if (current.data > data) {//当前值大于要插的值,那么放到左子树
                    current = current.leftChild;
                    if (current == null) {
                        parentNode.leftChild = newNode;
                        return true;
                    }
                } else {
                    current = current.rightChild;
                    if (current == null) {
                        parentNode.rightChild = newNode;
                        return true;
                    }
                }
            }
        }
        return false;
    }

    //中序遍历
    @Override
    public void infixOrder(Node current) {
        if (current != null) {
            infixOrder(current.leftChild);
            System.out.println(current.data + " ");
            infixOrder(current.rightChild);
        }
    }

    //前序遍历
    @Override
    public void preOrder(Node current) {
        if (current != null) {
            System.out.println(current.data + " ");
            preOrder(current.leftChild);
            preOrder(current.rightChild);
        }
    }

    //后续遍历
    @Override
    public void postOrder(Node current) {
        if (current != null) {
            postOrder(current.leftChild);
            postOrder(current.rightChild);
            System.out.print(current.data + " ");
        }
    }

    //最右下角的就是最大值
    @Override
    public Node findMax() {
        Node current = root;
        Node maxNode = null;
        while (current != null) {
            maxNode = current;
            current = current.rightChild;
        }
        return maxNode;
    }

    //最左下角的就是最下值
    @Override
    public Node findMin() {
        Node current = root;
        Node minNode = null;
        while (current != null) {
            minNode = current;
            current = current.leftChild;
        }
        return minNode;
    }

    @Override
    public boolean delete(int key) {
        Node current = root;
        Node parent = root;
        boolean isLeftChild = false;
        //查找删除的值,找不到返回false
        while (current.data != key) {
            parent = current;
            if (current.data > key) {
                isLeftChild = true;
                current = current.leftChild;
            } else {
                isLeftChild = false;
                current = current.rightChild;
            }
            if (current == null) {
                return false;
            }
        }
        //如果当前节点没有子节点
        if (current.leftChild == null && current.rightChild == null) {
            if (current == root) {
                root = null;
            } else if (isLeftChild) {
                parent.leftChild = null;
            } else {
                parent.rightChild = null;
            }
            return true;
        } else if (current.leftChild == null && current.rightChild != null) {
            if (current == root) {
                root = current.rightChild;
            } else if (isLeftChild) {
                parent.leftChild = current.rightChild;
            } else {
                parent.rightChild = current.rightChild;
            }
            return true;
        } else if (current.leftChild != null && current.rightChild == null) {
            if (current == root) {
                root = current.leftChild;
            } else if (isLeftChild) {
                parent.leftChild = current.leftChild;
            } else {
                parent.rightChild = current.leftChild;
            }
            return true;
        } else {
            //当前节点有两个子节点
            Node successor = getSuccessor(current);
            if (current == root) {
                root = successor;
            } else if (isLeftChild) {
                parent.leftChild = successor;
            } else {
                parent.rightChild = successor;
            }
        }
        return false;
    }

    public Node getSuccessor(Node delNode) {
        Node successorParent = delNode;
        Node successor = delNode;
        Node current = delNode.rightChild;
        while (current != null) {
            successorParent = successor;
            successor = current;
            current = current.leftChild;
        }
        if (successor != delNode.rightChild) {
            successorParent.leftChild = successor.rightChild;
            successor.rightChild = delNode.rightChild;
        }
        return successor;
    }

    //求深度
    @Override
    public int getMaxDepth(Node node) {
        if (node == null) {
            return 0;
        } else {
            int left = getMaxDepth(node.leftChild);
            int right = getMaxDepth(node.rightChild);
            return 1 + Math.max(left, right);
        }
    }
    //求某层的节点数

    /**
     * 思路:求第四层的深度时,我先求第三层,求第三层我就先求第二层
     *
     * @param node
     * @param tree
     * @return
     */
    @Override
    public int get_cen_jieidan(Node node, int tree) {
        if (node == null || tree < 1) {
            return 0;
        }
        if (tree == 1) {
            return 1;
        }
        int left_num = get_cen_jieidan(node.leftChild, tree - 1);
        int right_num = get_cen_jieidan(node.rightChild, tree - 1);
        return left_num + right_num;
    }

    //求二叉树的镜像
    @Override
    public void qiujingxiang(Node node) {
        if (node == null || node.leftChild == null && node.rightChild == null) {
            return;
        }
        Node tempNode = node.leftChild;
        node.leftChild = node.rightChild;
        node.rightChild = tempNode;
        if (node.leftChild != null) {
            qiujingxiang(node.leftChild);
        }
        if (node.rightChild != null) {
            qiujingxiang(node.rightChild);
        }

    }

    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.insert(50);
        bt.insert(20);
        bt.insert(80);
        bt.insert(10);
        bt.insert(30);
        bt.insert(60);
        bt.insert(90);
        bt.insert(25);
        bt.insert(85);
        bt.insert(100);
      /*  bt.delete(10);//删除没有子节点的节点
        bt.delete(30);//删除有一个子节点的节点
        bt.delete(80);//删除有两个子节点的节点*/
       /* System.out.println(bt.findMax().data);
        System.out.println(bt.findMin().data);
        System.out.println(bt.find(100));
        System.out.println(bt.find(200));*/
        bt.postOrder(bt.root);
        bt.qiujingxiang(bt.root);
        System.out.println();
        bt.postOrder(bt.root);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值