[英]Problem with pointers in binary search tree deletion
我正在嘗試實施二進制搜索樹操作,並被卡在刪除中。
11
/ \
10 14
使用有序遍歷作為樹的表示,初始輸出為10 11 14。
刪除節點10,預期輸出為11 14,但我得到0 11 14。
刪除節點14,預期輸出僅為11,但我得到0 11 67837。
請解釋為什么我得到錯誤的輸出。 我沒有在尋找任何代碼:)。
typedef struct _node{
int data;
struct _node *left;
struct _node *right;
} Node;
Node* bstree_search(Node *root, int key)
{
if(root == NULL){
return root;
}
// Based on binary search relation, key can be found in either left,
// right, or root.
if(key > root->data)
return bstree_search(root->right, key);
else if(key < root->data)
return bstree_search(root->left, key);
else
return root;
}
void bstree_insert(Node **adroot, int value)
{
// since address of address(root is itself address) is passed we can change root.
if(*adroot == NULL){
*adroot = malloc(sizeof(**adroot));
(*adroot)->data = value;
(*adroot)->right = (*adroot)->left = NULL;
return;
}
if(value > (*adroot)->data)
bstree_insert(&(*adroot)->right, value);
else
bstree_insert(&(*adroot)->left, value);
}
void bstree_inorder_walk(Node *root)
{
if(root != NULL){
bstree_inorder_walk(root->left);
printf("%d ",root->data);
bstree_inorder_walk(root->right);
}
}
void bstree_delete(Node **adnode)
{
//Node with no children or only one child
Node *node, *temp;
node = temp = *adnode;
if((*adnode)->right == NULL || (*adnode)->left == NULL){
if((*adnode)->right == NULL){
*adnode = (*adnode)->left;
}else{
*adnode = (*adnode)->right;
}
}else{ // Node with two children
}
free(temp);
}
int main()
{
Node *root = NULL;
Node *needle = NULL;
int i,elems[] = {11,10,14};
for(i = 0; i < 3; ++i)
bstree_insert(&root,elems[i]);
bstree_inorder_walk(root);
printf("\n");
needle = bstree_search(root, 10);
bstree_delete(&needle);
bstree_inorder_walk(root);
printf("\n");
needle = bstree_search(root, 14);
bstree_delete(&needle);
bstree_inorder_walk(root);
printf("\n");
}
請解釋為什么我得到錯誤的輸出。
您的delete
功能還必須更改已刪除節點的父節點。 例如,當刪除保留10的節點時,必須將根Node
的left
子Node
設置為NULL
。 由於不執行此操作,因此以后在遍歷樹時,將打印出已釋放的數據。
除了delete
,我沒有看到任何其他代碼,因此一旦進行此更改,就無法保證其正常工作。
您的輸出錯誤是因為您的刪除代碼有錯誤(好的,也許這很明顯)。
要從二叉搜索樹中刪除,首先要找到要刪除的節點。 如果它是葉節點,則在其父節點中將指向它的指針設置為NULL,然后釋放該節點。 如果不是葉節點,則采用兩個葉節點之一(右側子樹中最左側的子節點,或左側子樹中最右側的子節點),然后將其插入節點需要刪除,將指向該節點在其先前父節點中的節點的指針設置為NULL,然后刪除您現在“剪接”出樹的節點。
幾件事真的很快,
首先,當您分配節點時,您實際上應該在類型的大小(即Node)上執行malloc。
其次,如果您有2個孩子,則看起來您並沒有真正刪除節點並通過提升其中一個孩子來重建搜索樹。
其他人已經給您帶來其他明顯的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.