#include <cassert>
#include <iostream>
struct Node {
Node(int key_, int value_)
: left(nullptr) , right(nullptr) , key(key_), value(value_)
{}
Node * left, * right;
int key, value;
};
namespace incorrect_wiki {
void insert(Node* root, int key, int value) {
if (!root)
root = new Node(key, value);
else if (key < root->key)
insert(root->left, key, value);
else // key >= root->key
insert(root->right, key, value);
}
}
void insert(Node*& root, int key, int value) {
if (!root)
root = new Node(key, value);
else if (key < root->key)
insert(root->left, key, value);
else // key >= root->key
insert(root->right, key, value);
}
template<typename Node, typename Callable>
void visit_all(Node * root, Callable && callback) {
if (!root) return;
if (root->left) visit_all(root->left, callback);
callback(*root);
if (root->right) visit_all(root->right, callback);
}
int main(int argc, const char *argv[]) {
Node * p_root{nullptr};
int keys[] = {8, 3, 10, 1, 6, 14, 4, 7, 13};
size_t const N = sizeof(keys)/sizeof(int);
auto print_key = [](Node const & n) { std::cerr << n.key << ", "; };
// incorrect insert
for (int i = 0; i < N; ++i) { incorrect_wiki::insert(p_root, keys[i], 1); }
visit_all(p_root, print_key);
assert(nullptr == p_root); // p_root was passed by value and nothing
// has changed, moreover the memory allocations
// in incorrect_wiki::insert are all leaked
// correct insert
for (int i = 0; i < N; ++i) { insert(p_root, keys[i], 1); }
visit_all(p_root, print_key);
return 0;
}
I2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnN0cnVjdCBOb2RlIHsKICAgIE5vZGUoaW50IGtleV8sIGludCB2YWx1ZV8pCiAgICAgICAgOiBsZWZ0KG51bGxwdHIpICwgcmlnaHQobnVsbHB0cikgLCBrZXkoa2V5XyksIHZhbHVlKHZhbHVlXykKICAgIHt9CiAgICBOb2RlICogbGVmdCwgKiByaWdodDsKICAgIGludCBrZXksIHZhbHVlOwp9OwoKCm5hbWVzcGFjZSBpbmNvcnJlY3Rfd2lraSB7CnZvaWQgaW5zZXJ0KE5vZGUqIHJvb3QsIGludCBrZXksIGludCB2YWx1ZSkgewogICAgaWYgKCFyb290KQogICAgICAgIHJvb3QgPSBuZXcgTm9kZShrZXksIHZhbHVlKTsKICAgIGVsc2UgaWYgKGtleSA8IHJvb3QtPmtleSkKICAgICAgICBpbnNlcnQocm9vdC0+bGVmdCwga2V5LCB2YWx1ZSk7CiAgICBlbHNlICAvLyBrZXkgPj0gcm9vdC0+a2V5CiAgICAgICAgaW5zZXJ0KHJvb3QtPnJpZ2h0LCBrZXksIHZhbHVlKTsKfQp9Cgp2b2lkIGluc2VydChOb2RlKiYgcm9vdCwgaW50IGtleSwgaW50IHZhbHVlKSB7CiAgICBpZiAoIXJvb3QpCiAgICAgICAgcm9vdCA9IG5ldyBOb2RlKGtleSwgdmFsdWUpOwogICAgZWxzZSBpZiAoa2V5IDwgcm9vdC0+a2V5KQogICAgICAgIGluc2VydChyb290LT5sZWZ0LCBrZXksIHZhbHVlKTsKICAgIGVsc2UgIC8vIGtleSA+PSByb290LT5rZXkKICAgICAgICBpbnNlcnQocm9vdC0+cmlnaHQsIGtleSwgdmFsdWUpOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBOb2RlLCB0eXBlbmFtZSBDYWxsYWJsZT4Kdm9pZCB2aXNpdF9hbGwoTm9kZSAqIHJvb3QsIENhbGxhYmxlICYmIGNhbGxiYWNrKSB7CiAgICBpZiAoIXJvb3QpIHJldHVybjsKICAgIGlmIChyb290LT5sZWZ0KSB2aXNpdF9hbGwocm9vdC0+bGVmdCwgY2FsbGJhY2spOwogICAgY2FsbGJhY2soKnJvb3QpOwogICAgaWYgKHJvb3QtPnJpZ2h0KSB2aXNpdF9hbGwocm9vdC0+cmlnaHQsIGNhbGxiYWNrKTsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNvbnN0IGNoYXIgKmFyZ3ZbXSkgewogICAgTm9kZSAqIHBfcm9vdHtudWxscHRyfTsKICAgIGludCBrZXlzW10gPSB7OCwgMywgMTAsIDEsIDYsIDE0LCA0LCA3LCAxM307CiAgICBzaXplX3QgY29uc3QgTiA9IHNpemVvZihrZXlzKS9zaXplb2YoaW50KTsKCiAgICBhdXRvIHByaW50X2tleSA9IFtdKE5vZGUgY29uc3QgJiBuKSB7IHN0ZDo6Y2VyciA8PCBuLmtleSA8PCAiLCAiOyB9OwoKICAgIC8vIGluY29ycmVjdCBpbnNlcnQKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgKytpKSB7IGluY29ycmVjdF93aWtpOjppbnNlcnQocF9yb290LCBrZXlzW2ldLCAxKTsgfQogICAgdmlzaXRfYWxsKHBfcm9vdCwgcHJpbnRfa2V5KTsKICAgIGFzc2VydChudWxscHRyID09IHBfcm9vdCk7IC8vIHBfcm9vdCB3YXMgcGFzc2VkIGJ5IHZhbHVlIGFuZCBub3RoaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBoYXMgY2hhbmdlZCwgbW9yZW92ZXIgdGhlIG1lbW9yeSBhbGxvY2F0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gaW5jb3JyZWN0X3dpa2k6Omluc2VydCBhcmUgYWxsIGxlYWtlZAoKICAgIC8vIGNvcnJlY3QgaW5zZXJ0CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47ICsraSkgeyBpbnNlcnQocF9yb290LCBrZXlzW2ldLCAxKTsgfQogICAgdmlzaXRfYWxsKHBfcm9vdCwgcHJpbnRfa2V5KTsKCiAgICByZXR1cm4gMDsKfQ==