mirror of
https://github.com/lifegpc/c-utils.git
synced 2026-06-06 13:18:57 +08:00
116 lines
3.9 KiB
C++
116 lines
3.9 KiB
C++
#ifndef _UTIL_BINARY_TREE_H
|
|
#define _UTIL_BINARY_TREE_H
|
|
#include <functional>
|
|
#include <stddef.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
#include "linked_queue.h"
|
|
|
|
template <typename T>
|
|
struct BinaryTree {
|
|
T data;
|
|
struct BinaryTree* left;
|
|
struct BinaryTree* right;
|
|
};
|
|
|
|
template <typename T>
|
|
void binary_tree_clear(struct BinaryTree<T>*& top, std::function<void(T)> free_func = std::function<void(T)>()) {
|
|
if (!top) return;
|
|
binary_tree_dfs(top, [&free_func](struct BinaryTree<T>* node) {
|
|
if (free_func) {
|
|
free_func(node->data);
|
|
}
|
|
node->left = nullptr;
|
|
node->right = nullptr;
|
|
free(node);
|
|
});
|
|
top = nullptr;
|
|
}
|
|
|
|
template <typename T, class F>
|
|
inline void binary_tree_clear(struct BinaryTree<T>*& top, F free_func) {
|
|
binary_tree_clear(top, std::function<void(T)>(free_func));
|
|
}
|
|
|
|
template <typename T, typename... Args>
|
|
void binary_tree_dfs(struct BinaryTree<T>* top, std::function<void(struct BinaryTree<T>*, 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 <typename T, class F, typename... Args>
|
|
inline void binary_tree_dfs(struct BinaryTree<T>* top, F callback, Args... args) {
|
|
binary_tree_dfs(top, std::function<void(struct BinaryTree<T>*, Args...)>(callback), args...);
|
|
}
|
|
|
|
#define binary_tree_lrn binary_tree_dfs
|
|
|
|
template <typename T, typename... Args>
|
|
void binary_tree_lnr(struct BinaryTree<T>* top, std::function<void(struct BinaryTree<T>*, 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 <typename T, class F, typename... Args>
|
|
inline void binary_tree_lnr(struct BinaryTree<T>* top, F callback, Args... args) {
|
|
binary_tree_lnr(top, std::function<void(struct BinaryTree<T>*, Args...)>(callback), args...);
|
|
}
|
|
|
|
template <typename T, typename... Args>
|
|
void binary_tree_nlr(struct BinaryTree<T>* top, std::function<void(struct BinaryTree<T>*, 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 <typename T, class F, typename... Args>
|
|
inline void binary_tree_nlr(struct BinaryTree<T>* top, F callback, Args... args) {
|
|
binary_tree_nlr(top, std::function<void(struct BinaryTree<T>*, Args...)>(callback), args...);
|
|
}
|
|
|
|
template <typename T, typename... Args>
|
|
void binary_tree_bfs(struct BinaryTree<T>* top, std::function<void(struct BinaryTree<T>*, Args...)> callback, Args... args) {
|
|
if (!top) return;
|
|
struct LinkedQueue<struct BinaryTree<T>*> queue;
|
|
linked_queue_init(queue);
|
|
linked_queue_push(queue, top);
|
|
struct BinaryTree<T>* 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 <typename T, class F, typename... Args>
|
|
inline void binary_tree_bfs(struct BinaryTree<T>* top, F callback, Args... args) {
|
|
binary_tree_bfs(top, std::function<void(struct BinaryTree<T>*, Args...)>(callback), args...);
|
|
}
|
|
|
|
template <typename T>
|
|
struct BinaryTree<T>* binary_tree_new(T data) {
|
|
struct BinaryTree<T>* node = (struct BinaryTree<T>*)malloc(sizeof(struct BinaryTree<T>));
|
|
if (!node) return nullptr;
|
|
node->data = data;
|
|
node->left = nullptr;
|
|
node->right = nullptr;
|
|
return node;
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool binary_tree_is_leaf(struct BinaryTree<T>* node) {
|
|
return node->left == nullptr && node->right == nullptr;
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool binary_tree_node_is_full(struct BinaryTree<T>* node) {
|
|
return node->left != nullptr && node->right != nullptr;
|
|
}
|
|
|
|
#endif
|