#ifndef _UTIL_BINARY_SEARCH_TREE_H #define _UTIL_BINARY_SEARCH_TREE_H #include "binary_tree.h" template struct BinarySearchTreePair { K key; V value; }; template using BinarySearchTree = BinaryTree>; template void binary_search_tree_clear(BinarySearchTree*& root, std::function free_key = std::function(), std::function free_value = std::function()) { if (free_key || free_value) { binary_tree_clear(root, [&free_key, &free_value](BinarySearchTreePair e) { if (free_key) free_key(e.key); if (free_value) free_value(e.value); }); } else { binary_tree_clear(root); } } template inline void binary_search_tree_clear(BinarySearchTree*& root, F free_key, G free_value = nullptr) { binary_search_tree_clear(root, std::function(free_key), std::function(free_value)); } template void binary_search_tree_iter(BinarySearchTree* root, std::function callback, Args... args) { binary_tree_lnr(root, [&callback](BinarySearchTree* e, Args... args) { callback(e->data.key, e->data.value, args...); }, args...); } template inline void binary_search_tree_iter(BinarySearchTree* root, F callback, Args... args) { binary_search_tree_iter(root, std::function(callback), args...); } template bool binary_search_tree_insert(BinarySearchTree*& root, K key, V value, std::function comp, std::function free_key = std::function(), std::function free_value = std::function()) { if (!root) { root = binary_tree_new>({ key, value }); if (!root) { if (free_key) free_key(key); if (free_value) free_value(value); } return root != nullptr; } BinarySearchTree* cur = root; int re = comp(key, cur->data.key); while (!binary_tree_is_leaf(cur)) { if (re == 0) { break; } if (re < 0 && !cur->left) break; if (re > 0 && !cur->right) break; cur = re < 0 ? cur->left : cur->right; re = comp(key, cur->data.key); } if (re == 0) { if (free_value) free_value(cur->data.value); if (free_key) free_key(key); cur->data.value = value; return true; } BinarySearchTree* node = binary_tree_new>({key, value}); if (!node) { if (free_key) free_key(key); if (free_value) free_value(value); return false; } if (re == -1) { cur->left = node; } else { cur->right = node; } return true; } template inline bool binary_search_tree_insert(BinarySearchTree*& root, K key, V value, F comp) { return binary_search_tree_insert(root, key, value, std::function(comp)); } template bool binary_search_tree_insert(BinarySearchTree*& root, K key, V value) { return binary_search_tree_insert(root, key, value, [](K k1, K k2) { return k1 == k2 ? 0 : k1 < k2 ? -1 : 1; }); } #endif