Kylin/DataStructure/GeneralTree.h

213 lines
6.8 KiB
C
Raw Normal View History

2023-12-27 10:29:16 +08:00
#ifndef GENERALTREE_H
#define GENERALTREE_H
#include "LinkedList.h"
#include "LinkedQueue.h"
#include "Tree.h"
namespace Kylin {
template <typename T>
class GeneralTreeNode : public TreeNode<T> {
public:
GeneralTreeNode(const T &value, TreeNode<T> *parent = nullptr) : TreeNode<T>(value, parent) {}
LinkedList<GeneralTreeNode<T> *> children;
};
template <typename T>
class GeneralTree : public Tree<T> {
public:
class Iterator {
public:
Iterator(GeneralTreeNode<T> *pos) : m_pos(pos) {}
bool operator!=(const Iterator &other) { return (m_pos != other.m_pos); }
T &operator*() { return m_pos->value; }
Iterator &operator++() {
auto &children = m_pos->children;
for (auto &child : children) {
m_queue.enqueue(child);
}
m_pos = m_queue.empty() ? nullptr : m_queue.dequeue();
return *this;
}
private:
GeneralTreeNode<T> *m_pos = nullptr;
LinkedQueue<GeneralTreeNode<T> *> m_queue;
};
GeneralTree() = default;
GeneralTree(GeneralTree &&other) {
this->m_root = other.m_root;
other.m_root = nullptr;
}
~GeneralTree() { clear(); }
bool insert(TreeNode<T> *node) {
bool ret = false;
auto n = dynamic_cast<GeneralTreeNode<T> *>(node);
if (n == nullptr) THROW_EXCEPTION(InvalidParameterException, "the node must is GeneralTreeNode.");
if (this->m_root == nullptr) {
this->m_root = node;
node->parent = nullptr;
ret = true;
} else {
if (!find(n->parent)) return false;
auto parent = dynamic_cast<GeneralTreeNode<T> *>(node->parent);
parent->children.append(n);
ret = true;
}
return ret;
}
/**
* @brief TreeNode的地址nullptr
*/
GeneralTreeNode<T> *insert(const T &value, TreeNode<T> *parent) {
auto ret = new GeneralTreeNode<T>(value, parent);
if (ret == nullptr)
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to insert an element.");
bool status = insert(ret);
if (!status) {
delete ret;
ret = nullptr;
}
return ret;
}
GeneralTree<T> remove(const T &value) {
auto node = find(value);
return node == nullptr ? GeneralTree<T>() : remove(node);
}
GeneralTree<T> remove(const GeneralTreeNode<T> *node) {
if (node == nullptr) return GeneralTree<T>();
GeneralTree<T> tree;
auto n = const_cast<GeneralTreeNode<T> *>(node);
if (n == this->m_root) {
this->m_root = nullptr;
tree.m_root = n;
return tree;
}
auto parent = dynamic_cast<GeneralTreeNode<T> *>(n->parent);
auto &children = parent->children;
auto pos = children.indexOf(n);
if (pos == LinkedList<T>::npos) return GeneralTree<T>();
children.removeAt(pos);
tree.m_root = n;
return tree;
}
GeneralTreeNode<T> *find(const T &value) const {
return find(dynamic_cast<GeneralTreeNode<T> *>(this->m_root), value);
}
bool find(TreeNode<T> *node) const override {
return find(dynamic_cast<GeneralTreeNode<T> *>(this->m_root),
dynamic_cast<GeneralTreeNode<T> *>(node));
}
GeneralTreeNode<T> *root() const { return dynamic_cast<GeneralTreeNode<T> *>(this->m_root); }
int count() const { return count(dynamic_cast<GeneralTreeNode<T> *>(this->m_root)); }
int degree() const { return degree(dynamic_cast<GeneralTreeNode<T> *>(this->m_root)); }
int height() const { return height(dynamic_cast<GeneralTreeNode<T> *>(this->m_root)); }
void clear() {
destroy(dynamic_cast<GeneralTreeNode<T> *>(this->m_root));
this->m_root = nullptr;
}
Iterator begin() { return Iterator(dynamic_cast<GeneralTreeNode<T> *>(this->m_root)); }
Iterator end() { return Iterator(nullptr); }
GeneralTree &operator=(GeneralTree &&other) {
if (&other != this) {
auto root(this->m_root);
this->m_root = other.m_root;
other.m_root = root;
}
return *this;
}
protected:
/**
* @brief Node为根节点的GeneralTree,value的GeneralTreeNode
*/
GeneralTreeNode<T> *find(const GeneralTreeNode<T> *node, const T &value) const {
if (node == nullptr) return nullptr;
if (node->value == value) return const_cast<GeneralTreeNode<T> *>(node);
GeneralTreeNode<T> *ret = nullptr;
auto &children = const_cast<LinkedList<GeneralTreeNode<T> *> &>(node->children);
for (auto &child : children) {
ret = find(child, value);
if (ret != nullptr) break;
}
return ret;
}
/**
* @brief find node子树中查找obj
*/
GeneralTreeNode<T> *find(const GeneralTreeNode<T> *node, const GeneralTreeNode<T> *obj) const {
if (node == nullptr) return nullptr;
if (node == obj) return const_cast<GeneralTreeNode<T> *>(node);
GeneralTreeNode<T> *result = nullptr;
auto &children = const_cast<LinkedList<GeneralTreeNode<T> *> &>(node->children);
for (auto &child : children) {
result = find(child, obj);
if (result != nullptr) break;
}
return result;
}
void destroy(GeneralTreeNode<T> *node) {
if (node == nullptr) return;
auto &children = node->children;
for (auto &child : children) {
destroy(child);
}
delete node;
}
int count(const GeneralTreeNode<T> *node) const {
if (node == nullptr) return 0;
int ret = 1;
auto &children = const_cast<LinkedList<GeneralTreeNode<T> *> &>(node->children);
for (auto &child : children) {
ret += count(child);
}
return ret;
}
int height(const GeneralTreeNode<T> *node) const {
if (node == nullptr) return 0;
int ret = 0;
auto &children = const_cast<LinkedList<GeneralTreeNode<T> *> &>(node->children);
for (auto &child : children) {
int h = height(child);
if (ret < h) ret = h;
}
return ret + 1;
}
int degree(const GeneralTreeNode<T> *node) const {
if (node == nullptr) return 0;
int ret = node->children.length();
auto &children = const_cast<LinkedList<GeneralTreeNode<T> *> &>(node->children);
for (auto &child : children) {
int d = degree(child);
if (d > ret) ret = d;
}
return ret;
}
};
} // namespace Kylin
#endif // GENERALTREE_H