2011-08-21 74 views
-1

编写一个C程序来删除一棵树。删除一个文件树,如果它已满C使用C

我写的一小段代码来实现这一点,但它进入一个无限循环

void deleteTree(struct tnode *root) 
{ 
cout<<root->data<<endl; 
if(root->lchild == NULL && root->rchild == NULL) 
    delete(root); 

deleteTree(root->lchild); 
deleteTree(root->rchild); 
//return root; 
} 

我想删除它,而穿越。我知道可以使用Post Order Traversal。但其他一些想法可以存在或不存在?

+0

我只写了小代码。我们可以假设我将根节点的地址传递给上面的函数。 – aj983

回答

1

提示:如果没有留下孩子,您真的应该拨打deleteTree(root->lchild);吗,或者在没有孩子的时候拨打deleteTree(root->rchild);?你如何看待这与无限递归有关?另外:你不应该首先删除节点,然后递归到它的子节点中 - 因为在节点被删除后,它不再存在,并且你不能真正使用root(它对你来说是纯粹的运气) 。

1

它不应该是无限循环,但它不正确,因为根 - > lchild可以为空whilte右孩子不为空,当你deleteTree(根lchild)

+0

void deleteTree(struct tnode * root) { if(root == NULL) return; deleteTree(root-> lchild); deleteTree(root-> rchild); 删除(root); } – aj983

+0

void deleteTree(struct tnode * root) { if(root == NULL) return; deleteTree(root-> lchild); deleteTree(root-> rchild); 删除(root); }我不明白我犯的错误。你能否请详细解释 – aj983

4

无限循环?它实际上应该是访问冲突a.k.a SIGSEGV。当删除叶节点时,您只需拨打delete(root),但不会返回。所以接下来的两个递归deleteTree调用仍然被执行(因此导致SIGSEGV,因为root应该是无效的)。无论是delete(root)之后添加return;或使用本:

void deleteTree(struct tnode *root) 
{ 
    cout<<root->data<<endl; 

    if (root->lchild != NULL) 
    deleteTree(root->lchild); 
    if (root->rchild != NULL) 
    deleteTree(root->rchild); 
    delete(root); 
} 

它也将节省,因为儿童早期检查一个函数调用。

+0

国际海事组织,你不应该完整的solutios发布作业问题。 (除此之外,这是一个很好的答案......) –

+0

对不起,我没有注意到作业标签。我刚刚意识到它XD – LeleDumbo

2

您应该做一个后续遍历,删除子项并删除根目录。也许:

void deleteTree(struct tnode *root) 
{ 
    if (root != NULL) 
    { 
     // ?? delete root->data ?? 
     deleteTree(root->lchild); 
     deleteTree(root->rchild); 
     delete root; 
    } 
} 

如果您希望避免递归调用时,指针为空,你可以在调用deleteTree()递归测试之前每个孩子NULL的含量。然后你可以想象用断言替换现有的if测试,但是你不得不担心被要求删除一棵空树(当初始调用deleteTree()被赋予一个空指针时)。