2016-05-31 52 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) 樹看起來應該像

50 
/\ 
    60 
    / \ 
     70 
    /\ 
     65 

讓我們接着說,我選擇刪除60。這似乎是工作首先罰款。 但是,如果我然後運行我所信任的搜索方法,則返回70在其任何指針處都沒有節點。

我假設正在發生的是,70被設置爲null之前,65可以向上移動。由於技術上65不再連接到樹,所以搜索方法找不到它。

因此,像這樣:

50 
/\ 
    70 
    / \ 

    /\ 
     65 

的問題是,我不明白這到底是怎麼發生。特別是因爲它應該設置節點爲null,如果它的兩個指針指向空,由於if語句

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

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

而且,如果第一個if語句是不正確的(如果不!= null),不應該簡單地繼續「else」(並刪除正確的)insted?

任何建議或提示,非常歡迎。

+0

請你幫個忙和BST代碼從Swing代碼分開。爲您的BST編寫單元測試並確保它正常工作,然後將其與前端連接起來。 –

+0

我不知道如何在這裏製作一棵樹,但拿起原來的樹並把65放在60的地方。我不認爲有可能像你認爲你擁有一棵樹。 – Marichyasana

+1

@Marichyasana例子的樹是一個正確的BST;那麼你修改後的結果就不是。 – Matt

回答

1

您的刪除方法的邏輯有很大的缺陷。首先,你並沒有移動節點,而是複製值,這已經是不正確的了:因爲任何節點都可以有兩個鏈接,只需複製左邊或右邊的鏈接值,然後檢查是否在葉中最終刪除它是錯誤的:如果你不是在一片葉子?那麼你放棄的另一個環節呢?在你的情況下,你最終將有70到右邊的值65:不再是BST。請記住,規則是對於任何節點n,左子樹中的所有節點必須小於n,並且右子樹中的所有節點大於n。

這也是爲什麼你找不到65:這不是因爲70有兩個空指針附加到它像你想象的,但是因爲你的搜索方法,當它到達70,因爲它大於65,搜索65到節點70的左側,並且在那裏找到空值。

這是正確的和經典希巴德的算法來去除在BST節點:刪除一個節點x你有它的繼任來取代它。它的繼任者是誰?因爲x有一個正確的孩子,所以它的後繼者是右子樹中具有最小密鑰的節點。替換保留了樹中的順序,因爲x.key和後繼鍵之間沒有鍵。我們完成了它的繼任者取代X的任務四個步驟:

  • 保存的鏈接節點在T被刪除

  • 集X指向它的後繼分鐘(t.right) 。

  • 設置x的右連桿(這是應該指向包含所有比x.key較大密鑰的BST )至deleteMin(t.right),則 鏈接到BST包含所有的按鍵時刪除後大於x.key
    。 (要刪除最小值,我們往左走,直到找到一個有空左節點的節點,然後用右節點替換到該節點的鏈接)

  • 設置x(它爲null)的左鏈接爲t.left( 小於刪除鍵及其後繼鍵的所有鍵)。

enter image description here