2010-02-11 66 views
4

我有一個BST,它是C++中的一個鏈表。我如何從內存中刪除整個事物?它會從類功能完成嗎?如何從內存中刪除二叉搜索樹?

+2

根據定義,鏈接列表具有前向和後向鏈接。 BST已經離開了孩子,正確的孩子,也許還有父母的聯繫。這是什麼? – Potatoswatter 2010-02-11 00:14:14

+0

我的BST的節點可以有左邊的孩子,右邊的孩子和父親的鏈接。 – neuromancer 2010-02-11 02:23:47

回答

1

執行樹的後序遍歷(即訪問父母之前的子節點),並在您訪問它時刪除每個節點。

這是否與類有關取決於你的實現。

0

由於提供的信息有限....

如果您分配了新的或的malloc(或相關的功能),比你需要遍歷了所有節點和免費或刪除節點。

另一種方法是把shared_ptr's (and weak_ptr's to kill cyclics)在分配 - 只要你做正確,你將不必釋放節點手動

如果您使用的是你在互聯網上拿起比所提供的質量實現班級不泄漏,你不必擔心任何事情。

4

只要刪除兒女

struct TreeNode { 
    TreeNode *l, *r, *parent; 
    Data d; 

    TreeNode(TreeNode *p) { l = nullptr; r = nullptr; parent = p; } 
    TreeNode(TreeNode const &) = delete; 
    ~TreeNode() { 
     delete l; // delete does nothing if ptr is 0 
     delete r; // or recurses if there's an object 
    } 
}; 

,或者如果你正在使用unique_ptr或一些這樣的,這還沒有必要:

struct TreeNode { 
    unique_ptr<TreeNode> l, r; 
    TreeNode *parent; 
    Data d; 

    TreeNode(TreeNode *p) { l = nullptr; r = nullptr; parent = p; } 
    TreeNode(TreeNode const &) = delete; 
    ~TreeNode() = default; 
}; 
+0

如果您需要保留一部分子樹,那麼您可以提供一個Detach()方法,該方法將從其父節點中取消列出節點。然後刪除將不會級聯到您想要保留的子樹。 – 2010-02-11 00:42:13

+0

使用'auto_ptr',只需指定'auto_ptr outside_ptr = my_node.l'即可完成。 – Potatoswatter 2010-02-11 00:46:05

+0

我想提出一個警告:這個樣本是邪惡的,很可能導致崩潰。問題是'auto_ptr'的複製/賦值操作符有奇怪的語義...'const TreeNode&node = ...; TreeNode拷貝(節點); node.l-> data;'會崩潰(希望立即)。 – 2010-02-11 13:28:04

3

如果你有機會到鏈表本身,這是小菜一碟:

// Making liberal assumptions about the kind of naming/coding conventions that might have been used... 
ListNode *currentNode = rootNode; 

while(currentNode != NULL) 
{ 
    ListNode *nextNode = currentNode->Next; 
    delete currentNode; 
    currentNode = nextNode; 
} 

rootNode = NULL; 

如果這是BST的定製FPGA實現,那麼這很可能是它的內部工作原理,如果它有綁定到一個特定的數據結構。

如果你沒有訪問內部,那麼Potatoswatter的答案應該是現貨。假設BST按照他們的建議進行設置,那麼簡單地刪除根節點應該會自動刪除所有分配的內存,因爲樹下的每個父節點都將刪除其子節點。

如果你問如何去跨越一個二叉樹遍歷手動,那麼你會做以下遞歸步驟:

void DeleteChildren(BSTNode *node) 
{ 
    // Recurse left down the tree... 
    if(node->HasLeftChild()) DeleteChildren(node->GetLeftChild()); 
    // Recurse right down the tree... 
    if(node->HasRightChild()) DeleteChildren(node->GetRightChild()); 

    // Clean up the data at this node. 
    node->ClearData(); // assume deletes internal data 

    // Free memory used by the node itself. 
    delete node; 
} 

// Call this from external code. 
DeleteChildren(rootNode); 

我希望我沒有理解錯了這裏的東西的這幫助。

+0

)爲什麼需要函數ClearData()?爲什麼不刪除節點?這是否也會刪除根節點? – neuromancer 2010-02-11 02:25:41

+1

我包含了ClearData()來表示在每個節點* *需要完成一些操作來釋放節點佔用的數據(如果有的話)。如果節點只有一個指向外部數據的指針(很可能)那麼ClearData()可能只是將指針NULL,如果樹實際爲數據本身分配內存(假設每個節點直接將字符串數據作爲char []分配給它),那麼ClearData()需要刪除該數組[ 。我試圖暗示的步驟是:1)清除每個節點所擁有的任何數據(這可以在析構函數中完成)2)刪除節點本身。 – xan 2010-02-11 11:39:03