二叉搜索树的Java实现(2)

public class BinTree {
    Node root=null;
    private class Node{
        Node parent=null;
        Node leftChild=null;
        Node rightChild=null;
        int key;
        public Node(int data) {
            this.key=data;
        }
    }
    public BinTree(int[] datas) {
        buildTree(datas);
    }
    private void buildTree(int[] datas) {
        for (int i = 0; i < datas.length; i++) {
            Node node=new Node(datas[i]);
            insertNode(node);
        }
    }
    private void insertNode(Node node) {    //插入结点
        Node next=this.root;   
        Node cur=null;    //用来保存当前结点
        while(next!=null){    //当到达叶子结点时,确认位置!
            cur=next;
            if(node.key>=cur.key){
                next=next.rightChild;
            }else{
                next=next.leftChild;
            }
        }
        node.parent=cur;    //插入该结点!
        if(cur==null){
            this.root=node;  //该树为空树,所以这个是根节点
        }else if(node.key>=cur.key){
            cur.rightChild=node;
        }else{
            cur.leftChild=node;
        }
    }
    /*
    * 插入一个数
    */
    public void insert(int data){   
        Node node=new Node(data);
        System.out.println("插入结点:"+data);
        insertNode(node);
        this.midOrderTraverse();
    }
   
    /*
    * 先序遍历
    */
    public void preOrderTraverse(){   
        System.out.println("先序遍历:");
        preOrderTraverse(root);
        System.out.println();
    }
    private void preOrderTraverse(Node node){    //先序遍历
        if(node!=null){
            System.out.print("-"+node.key+"-");
            preOrderTraverse(node.leftChild);
            preOrderTraverse(node.rightChild);
        }
    }
    /*
    * 中序遍历
    */
    public void midOrderTraverse(){   
        System.out.println("中序遍历:");
        midOrderTraverse(root);
        System.out.println();
    }
    private void midOrderTraverse(Node node){    //中序遍历
        if(node!=null){
            midOrderTraverse(node.leftChild);
            System.out.print("-"+node.key+"-");
            midOrderTraverse(node.rightChild);
        }
       
    }
   
    /*
    * 后序遍历
    */
    public void postOrderTraverse(){
        System.out.println("后序遍历:");
        postOrderTraverse(root);
        System.out.println();
    }
    private void postOrderTraverse(Node node){    //后序遍历
        if(node!=null){
            System.out.print("-"+node.key+"-");
            postOrderTraverse(node.leftChild);
            postOrderTraverse(node.rightChild);
        }
    }
   
    /*
    * 搜索结点
    */
    public void search(int data){   
        System.out.println("您要查找的是:"+data);
        Node node;
        if((node=searchNode(new Node(data)))==null){
            System.out.println("树中没有该结点!");
        }else{
            System.out.println("查找"+node.key+"成功!");
        }
    }
   
    private Node searchNode(Node node){    //private供内部调用,搜索结点
        if(node==null){
            System.out.println("输入为空,查找失败!");
        }else{
            if(root==null){
                System.out.println("该树为空树!");
            }else{                        //开始查找
                boolean isFound=false;   
                Node x=root;
                Node y=null;
                while(!isFound&&x!=null){    //当查到或者到了叶子节点还没查到时,终结!
                    y=x;
                    if(node.key==x.key){   
                        isFound=true;
                    }else{                    //通过比较大小往下面查找
                        if(node.key>x.key){   
                            x=x.rightChild;
                        }else{
                            x=x.leftChild;
                        }
                    }
                }
                if(isFound){    //没找到的话,在最后返回null
                    return y;
                }
            }
        }
        return null;
    }
   
    /*
    * 获取最大值
    */
    public void  getMax(){   
        Node node;
        if((node=getMaxNode(root))==null){
            System.out.println("该树为空!");
        }else{
            System.out.println("最大的结点是:"+node.key);
        }
       
    }
   
    private Node getMaxNode(Node node){    //获取最大值
        if(node!=null){
            Node x=node;
            Node y=null;
            while(x!=null){    //一直往右遍历直到底就是最大值了!
                y=x;
                x=x.rightChild;
            }
            return y;
        }
        return null;
    }
   
    /*
    * 获取最小值
    */
    public void getMin(){   
        Node node;
        if((node=getMinNode(root))==null){
            System.out.println("该树为空!");
        }else{
            System.out.println("最小的结点是:"+node.key);
        }
    }
    private Node getMinNode(Node node){    //获取最小值
        if(node!=null){
            Node x=node;
            Node y=null;
            while(x!=null){    //一直往左遍历直到底就是最小值了!
                y=x;
                x=x.leftChild;
            }
            return y;
        }
        return null;
    }
   
    /*
    * 获取前驱结点
    */
    public void getPre(int data){   
        Node node=null;
        System.out.println(data+"的前驱结点:");
        if((node=getPreNode(searchNode(new Node(data))))==null){
            System.out.println("该结点不存在或无前驱结点!");
        }else{
            System.out.println(data+"的前驱结点为:"+node.key);
        }
    }
   
    private Node getPreNode(Node node){    //获取前驱结点
        if(node==null){
            return null;
        }
        if(node.leftChild!=null){    //当有左孩子时,前驱结点就是左子树的最大值
            return getMaxNode(node.leftChild);
        }else{//当不存在左孩子时,前驱结点就是——它的祖先,而且,它在这个祖先的右子树中。这句话自己画图就能理解了
            Node x=node;
            Node y=node.parent;
            while(y!=null&&x==y.leftChild){
                x=y;
                y=y.parent;
            }
            return y;
        }
    }
   
    /*
    * 获取后继结点
    */
    public void getPost(int data){   
        Node node=null;
        System.out.println(data+"的后继结点:");
        if((node=getPostNode(searchNode(new Node(data))))==null){
            System.out.println("该结点不存在或无后继结点!");
        }else{
            System.out.println(data+"的后继结点为:"+node.key);
        }
    }
   
    private Node getPostNode(Node node){    //获取后继结点
        if(node==null){
            return null;
        }
        if(node.rightChild!=null){    //当有右孩子时,前驱结点就是右子树的最小值
            return getMinNode(node.rightChild);
        }else{//当不存在右孩子时,后继结点就是——它的祖先,而且,它在这个祖先的左子树中。这句话自己画图就能理解了
            Node x=node;
            Node y=node.parent;
            while(y!=null&&x==y.rightChild){
                x=y;
                y=y.parent;
            }
            return y;
        }
    }
   
   
    /*
    * 删除结点
    */
    public void delete(int data){   
        Node node;
        if((node=searchNode(new Node(data)))==null){//注意!这里不能new结点!你必须从树中找该结点!new就是初始化了
            System.out.println("二叉树中不存在此结点!");
            return;
        }
        deleteNode(node);
        System.out.println("删除结点"+data+"后:");
        this.midOrderTraverse();
    }
   
   
    private void deleteNode(Node node){
        if(node==null){
            System.out.println("删除结点不能为空!");
            return;
        }
        replacedNode(node);
    }
   
    private void replacedNode(Node node) {    //替换结点
        if(node.leftChild!=null
                &&node.rightChild!=null){    //当有左右孩子时,用后继结点替换
            replacedNodeOfPost(node);
        }
        else
        {
            if(node.leftChild!=null){    //当只有左孩子时,直接用左子树替换
                node=node.leftChild;
            }else if(node.rightChild!=null){    //只有右孩子时,直接有子树替换
                node=node.rightChild;
            }else{            //当没有左右孩子时,就直接释放了这个结点
                freeNode(node);
            }
        }
    }
   
   
    private void freeNode(Node node) {    //释放该结点,断掉其与父结点的链接
        if(node==node.parent.leftChild){
            node.parent.leftChild=null;
        }else{
            node.parent.rightChild=null;
        }
    }
   
    private void replacedNodeOfPost(Node node) {   
        Node y=this.getPostNode(node);    //找后继结点
        node.key=y.key;
        replacedNode(y);    //替换了key之后,再一次递归把现在这个结点给替换了!
    }
   
}

最后是测试结果:

------------------分割线-------------------------

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/75bb65376b71197627b23e9b56907d70.html