2011-08-21 56 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()被賦予一個空指針時)。