ノードのバイナリ検索ツリーを削除するデバッグ解析プロセス

トピックの背景

対象時に何か間違ったのベースケースは比較的理解不足で、その後、デバッグを思考の方法でトピックを紹介注ぎ、そしてその逆の考え方が明確になり戻ってきます。あまり話をしなかった、例を参照してください
オリジナルタイトルリンク:https://leetcode-cn.com/problems/delete-node-in-a-bst/description/を

タイトル説明

バイナリサーチツリーのルートノードの所与のルートと値キーを、バイナリサーチツリー削除キーノードに対応し、かつ同じ二分探索木の特性ことを確認してください。(おそらく更新される)のバイナリ検索ツリーのルートノードへの参照を返します。
:一般的には、削除ノードは2つのステップに分けることができ
、削除するノードを見つけ、まず
見つかった場合、それを削除します。
説明:アルゴリズムの時間複雑度は、O(h)は、hは木の高さが必要です。
例:

root = [8,5,6,3,7,null,9]
key = 5

    8
   / \
  5   6
 / \   \
3   7   9

给定需要删除的节点值是 5,所以我们首先找到 5 这个节点,然后删除它。

一个正确的答案是 [8,7,6,3,null,null,9], 如下图所示。

    8
   / \
  7   6
 /     \
3       9

另一个正确答案是 [8,3,6,null,7,null,9]

    8
   / \
  3   6
   \   \
    7   9
思考

子ノード、単に削除がない場合:ステップ1は、
ノードを削除したい場合は、唯一の子ノードを持っている、ノードはこの子ノードと交換することが削除されます。STEP2
STEP3:ノードは削除したい場合は、ノードを右から削除し、2人の子供を持っています最低限の枝を見つけ、そのノードが削除されるように置換されます

コードに直接来ます:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) {
            return null;
        }
        if (key < root.val){
            root.left = deleteNode(root.left,key);
            return root;
        }else if (key > root.val){
            root.right = deleteNode(root.right,key);
            return root;
        }else {
            if (root.left == null || root.right == null){
                root = root.left == null?root.right:root.left;
            }else {
                TreeNode cur = root.right;
                while (cur.left != null){
                    cur = cur.left;
                }
                root.val = cur.val;
                root.right = deleteNode(root.right,cur.val);
            }
        }
        return root;
    }
}

まず考えることができ、一時的に下品なやり方で木に割り当てられ、その後、我々は、デバッグに始まりました

public static void main(String[] args) {
        Solution solution = new Solution();
        TreeNode treeNode1 = new TreeNode(8);
        TreeNode treeNode2 = new TreeNode(5);
        TreeNode treeNode3 = new TreeNode(6);
        TreeNode treeNode4 = new TreeNode(3);
        TreeNode treeNode5 = new TreeNode(7);
        TreeNode treeNode6 = new TreeNode(9);
        treeNode1.left = treeNode2;
        treeNode1.right = treeNode3;
        treeNode2.left = treeNode4;
        treeNode2.right = treeNode5;
        treeNode3.left =null;
        treeNode3.right = treeNode6;
        TreeNode treeNode = solution.deleteNode(treeNode1, 5);
}

まず、root.val値が8で、キーの値は、反復に、5未満であります

ここに画像を挿入説明
今回は、root.valは5であり、この時間は、最初のサブブランチがあり、この時点で決定するために、サブブランチがあるかどうかを判断、次の分岐に進み、もしあれば、我々は、ここに右の分岐枝を残しているかどうかそれから決定し、その後、我々は削除する権利枝の値をカバーするでない場合は、反復を続けるために、あなたは、私たちの権利の枝が、削除したい元の場所を置き換えるために、この時点で見ることができます。

ここに画像を挿入説明

しかし、右の分岐がある、削除されていない、我々は枝を運営する権利を持つことになり、ダウン反復継続しました

ここに画像を挿入説明

ここに画像を挿入説明

ここでも、これはこれまで、何のサブブランチを発見しに来て、それは彼にはnullを与えるだろう。このとき、上のシーケンス右。このアイデアと一緒に行くためには、業務プロセスを整理することができます。
話題の種類の明確なアイデアがある場合は、あなたが自分自身のフローチャートを通過することができます、あなたはより良いこれらのトピックを探求し、自分のアイデアを通じて、この方法を理解する必要はありません。
あなたを助けることを望みます!

リリース5元の記事 ウォンの賞賛3 ビュー99

おすすめ

転載: blog.csdn.net/weixin_42887211/article/details/102916542