如何解决通过 C++ 的递归在 BST 上实现插入
我正在递归地在 BST 上插入一个节点,我在下面找到了一个实现(检查下面代码中的rinnrt() 函数)。递归函数返回新插入节点的指针。
如果插入了节点,让我们说一棵树的高度为 4 的叶节点。沿着从高度 3 到根的路径上的所有节点不应该引用一些垃圾指针吗?
您还可以找到一个 test() 函数,当该函数没有遇到显式 return 语句时,它实际上返回一个垃圾指针。
当我使用rinnrt() 运行中序遍历时,我得到了没有任何垃圾值的BST。 任何人都可以帮助我了解rinrinrt() 函数中发生了什么吗?
struct Node {
Node* left;
Node* right;
int key;
Node(int key) {
this->key = key;
left = NULL;
right = NULL;
}
};
class BST {
Node* root;
public:
BST(int key) {
root = new Node(key);
}
Node* rinsert(Node* cur,int key) {
if (!cur) return new Node(key);
if (key < cur->key)
cur->left = rinsert(cur->left,key);
else
cur->right = rinsert(cur->right,key);
}
void inorder(Node* node) {
if (node == NULL) return;
inorder(node->left);
cout<<node->key<<" ";
inorder(node->right);
}
Node* getRoot() {
return root;
}
};
// function to return garbage pointer
Node* test() {
if (0) return new Node(2);
}
int main() {
BST bst = BST(2);
bst.rinsert(bst.getRoot(),3);
bst.rinsert(bst.getRoot(),1);
bst.rinsert(bst.getRoot(),0);
bst.rinsert(bst.getRoot(),7);
bst.rinsert(bst.getRoot(),8);
bst.rinsert(bst.getRoot(),4);
bst.rinsert(bst.getRoot(),9);
bst.inorder(bst.getRoot());
// is it really a garbage pointer?
Node* t = test();
cout<<endl;
cout<<t->key;
}
输出:
0 1 2 3 4 7 8 9
253425920
解决方法
是的,该函数存在漏洞,因为尽管它承诺返回
@Override
protected Publisher<MutableHttpResponse<?>> doFilterOnce(HttpRequest<?> request,ServerFilterChain chain) {
// If Micronaut Security rejected the request simpy do nothing
if (request.getAttribute(SecurityFilter.REJECTION).isPresent()) {
log.debug("Request was previously rejected. Not going to contact PDP");
return chain.proceed(request);
}
HttpMethod method = request.getMethod();
return Flowable.fromPublisher(chain.proceed(request)).flatMap(response -> {
if (method.equals(HttpMethod.GET) || method.equals(HttpMethod.HEAD)) {
if (response.getBody().isPresent()) {
// iterate through the body
Object theBody = response.getBody().get();
if (theBody instanceof Collection) {
Collection<?> iterable = (Collection<?>) theBody;
// find which elements are not allowed.
Flowable<Boolean> isElementAllowed = Flowable.fromIterable(iterable)
.concatMapSingle(mySecService::isAllowedReactive);
// filter out forbidden elements
Single<ArrayList<? super Object>> allowedElementsSingle = isElementAllowed
.zipWith(iterable,(isAllowed,item) -> {
if (isAllowed) {
return Optional.of(item);
} else {
return Optional.empty();
}
})
.filter(Optional::isPresent)
.map(Optional::get)
.collect(ArrayList::new,ArrayList::add);
return allowedElementsSingle.flatMapPublisher(allowedElements -> {
// reset the body
response.body(allowedElements);
return Flowable.just(response);
});
}
}
}
return Flowable.just(response);
});
}
,但并非在所有情况下都如此。
正确的代码(未经测试)是
Node*
缺少 return 语句意味着发布的代码调用 undefined behaviour。不幸的是,未定义的行为并不意味着程序将无法运行,也不意味着该函数将返回垃圾指针。碰巧,在这种情况下,正确的指针恰好位于正确的寄存器中,以便返回值正确。所以代码“有效”。在不同的编译器(甚至不同的日子)上,您可能就没那么幸运了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。