This is a follow-up toRecursive binary search treechanges:Used raw pointers rather than std::unique_ptrconst correctnessMade variable names more beautifulimplemented at()How can I improve this code?template<typename K, typename V>class binarySearchTree {    struct Node {        K key;        V val;        Node* left;        Node* right;        Node(const K& k, const V& v) : key(k), val(v), left(nullptr), right(nullptr) { }    };    void check(Node* node) {        if (node == nullptr) {            throw std::runtime_error(No node);        }    }    V& at(Node* node, const K& key) {        if (node == nullptr) {            throw std::runtime_error(no node);        }        if (key < node->key) {            return at(node->left,key);        } else if (key > node->key) {            return at(node->right,key);        }        return node->val;    }    V& get(Node*& node, const K& key) {        if (node == nullptr) {            node = new Node{key,{}};            ++n;            return node->val;        }        if (key < node->key) {            return get(node->left,key);        } else if (key > node->key) {            return get(node->right,key);        } else {            return node->val;        }    }    Node* min(Node* node) const {        if (node->left == nullptr) {            return node;        }        return min(node->left);    }    Node* max(Node* node) const {        if (node->right == nullptr) {            return node;        }        return max(node->right);    }    Node* remove_min(Node*& node) {        if (node->left == nullptr) {            Node* x = node->right;            delete node;            --n;            return x;        }        node->left = remove_min(node->left);        return node;    }    Node* remove_max(Node*& node) {        if (node->right == nullptr) {            Node* x = node->left;            delete node;            --n;            return x;        }        node->right = remove_max(node->right);        return node;    }    Node* remove(Node*& node, K key) {        check(node);        if      (key < node->key){            node->left = remove(node->left,  key);        } else if (key > node->key){            node->right = remove(node->right, key);        } else {            if (node->right == nullptr) {                Node* x =  node->left;                delete node;                --n;                return x;            }            if (node->left == nullptr) {                Node* x = node->right;                delete node;                --n;                return x;            }            Node* old = node;            node = min(old->right);            node->right = remove_min(old->right);            node->left = old->left;            delete old;            --n;        }        return node;    }    void traverse(Node* node) {        if (node == nullptr) {            return;        }        traverse(node->left);        std::cout << node->key <<   << node->val << '\n';        traverse(node->right);    }    void destruct(Node* node) {        if (node == nullptr) {            return;        }        destruct(node->left);        destruct(node->right);        delete node;    }    Node* root;    std::size_t n;public:    binarySearchTree() :root{nullptr},n{0} { }    //no compy/move    std::size_t size() const {        return n;    }    V& at(const K& key) {        return at(root,key);    }    V& operator[](const K& key) {        return get(root,key);    }    K& min() {        check(root);        return min(root)->key;;    }    K& max() {        check(root);        return max(root)->key;    }    void remove_min() {        check(root);        root = remove_min(root);    }    void remove_max() {        check(root);        root = remove_max(root);    }    void remove(K key) {        root = remove(root, key);    }    void traverse() {        traverse(root);    }    ~binarySearchTree() {        destruct(root);    }};
Recursive binary search tree - follow-up
c++;c++11;tree
In addition to ratchet freak's answer. These private methods:V& at(Node* node, const K& key)V& get(Node*& node, const K& key)Node* min(Node* node) constNode* max(Node* node) constNode* remove_min(Node*& node)Node* remove_max(Node*& node)Node* remove(Node*& node, K key)void traverse(Node* node)can and should easily be reworked into members of Node. Try it and see how much less typing of node-> it will result in. This method:void destruct(Node* node)should really just be the destructor ~Node(), and in ~binarySearchTree() simply call delete root. Calling delete on a null pointer is perfectly fine so you don't even need to check for null here. So you only really need this:    ~Node() {        delete left;        delete right;    }    ~binarySearchTree(){        delete root;    }to clean up after you. Please note that if you do this, you need to completely detach a node from the tree in your remove* methods before deleting it, otherwise the children will go too. But I find this to be better style anyway; detach, re-link tree, then delete.Also you're being inconsistent with your naming, you have Node and binarySearchTree. Either Node should be node (first letter of first word is lower case), or binarySearchTree should be BinarySearchTree (first letter of all words is upper case). Personally, I prefer the later.