2010-02-11 37 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