数据结构复习七之 查找之 二叉搜索树

1.二叉排序树介绍

前面讲到中,顺序表的插入和删除效率还可以,但查找效率很低;而有序线性表中,可以使用折半、插值、斐波那契等查找方法来实现,因为要保持有序,其插入和删除操作很耗费时间。二叉排序树(Binary Sort Tree),又称为二叉搜索树,则可以在高效率的查找下,同时保持插入和删除操作也又较高的效率。
二叉查找树具有以下性质:
(1)若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)任意节点的右子树不空,则右子树.上所有结点的值均大于它的根结点的值;
(3)任意节点的左、右子树也分别为二叉查找树。

2.二叉搜索树的增删查

package 查找;
class Node{
    int data;
    Node lChild;
    Node rChild;
    Node parent;

    public Node(int data){
        this.data=data;
        lChild=null;
        rChild=null;
        parent=null;
    }
}
public class 二叉搜索树 {

    private Node root;
    public 二叉搜索树(){
        this.root=null;
    }
    //查找最小结点  返回以root为根的二叉树的最小结点
    public Node find_min(Node root){
        if(root==null){
            return null;
        }
        while(root.lChild!=null){
            root=root.lChild;
        }
        return root;
    }
    //查找最大结点  返回以root为根的二叉树的最大结点
    public Node find_max(Node root){
        if(root==null){
            return null;
        }
        while(root.rChild!=null){
            root=root.rChild;
        }
        return root;
    }
    //查找
    public boolean SearchBST(Node root,int key){
        if(root==null){
            return false;
        }
        while(root!=null){
            if(root.data==key){
                return true;
            }else if(root.data>key){
                root=root.lChild;
            }else{
                root=root.rChild;
            }
        }
        return false;
    }
    //插入
    public Node InsertBST(Node root,int key){
        if (root == null) {
            return new Node(key);
        }
        if (key == root.data) {
            return root;
        } else if (key < root.data) {
            root.lChild=InsertBST(root.lChild, key);
        } else {
            root.rChild=InsertBST(root.rChild, key);
        }
        return root;
    }
    //删除
    public boolean deleteBST(Node root,int key){
        if(root==null){
            return false;
        }
        Node parent=null;//用来保存父节点
        Node pnext=root;//用来移动  保存孩子结点
        while(pnext!=null){
            if(pnext.data==key){
                delete(pnext,parent);
                return true;
            }else if(pnext.data>key){
                parent=pnext;
                pnext=pnext.lChild;
            }else{
                parent=pnext;
                pnext=pnext.rChild;
            }
        }
        return false;
    }
    public void delete(Node pnext,Node parent){//前面是被删除结点  后面是父结点
        if(pnext.lChild==null){//左子树为空
            if(pnext==root){//被删除是根结点
                root=root.rChild;
                pnext=null;
            }else{
                if(pnext.data<parent.data){//被删除结点是左孩子节点
                    parent.lChild=pnext.rChild;//将它的右孩子接在父节点的左孩子上
                    pnext=null;
                }else{
                    parent.rChild=pnext.rChild;
                    pnext=null;
                }
            }
        }else if(pnext.rChild==null){//右子树为空
            if(pnext==root){//被删除是根结点
                root=root.lChild;
                pnext=null;
            }else{
                if(pnext.data<parent.data){//被删除结点是左孩子节点
                    parent.lChild=pnext.lChild;//将它的右孩子接在父节点的左孩子上
                    pnext=null;
                }else{
                    parent.rChild=pnext.lChild;
                    pnext=null;
                }
            }
        }else{//左右子树都不为空   删除的地方使用前驱结点代替
            Node pre,node;
            node=pnext;
            pre=pnext.lChild;//保存左子树
            while(pre.rChild!=null) {//找左子树最大结点   也就是最大的前驱
                node=pre;
                pre=pre.rChild;
            }
            pnext.data=pre.data;
            if(node!=pnext){
                node.rChild=pre.lChild;
            }else{
                node.lChild=pre.lChild;
            }
            node=null;
        }
    }
    //遍历
    public void inorder(Node node){
        if(node==null){
            return;
        }
        inorder(node.lChild);
        System.out.print(node.data+" ");
        inorder(node.rChild);
    }

    public static void main(String[] args) {
        二叉搜索树 BinaryTree=new 二叉搜索树();
        System.out.println("根结点:");
        Node root=new Node(4);
        BinaryTree.inorder(root);
        System.out.println(" ");

        System.out.println("插入新的结点:");
        root=BinaryTree.InsertBST(root,5);
        root=BinaryTree.InsertBST(root,6);
        root=BinaryTree.InsertBST(root,7);
        root=BinaryTree.InsertBST(root,2);
        root=BinaryTree.InsertBST(root,2);//重复结点
        BinaryTree.inorder(root);
        System.out.println(" ");

        System.out.println("查询结点:");
        System.out.println(BinaryTree.SearchBST(root,8));
        System.out.println("删除结点:");
        System.out.println(BinaryTree.deleteBST(root,6));
        BinaryTree.inorder(root);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值