BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #88648同步于 2015/9/17
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

这个程序还有bug吗?

spicewolf
2015/9/17镜像同步15 回复
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; }
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
nuanyangyang机器人#1 · 2015/9/17
用valgrind跑跑试试?
spicewolf机器人#2 · 2015/9/17
试了一下,目测没有问题 【 在 nuanyangyang 的大作中提到: 】 : 用valgrind跑跑试试?
erueat机器人#3 · 2015/9/17
想吐槽一下最后为什么不直接 return success。。。 另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。 第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。 做了重复工作又让接口变得更加复杂了。。建议程序里引用谨慎用。。 bug的话如果不考虑线程安全的问题的话,似乎能想到的会让程序崩在这里面的地方就只有因为Node的两个child指针是无效指针的情况了。。 要从设计上规避这个问题的话只能让child指针对外不可见吧。。 另外 Node 类的默认构造函数为什么不做初始化操作呢。。Node::Node(int value) 里面倒是对指针初始化了。。初始化操作请统一。。 再另外,在这个具体案例的情况下,觉得把Node的data成员改名value更为合适。。 以及 findMin 和 deleteNode_helper 两个函数的命名规范不一致啊。。 【似乎更多的是从工程的角度来评价这段程序了,跑题了么?】
spicewolf机器人#4 · 2015/9/17
说的挺好的,都说到点子上了。谢谢! 【 在 erueat 的大作中提到: 】 : 想吐槽一下最后为什么不直接 return success。。。 : 另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。 : 第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。 : ...................
spicewolf机器人#5 · 2015/9/17
delete_node_helper 关于第一个参数,我是这样想的,如果树只有一个节点,而且你要删的就是这个节点,你不用引用的话,在delete_node_helper 删了这个节点,deleteNode里面的root就是个野指针了,这样会出问题的。 你说呢? 【 在 erueat 的大作中提到: 】 : 想吐槽一下最后为什么不直接 return success。。。 : 另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。 : 第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。 : ...................
kuangfengwin机器人#6 · 2015/9/17
一直觉得写C++的都是大神。。。。
Lights机器人#7 · 2015/9/17
学长这是佛码双修啊 【 在 erueat 的大作中提到: 】 : 想吐槽一下最后为什么不直接 return success。。。 : 另外 delete_node_helper 这个函数的接口设计有点儿费解啊。。 : 第一个参数作为引用穿进去,在找到data的时候已经进行了赋值,却还同时作为返回值在返回后再赋一遍值。。 : ...................
laoguo机器人#8 · 2015/9/17
代码没细看,无脑问一下,是线程安全的么? 来自「北邮人论坛手机版」
erueat机器人#9 · 2015/9/18
呐,这个考虑是很好的,然而你的 deleteNode_helper 是有返回值的啊,如果保留这个返回值的话,那就不需要让第一个参数成为引用了,直接在 deleteNode 里面用返回值给 root 赋值就好了。。 其实在实际代码中,引用这个语法糖用得不好很容易给程序可读性带来问题的。因为使用者使用的时候跟用普通函数并没有什么区别,然而实际上它会可能“悄悄”改变实参的值。造成使用上的一些困惑。一般来说,对于使用引用并对引用变量进行修改操作的话,要么用二重指针来做(显式告诉别人这个函数不是安全的(函数式语言意义上的安全)),或者函数名上应该体现出来。 【 在 spicewolf 的大作中提到: 】 : delete_node_helper 关于第一个参数,我是这样想的,如果树只有一个节点,而且你要删的就是这个节点,你不用引用的话,在delete_node_helper 删了这个节点,deleteNode里面的root就是个野指针了,这样会出问题的。 : 你说呢? :