基于Java的二叉树实现

来源:互联网 发布:淘宝购物,如何返利? 编辑:程序博客网 时间:2024/05/21 04:43

简介:二叉搜索树的插入与删除图解_Linux编程_Linux公社-Linux系统门户网站

1.node

public class Node {    public int data;    public Node leftChild;//左子树    public Node rightChild;//右子树    public Node(int data) {        this.data = data;        leftChild = null;        rightChild = null;    }}

2.MyTree

public class MyTree {    private Node root;    /*增*/    public void insert(int value) {        Node node = new Node(value);        if (root == null) {            root = node;//根节点        } else {            Node current = root;            Node parent = root;            while (true) {                //左小右大                if (current.data > node.data) {                    //先找左边                    parent = current;                    current = current.leftChild;                    if (current == null) {                        parent.leftChild = node;//                        System.out.println("左边插入之后current==node" + (current == node));//                        System.out.println("左边插入之后current==node" + (root.leftChild == node));                        return;                    }                } else {                    //再找右                    parent = current;                    current = current.rightChild;                    if (current == null) {                        parent.rightChild = node;//                        System.out.println("右边边插入之后current==node" + (current == node));//                        System.out.println("右边插入之后current==node" + (root.leftChild == node));                        return;                    }                }            }        }    }    /*查询*/    public Node find(int value) {        //查找        if (root == null) {            return null;        }        Node current = root;        while (current.data != value) {            if (current.data > value) {                //左边                current = current.leftChild;            } else {                current = current.rightChild;            }            if (current == null) {                return null;            }        }        return current;    }    public boolean update(int oldValue, int newValue) {        if (root == null) {            return false;        }        Node current = root;        while (current.data != oldValue) {            if (current.data > oldValue) {                current = current.leftChild;            } else {                current = current.rightChild;            }            if (current == null) {                return false;            }        }        current.data = newValue;        return true;    }    /***     * 前序遍历:根->左->右     * @param localNode     */    public void frontOrder(Node localNode) {        if (localNode == null) {            return;        } else {            System.out.print(localNode.data + " ,");            //节点的左子树            frontOrder(localNode.leftChild);            frontOrder(localNode.rightChild);        }    }    /***     * 中序遍历:左->根->右     * @param localNode     */    public void inOrder(Node localNode) {        if (localNode == null) {            return;        } else {            //节点的左子树            inOrder(localNode.leftChild);            System.out.print(localNode.data + " ,");            inOrder(localNode.rightChild);        }    }    /***     * 后序遍历:左->右->根     * @param localNode     */    public void afterOrder(Node localNode) {        if (localNode == null) {            return;        } else {            //节点的左子树            afterOrder(localNode.leftChild);            afterOrder(localNode.rightChild);            System.out.print(localNode.data + " ,");        }    }    public boolean delete(int value) {        //首先查询需要删除的节点先        if (root == null) {            return false;        }        Node current = root;        Node parent = root;        boolean isLeftChild = false;//存储被删结点是左子树还是右子树        while (current.data != value) {            parent = current;//存储当前结点,作为下一次循环的上一次结点            if (current.data > value) {                //左子树                current = current.leftChild;                isLeftChild = true;            } else {                //右子树                current = current.rightChild;                isLeftChild = false;            }            if (current == null) {                return false;            }        }        //找到那个符合条件的结点了,来到这里的current不会为空        if (current.leftChild == null && current.rightChild == null) {            //被删结点叶子结点(即是:被删结点的左子树为空,右子树也为空)            if (isLeftChild) {                parent.leftChild = null;            } else {                parent.rightChild = null;            }        } else if (current.leftChild == null) {            //被删结点的左子树为空,但右子树一定不为空            if (isLeftChild) {                //被删结点是左子树(对于它父亲而言)                parent.leftChild = current.rightChild;            } else {                parent.rightChild = current.rightChild;            }        } else if (current.rightChild == null) {            //被删结点的右子树为空,但左子树一定不为空            if (isLeftChild) {                //被删结点是左子树(对于它父亲而言)                parent.leftChild = current.leftChild;            } else {                parent.rightChild = current.leftChild;            }        } else {            //被删结点的右子树不为空,但左子树不为空            //中序后继,帮助被删结点找出他的继承结点(min(x>被删结点))            Node successor = getSuccessor(current);            if (current == root) {                root = successor;            } else {                //需要连接新点                if (isLeftChild) {                    parent.leftChild = successor;                } else {                    parent.rightChild = successor;                }            }            //把被删结点的左子树移交给被继承结点            successor.leftChild = current.leftChild;        }        return true;    }    /*找到被删结点的继承结点*/    private Node getSuccessor(Node delNode) {        Node successorParent = delNode;        Node success = delNode;        Node current = delNode.rightChild;//在右边才能找到比它大的点        while (current != null) {            successorParent = success;            success = current;            current = current.leftChild;//这样才能找到min(x>被删结点)        }        if (success != delNode.rightChild) {            //把它右子树给它老爸(它本身一定不会有左子树)            success.rightChild = successorParent.leftChild;            success.rightChild = delNode.rightChild;        }        return success;    }    public Node getRoot() {        return root;    }    public boolean isEmpty() {        return root == null;    }}

3.测试代码

        MyTree mt = new MyTree();        mt.insert(10);        mt.insert(20);        mt.insert(15);        mt.insert(3);        mt.insert(4);        mt.insert(90);//        Node node = mt.find(0);//        System.out.println(node.data);//        boolean update = mt.update(2, 5);//        System.out.println(update);////        Node node = mt.find(5);//        System.out.println(node.data);//        Node root = mt.getRoot();//        System.out.println(root.data);//3//        System.out.println("root.leftChild:" + root.leftChild.data);//null//        System.out.println("root.rightChild:" + root.rightChild.data);//null//        System.out.print("前序遍历:");//        mt.frontOrder(mt.getRoot());////        System.out.println();////        System.out.print("中序遍历:");//        mt.inOrder(mt.getRoot());//        System.out.println();////        System.out.print("后序遍历:");//        mt.afterOrder(mt.getRoot());        mt.delete(11);        System.out.print("中序遍历:");        mt.inOrder(mt.getRoot());        System.out.println();

这里写图片描述

上文中删除有点小问题,如果是仅有左子树或者右子树的根结点被删除的时候,会有bug,修正代码如下:

    /**     * 删除节点     * @param value     */    public boolean delete(long value) {        //引用当前节点,从根节点开始        Node current = root;        //应用当前节点的父节点        Node parent = root;        //是否为左节点        boolean isLeftChild = true;        while(current.data != value) {            parent = current;            //进行比较,比较查找值和当前节点的大小            if(current.data > value) {                current = current.leftChild;                isLeftChild = true;            } else {                current = current.rightChild;                isLeftChild = false;            }            //如果查找不到            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;            }        } else if(current.rightChild == null) {            if(current == root) {                root = current.leftChild;            }else if(isLeftChild) {                //这里的isLeftChild是相对于parent跟current连接而言的                parent.leftChild = current.leftChild;            } else {                parent.rightChild = current.leftChild;            }        } else if(current.leftChild == null) {            if(current == root) {                root = current.rightChild;            } else if(isLeftChild) {                parent.leftChild = current.rightChild;            } else {                parent.rightChild = current.rightChild;            }        } else {            //中序后继            Node successor = getSuccessor(current);            if(current == root) {                root = successor;            } else if(isLeftChild) {                parent.leftChild = successor;            } else{                parent.rightChild = successor;            }            successor.leftChild = current.leftChild;        }        return true;    }    public Node getSuccessor(Node delNode) {        Node successor = delNode;        Node successorParent = 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;    }
原创粉丝点击