データ構造Javaデータ構造---バイナリ検索ツリー

二分探索木

1.二分探索木の概念

バイナリソートツリーとも呼ばれるバイナリ検索ツリーは、空のツリー**または次のプロパティを持つバイナリツリーのいずれかです。

  • 左側のサブツリーが空でない場合、左側のサブツリー内のすべてのノードの値は、ルートノードの値よりも小さくなります。
  • 右側のサブツリーが空でない場合、右側のサブツリー内のすべてのノードの値がルートノードの値よりも大きくなります
  • その左右のサブツリーも二分探索木です。

ここに画像の説明を挿入

2.二分木操作-検索

ここに画像の説明を挿入
コード:

 public Node search(int val){
    
    
        while (root != null){
    
    
            if(val > root.val){
    
    // val>root.val 在右子树查找
                root = root.right;
            }else if(val < root.val){
    
    // val<root.val 在左子树查找
                root = root.left;
            }else {
    
    // val=root.val 返回该节点即可
                return root;
            }
        }
        return null;
    }

3.二分木操作-挿入

ここに画像の説明を挿入
コード:

    public boolean insert(int val) {
    
    
    	// 当为空树的时候 直接插入val
        if(root == null) {
    
    
            root = new Node(val);
            return true;
        }
        // 当不为空时的时候,进行判断
        Node parent = null;
        Node child = root;
        while (child != null){
    
    
        	// val 较大 寻找右子树
            if(child.val < val){
    
    
                parent = child;
                child = child.right;
            }else {
    
    //val 较小 寻找左子树
                parent = child;
                child = child.left;
            }
        }
        // 这里 parent的左子树或右子树就可以进行插入,此时进行判断.
        if(parent.val < val){
    
    
            parent.right = new Node(val);
        }else {
    
    
            parent.left = new Node(val);
        }
        return true;
    }

4.二分木操作-削除

ここに画像の説明を挿入
ここに画像の説明を挿入

   public void remove(int key) {
    
    
        Node cur = root;
        Node parent = null;
        while (cur != null){
    
    
            if(cur.val == key){
    
    
            	//找到要删除的节点 进行删除
                removeNode(cur,parent);
            }else if(cur.val < key){
    
    
                parent = cur;
                cur = cur.right;
            }else {
    
    
                parent = cur;
                cur = cur.left;
            }
        }
    }
    public void removeNode(Node cur,Node parent){
    
    
        if(cur.left == null){
    
     // 情况一
            if(cur == root){
    
    
                root = cur.right;
            }else if(cur == parent.left){
    
    
                parent.left = cur.right;
            }else {
    
    
                parent.right = cur.right;
            }
        }else if(cur.right == null){
    
     // 情况二
            if(cur == root){
    
    
                root = cur.left;
            }else if(cur == parent.right){
    
    
                parent.right = cur.left;
            }else {
    
    
                parent.left = cur.left;
            }
        }else {
    
     // 情况三
            Node targetParent = cur;
            Node target = cur.right;
            while(target.left != null){
    
    
                targetParent = target;
                target = target.left;
            }
            cur.val = target.val;
            if(target == targetParent.left){
    
    
                targetParent.left = target.right;
            }else {
    
    
                targetParent.right = target.right;
            }
        }
    }

5.パフォーマンス分析

挿入操作と削除操作の両方を最初に検索する必要があります。検索効率は、バイナリ検索ツリーの各操作のパフォーマンスを表します。
n個のノードを持つ二分探索木の場合、各要素を探索する確率が等しい場合、二分探索木の平均探索長は、二分探索木のノードの深さの関数になります。ノードは、より多くの回数です。
しかし、同じキーコードセットに対して、各キーコードの挿入順序が異なる場合、異なる構造の二分探索木を取得することが可能です。
ここに画像の説明を挿入
最適な場合、二分探索木は完全な二分木であり、平均比較の数は次のとおりです。ここに画像の説明を挿入

最悪の場合、二分探索木は単一分岐木に縮退し、比較の平均数は次のようになります。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/wwzzzzzzzzzzzzz/article/details/123109124