2016-05-31 5 views
1

バイナリ検索ツリーからノードを削除するメソッドを作成したいと思います。BST削除ノードメソッドがツリーの残りの部分を切り捨てる

これは私の方法である:

public void remove(Node node) 
 
\t //Removes a given node and puts one of the nodes below it in its place until it reaches the end 
 
\t { 
 
\t \t 
 
\t \t if (node.left != null) //If the node to the left is not empty 
 
\t \t { 
 
\t \t \t node.value = node.left.value; //Moves up the left node to take its place 
 
\t \t \t remove(node.left); //Goes to the next node 
 
\t \t \t if (node.left.right == null && node.left.left == null) 
 
\t \t \t \t node.left = null; //Removes the last node at the end of the tree after moving it up 
 
\t \t } 
 
\t \t else if (node.right != null) 
 
\t \t { 
 
\t \t \t node.value = node.right.value; //Moves up the left node to take its place 
 
\t \t \t remove(node.right); //Goes to the next node 
 
\t \t \t if (node.right.left == null && node.right.right == null) 
 
\t \t \t \t node.right = null; //Removes the last node at the end of the tree after moving it up 
 
\t \t \t 
 
\t \t } \t 
 
\t \t 
 
\t }

問題はそれだけでいくつかのケースで動作しています。

のは、私が60、70、65ツリーが

50 
/\ 
    60 
    / \ 
     70 
    /\ 
     65 

が、その後ができます私はこれが動作しているようです60の削除を選択すると言う

ようになるはずです (ルートノードが50である)を入力します例えばましょう最初は大丈夫です。 しかし、私が信頼する検索メソッドを実行すると、そのポインタのいずれにもノードがないことが返されます。

私が想定していることは、65が上に移動する前に70がヌルに設定されていることです。そして、65は技術的にもツリーに接続されていないので、検索メソッドはそれを見つけることができません。

だから、このようなものは:

50 
/\ 
    70 
    / \ 

    /\ 
     65 

問題は、私はこれが起こっする方法を理解していない、です。それが原因文が(事実ではない場合、最初の場合のステートメントは

if (node.left.right == null && node.left.left == null) 
       node.left = null; 

。また

if (node.right.left == null && node.right.right == null) 
       node.right = null; 

、放置しておく場合には、両方のポインタポイントは、nullにあればnullにノードを設定する必要があり、特に以来!= null)、それは単純に "else"(そして正しいものを削除)に進むべきではありませんか?

どのような提案やヒントも大歓迎です。

+0

自分に好意を行うと、SwingコードからBSTコードを分離。 BSTの単体テストを書いて正しく動作することを確認してから、フロントエンドに接続します。 –

+0

ここに木を作る方法は分かりませんが、オリジナルの木をとり、60の場所に65を入れてください。私はあなたが思っているような木を持つことは可能ではないと思います。 – Marichyasana

+1

@Marichyasanaの例のツリーは正しいBSTです。あなたの変更から生じるものはそうではありません。 – Matt

答えて

1

削除方法のロジックには大きな欠陥があります。まず最初に、ノードを移動せずに値をコピーしていますが、これは既に間違っています。どのノードも2つのリンクを持つことができるため、左右のリンク値だけをコピーし、最終的にそれを削除することは間違っています:もしあなたが葉にいなければ?あなたが後ろに置いている他のリンクはどうですか?あなたの場合、最後には70の右に65という値があります:もはやBSTはありません。ルールは、任意のノードnに対して、左のサブツリー内のすべてのノードがnより小さく、右のサブツリー内のすべてのノードがnより大きくなければならないことを覚えておいてください。

これはあなたが考えているように70に2つのヌルポインタが付いているからではありませんが、検索方法が70に達したときに65より大きいため、ノード70のを左にと検索し、そこにはヌルがあります。あなたはその後継と交換する必要があるノードxを削除する:

は、これがBST内のノードを削除するには、正しいとクラシックHibbardのアルゴリズムです。後継者はどれですか? xには正しい子があるので、その後継ノードは右のサブツリーに最も小さなキーを持つノードです。 x.keyと後継者のキーの間にはキーが存在しないため、置換はツリー内の順序を保持します。その後継分を指すようにトン

  • 集合X(t.right)で削除するノードへのリンク

    • 割引:私たちは4つのステップでその後継でXを交換する作業を達成します。 deleteMin(t.right)、そのすべてのキーを含むBSTへ リンクに(x.keyより大きいすべてのキーを含むBST を指すようになっている)は、xの右リンクを設定

    • 削除後x.key
      より大きい。 (最小値を削除するには、左のリンクがヌルのノードを見つけて、そのリンクを右のリンクでそのノードに置き換えます)

    • xの左側のリンクをt.left( が削除されたキーとその後継キーよりも小さいすべてのキー)。

    enter image description here

  • 関連する問題