2014-03-03 139 views
0

我想刪除一個二叉樹的,我的工作方案如下:刪除引用二叉樹通過節點的節點只有

(1)它讀取樹要創建節點的數量。

(2)它讀取所有這些節點。

(3)它打印由這些節點形成的樹。

(4)它讀取終端上要刪除的節點。

直到這裏一切工作正常,但是當我嘗試刪除所需的節點,然後它給出了分段錯誤的錯誤。

注:我必須通過引用傳遞根(這就是爲什麼我已經爲delete_tree_node(int delete_val,node ** root))中保留了兩個指針。

我的方法這樣做是: 我稱之爲遞歸函數delete_tree_node()由左,右的孩子,以遍歷樹,直到我得到節點等於值用戶想要刪除的節點的值。一次,如果我得到那個地方,然後我釋放()該節點。

我的代碼來實現這一目標是:(這給分割問題):

delete_tree_node(int delete_val, node **root)//two "**" because i call by reference in function call  
{ 
node*temp1; 
temp1=(*root); 
if(delete_val==(*root)->freq) 
    {  
    free((*root));  
    temp1=temp1->left;  
    (*root)=temp1;  
    } 

if(delete_val<temp1->freq)  
    { 
    delete_tree_node(delete_val,&temp1->left);  
    } 
if(delete_val>temp1->freq)  
    { 
    delete_tree_node(delete_val,&temp1->right); 
    }  
} 

它的函數調用:

delete_tree_node(delete_val, & head);//I give reference 

能有人幫我瞭解:

( 1)爲什麼它給分段錯誤。

(2)我的邏輯是正確的刪除所需的節點?如果不是,那麼你能給我一段代碼作爲參考嗎?

+0

在教科書中複習如何刪除二叉搜索樹中的節點。這並不像你現在編程那麼簡單。 – Henry

回答

1

您不能釋放節點然後訪問它。嘗試在temp1=temp1->left後移動免費。 此外,您必須返回一旦你找到正確的節點或路徑(或其他如使用):

delete_tree_node(int delete_val, node **root) 
{ 
    node *temp1; 
    temp1 = *root; 
    if(delete_val == temp1->freq) 
    {  
    temp1 = temp1->left;  
    free(*root);  
    *root = temp1;  
    } 
    else if(delete_val < temp1->freq)  
    { 
    delete_tree_node(delete_val, &temp1->left);  
    } 
    else if(delete_val > temp1->freq)  
    { 
    delete_tree_node(delete_val, &temp1->right); 
    }  
} 
+0

我試圖做到這一點,但它仍然給出錯誤。我的邏輯是否正確?你可以給任何一段代碼作爲參考嗎? – Sss

+0

哦,對不起,還有一個錯誤,假設你沒有重複的頻率:在每個ifs之前添加一個返回值} – Loghorn

+0

感謝它工作正常,除了它不會在要刪除的元素之後打印節點元素(我的意思是它只是打印在元素被刪除之前不在該位置之後的元素) – Sss

1
temp1=(*root); // copying the memory address of node to temp1 
free((*root)); // your freeing the memory here of the node 
temp1=temp1->left; // the memory your accessing is already free'd hence segmentation fault occurs 

嘗試交換兩種說法。

temp1=temp1->left; 
free((*root)); 

關於邏輯check here

+0

我試圖讀取兩個指針approac,但我不明白刪除的地方節點?根本沒有刪除http://dev-faqs.blogspot.in/2012/03/remove-node-from-binary-search-tree.html – Sss

+0

你不能只刪除一個節點,因爲它會依賴於它就像是左小孩和右小孩。嘗試追蹤算法,你會更好地理解它。看看數據匹配時會發生什麼,他們檢查該節點是否有子節點(你不能只留下子節點)'BinaryTreeNode **後繼者= getSuccessor(&(* node) - > left); (* node) - > data =(* successor) - > data; 刪除(後繼,(*後繼) - >數據);' – const

2

爲什麼它給了段錯誤的參考?

由於您在嘗試訪問temp1->left中的相同內存之前釋放了由*root指向的內存。

讓我們看看事情密切: -

temp1 = (*root) 

temp1中現在擁有相同的內存地址爲(*根),即都是一些數字指向相同的地址。爲了清楚起見,我們假設這個數字是'6'。所以,他們都指向內存地址'6'。請注意,它們不等於該地址的值,但只是指向該值。

現在,free((*root));告訴系統您釋放(* root)所指向的內存位置,在本例中爲6.一旦釋放內存,您將失去對內存的訪問權限,並且下次請求它(通過temp1->left),你會得到分段錯誤。

我希望澄清是什麼導致了分段錯誤。

粗略一瞥告訴我,你可以通過釋放(* root)來解決這個問題。事實上,遞歸調用會比較清楚這種方式,因爲你可以通過這個僞代碼描述它: -

delete left subtree 
delete right subtree 
delete root 

我不會深入到邏輯的正確性,因爲它似乎是一個家庭作業的問題,你最好自己解決這個問題。