#ifndef _UTIL_BINARY_TREE_H #define _UTIL_BINARY_TREE_H #include #include #include #include #include "linked_queue.h" template struct BinaryTree { T data; struct BinaryTree* left; struct BinaryTree* right; }; template void binary_tree_clear(struct BinaryTree*& top, std::function free_func = std::function()) { if (!top) return; binary_tree_dfs(top, [&free_func](struct BinaryTree* node) { if (free_func) { free_func(node->data); } node->left = nullptr; node->right = nullptr; free(node); }); top = nullptr; } template inline void binary_tree_clear(struct BinaryTree*& top, F free_func) { binary_tree_clear(top, std::function(free_func)); } template void binary_tree_dfs(struct BinaryTree* top, std::function*, Args...)> callback, Args... args) { if (!top) return; if (top->left) binary_tree_dfs(top->left, callback, args...); if (top->right) binary_tree_dfs(top->right, callback, args...); callback(top, args...); } template inline void binary_tree_dfs(struct BinaryTree* top, F callback, Args... args) { binary_tree_dfs(top, std::function*, Args...)>(callback), args...); } #define binary_tree_lrn binary_tree_dfs template void binary_tree_lnr(struct BinaryTree* top, std::function*, Args...)> callback, Args... args) { if (!top) return; if (top->left) binary_tree_lnr(top->left, callback, args...); callback(top, args...); if (top->right) binary_tree_lnr(top->right, callback, args...); } template inline void binary_tree_lnr(struct BinaryTree* top, F callback, Args... args) { binary_tree_lnr(top, std::function*, Args...)>(callback), args...); } template void binary_tree_nlr(struct BinaryTree* top, std::function*, Args...)> callback, Args... args) { if (!top) return; callback(top, args...); if (top->left) binary_tree_nlr(top->left, callback, args...); if (top->right) binary_tree_nlr(top->right, callback, args...); } template inline void binary_tree_nlr(struct BinaryTree* top, F callback, Args... args) { binary_tree_nlr(top, std::function*, Args...)>(callback), args...); } template void binary_tree_bfs(struct BinaryTree* top, std::function*, Args...)> callback, Args... args) { if (!top) return; struct LinkedQueue*> queue; linked_queue_init(queue); linked_queue_push(queue, top); struct BinaryTree* tmp; while (linked_queue_pop(queue, tmp)) { if (tmp->left) linked_queue_push(queue, tmp->left); if (tmp->right) linked_queue_push(queue, tmp->right); callback(tmp, args...); } } template inline void binary_tree_bfs(struct BinaryTree* top, F callback, Args... args) { binary_tree_bfs(top, std::function*, Args...)>(callback), args...); } template struct BinaryTree* binary_tree_new(T data) { struct BinaryTree* node = (struct BinaryTree*)malloc(sizeof(struct BinaryTree)); if (!node) return nullptr; node->data = data; node->left = nullptr; node->right = nullptr; return node; } template inline bool binary_tree_is_leaf(struct BinaryTree* node) { return node->left == nullptr && node->right == nullptr; } template inline bool binary_tree_node_is_full(struct BinaryTree* node) { return node->left != nullptr && node->right != nullptr; } #endif