返回信息流bst删除节点
我想知道这个程序还有bug吗?求高人指点。在我的知识范围内,我认为真心没有bug了,野指针我也都处理了。
求大牛指导。
class Node
{
public:
int data;
Node * lchild, * rchild;
Node(){}
Node(int value): data(value),lchild(NULL),rchild(NULL){}
};
int findMin(Node * root)//找出这棵树最小的节点,返回它的值
{
while(root->lchild) root = root->lchild;
return root->data;
}
Node * deleteNode_helper(Node * & root, int data, bool & success)
{
if(!root) return NULL;
if(root->data > data)
{
root->lchild = deleteNode_helper(root->lchild,data,success);
return root;
}
else if(root->data < data)
{
root->rchild = deleteNode_helper(root->rchild, data,success);
return root;
}
else
{
success = true;
if(!root->lchild && !root->rchild)//删除叶子节点
{
delete root;
root = NULL;
return NULL;
}
if(!root->lchild || !root->rchild)//节点只有一个子树
{
Node * tmp;
if(!root->lchild)//只有右子树
{
tmp = root;
root = root->rchild;
delete tmp;
tmp = NULL;
return root;
}
else//只有左子树
{
tmp = root;
root = root->lchild;
delete tmp;
tmp = NULL;
return root;
}
}
//节点有两个子树
int minV = findMin(root->rchild);
root->data = minV;
root->rchild = deleteNode_helper(root->rchild, minV,success);
return root;
}
}
bool deleteNode(Node * & root, int data)
{
if(!root) return false;
bool success = false;
deleteNode_helper(root,data, success);
if(success) return true;
return false;
}
这是一条镜像帖。来源:北邮人论坛 / cpp / #88648同步于 2015/9/17
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
这个程序还有bug吗?
spicewolf
2015/9/17镜像同步15 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
想吐槽一下最后为什么不直接 return success。。。
另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。
第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。
做了重复工作又让接口变得更加复杂了。。建议程序里引用谨慎用。。
bug的话如果不考虑线程安全的问题的话,似乎能想到的会让程序崩在这里面的地方就只有因为Node的两个child指针是无效指针的情况了。。
要从设计上规避这个问题的话只能让child指针对外不可见吧。。
另外 Node 类的默认构造函数为什么不做初始化操作呢。。Node::Node(int value) 里面倒是对指针初始化了。。初始化操作请统一。。
再另外,在这个具体案例的情况下,觉得把Node的data成员改名value更为合适。。
以及 findMin 和 deleteNode_helper 两个函数的命名规范不一致啊。。
【似乎更多的是从工程的角度来评价这段程序了,跑题了么?】
说的挺好的,都说到点子上了。谢谢!
【 在 erueat 的大作中提到: 】
: 想吐槽一下最后为什么不直接 return success。。。
: 另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。
: 第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。
: ...................
delete_node_helper 关于第一个参数,我是这样想的,如果树只有一个节点,而且你要删的就是这个节点,你不用引用的话,在delete_node_helper 删了这个节点,deleteNode里面的root就是个野指针了,这样会出问题的。
你说呢?
【 在 erueat 的大作中提到: 】
: 想吐槽一下最后为什么不直接 return success。。。
: 另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。
: 第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。
: ...................
学长这是佛码双修啊
【 在 erueat 的大作中提到: 】
: 想吐槽一下最后为什么不直接 return success。。。
: 另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。
: 第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。
: ...................
呐,这个考虑是很好的,然而你的 deleteNode_helper 是有返回值的啊,如果保留这个返回值的话,那就不需要让第一个参数成为引用了,直接在 deleteNode 里面用返回值给 root 赋值就好了。。
其实在实际代码中,引用这个语法糖用得不好很容易给程序可读性带来问题的。因为使用者使用的时候跟用普通函数并没有什么区别,然而实际上它会可能“悄悄”改变实参的值。造成使用上的一些困惑。一般来说,对于使用引用并对引用变量进行修改操作的话,要么用二重指针来做(显式告诉别人这个函数不是安全的(函数式语言意义上的安全)),或者函数名上应该体现出来。
【 在 spicewolf 的大作中提到: 】
: delete_node_helper 关于第一个参数,我是这样想的,如果树只有一个节点,而且你要删的就是这个节点,你不用引用的话,在delete_node_helper 删了这个节点,deleteNode里面的root就是个野指针了,这样会出问题的。
: 你说呢?
: