This is a follow-up to
changes:
- Used raw pointers rather than std::unique_ptr
- const correctness
- Made variable names more beautiful
- implemented 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);
}
};