该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
以下是二叉树删除节点的代码,C Primer Plus 第5版中的第17章的原代码
bool DeleteItem(const Item *pi,Tree *ptree)
{
Pair look;
look=SeekItem(pi,ptree);
if(look.child==NULL)
return false;
if(look.parent==NULL) /*删除根项目 */
DeleteNode(&ptree->root);
else if(look.parent->left==look.child)
DeleteNode(&look.parent->left);
else
DeleteNode(&look.parent->right);
ptree->size--;
return true;
}
static void DeleteNode(Node **ptr)
/*ptr 是指向目标节点的父节点指针成员的地址 */
{
Node *temp;
puts((*ptr)->item.petname);
if((*ptr)->left==NULL)
{
temp=*ptr;
*ptr=(*ptr)->right;
free(temp);
}
else if((*ptr)->right==NULL)
{
temp=*ptr;
*ptr=(*ptr)->left;
free(temp);
}
else /*被删成员有两个子节点 */
{
/*找到右子树的依附位置 */
for(temp=(*ptr)->left;temp->right!=NULL;temp=temp->right)
continue;
temp->right=(*ptr)->right;
temp=*ptr;
*ptr=(*ptr)->left;
free(temp);
}
}
Pair类型的声明如下:
typedef struct pair
{
Node *parent;
Node *child;
} Pair;
Node类型的声明如下:
typedef struct node{
Item item;
struct node *left;
struct node *right;
}Node;
我想问的问题是是在DeleteItem()函数中,删除节点调用的是DeleteNode(&look.parent->right)或(&look.parent->left),
而不直接调用(&look.child);将原代码中的DeleteItem()函数修改后如下:
bool DeleteItem(const Item *pi,Tree *ptree)
{
Pair look;
look=SeekItem(pi,ptree);
if(look.child==NULL)
return false;
if(look.parent==NULL) /*删除根项目 */
DeleteNode(&ptree->root);
else
DeleteNode(&look.child)
ptree->size--;
return true;
}
发现程序不能正确删除节点。调试过程中,发现DeleteNode()函数返回前,*ptr已经指向了他的一个子树,但是函数返回后,发现ptree里面对应的节点指向了一段乱码。&look.child和&look.parent->right(或left),应该都是一个二级指针,为什么传递&look.child会达不到和&look.parent->right(或left)一样的效果呢?