mirror of
https://github.com/lifegpc/c-utils.git
synced 2026-06-18 00:45:01 +08:00
Add binary tree and binary search tree
This commit is contained in:
115
binary_tree.h
Normal file
115
binary_tree.h
Normal file
@@ -0,0 +1,115 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user