Kylin/DataStructure/BinaryTree.h

413 lines
13 KiB
C
Raw Normal View History

2023-12-27 10:29:16 +08:00
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include "DynamicArray.h"
#include "LinkedQueue.h"
#include "SharedPointer.h"
#include "Tree.h"
namespace Kylin {
template <typename T>
class BinaryTreeNode : public TreeNode<T> {
public:
BinaryTreeNode(const T &value, BinaryTreeNode *parent = nullptr) : TreeNode<T>(value, parent) {}
BinaryTreeNode *left = nullptr;
BinaryTreeNode *right = nullptr;
};
template <typename T>
class BinaryTree : public Tree<T> {
public:
enum Pos { //子树节点位置
Any,
Left,
Right
};
enum Traversal { //遍历顺序
Preorder, //先序遍历
Inorder, //中序遍历
Postorder, //后续遍历
Levelorder //层次遍历
};
class Iterator {
public:
Iterator(BinaryTreeNode<T> *pos) : m_pos(pos) {}
bool operator!=(const Iterator &other) { return (m_pos != other.m_pos); }
T &operator*() { return m_pos->value; }
Iterator &operator++() {
if (m_pos->left != nullptr) m_queue.enqueue(m_pos->left);
if (m_pos->right != nullptr) m_queue.enqueue(m_pos->right);
m_pos = m_queue.empty() ? nullptr : m_queue.dequeue();
return *this;
}
private:
BinaryTreeNode<T> *m_pos = nullptr;
LinkedQueue<BinaryTreeNode<T> *> m_queue;
};
BinaryTree() = default;
BinaryTree(const BinaryTree &other) { this->m_root = clone(dynamic_cast<BinaryTreeNode<T> *>(other.m_root)); }
BinaryTree(BinaryTree &&other) {
this->m_root = other.m_root;
other.m_root = nullptr;
}
~BinaryTree() { clear(); }
virtual BinaryTreeNode<T> *root() const { return dynamic_cast<BinaryTreeNode<T> *>(this->m_root); }
int degree() const { return degree(dynamic_cast<BinaryTreeNode<T> *>(this->m_root)); }
int height() const { return height(dynamic_cast<BinaryTreeNode<T> *>(this->m_root)); }
int count() const { return count(dynamic_cast<BinaryTreeNode<T> *>(this->m_root)); }
void clear() {
free(dynamic_cast<BinaryTreeNode<T> *>(this->m_root));
this->m_root = nullptr;
}
BinaryTree operator+(const BinaryTree &other) {
BinaryTree result;
result.m_root =
add(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), dynamic_cast<BinaryTreeNode<T> *>(other.m_root));
return result;
}
BinaryTree<T> &operator=(const BinaryTree &other) {
if (&other != this) {
clear();
this->m_root = clone(other.m_root);
}
return *this;
}
bool operator==(const BinaryTree<T> &other) const {
return equal(dynamic_cast<const BinaryTreeNode<T> *>(this->m_root),
dynamic_cast<const BinaryTreeNode<T> *>(other.m_root));
}
bool operator!=(const BinaryTree<T> &other) const { return !(*this == other); }
DynamicArray<T> traversal(Traversal order) {
LinkedQueue<BinaryTreeNode<T> *> queue;
traversal(order, queue);
auto size = queue.size();
DynamicArray<T> result(size);
for (size_t i = 0; i < size; i++) {
result[i] = queue.dequeue()->value;
}
return result;
}
bool insert(TreeNode<T> *node) override { return insert(node, Any); }
virtual bool insert(TreeNode<T> *node, Pos pos) {
if (node == nullptr) return false;
if (this->m_root == nullptr) {
this->m_root = node;
node->parent = nullptr;
return true;
}
auto status = find(node->parent);
if (!status) return false; //没有找到父节点
return insert(dynamic_cast<BinaryTreeNode<T> *>(node), dynamic_cast<BinaryTreeNode<T> *>(node->parent), pos);
}
bool insert(const T &value, TreeNode<T> *parent, Pos pos) {
bool ret = false;
auto n = new BinaryTreeNode<T>(value);
if (n == nullptr) THROW_EXCEPTION(NoEnoughMemoryException, "There is no enough memory to insert an element.");
n->parent = parent;
ret = insert(n, pos);
if (!ret) {
delete n;
}
return ret;
}
virtual BinaryTreeNode<T> *find(const T &value) const {
return find(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), value);
}
bool find(TreeNode<T> *node) const {
return find(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), dynamic_cast<BinaryTreeNode<T> *>(node));
}
BinaryTree<T> remove(const T &value) {
auto node = find(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), value);
if (node == nullptr) return BinaryTree<T>();
auto parent = dynamic_cast<BinaryTreeNode<T> *>(node->parent);
if (parent->left == node) {
parent->left = nullptr;
} else if (parent->right == node) {
parent->right = nullptr;
}
node->parent = nullptr;
BinaryTree<T> result;
result.m_root = node;
return result;
}
BinaryTree<T> remove(TreeNode<T> *node) {
auto status = find(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), dynamic_cast<BinaryTreeNode<T> *>(node));
if (!status) return BinaryTree();
auto parent = dynamic_cast<BinaryTreeNode<T> *>(node->parent);
if (parent->left == node) {
parent->left = nullptr;
} else if (parent->right == node) {
parent->right = nullptr;
}
node->parent = nullptr;
BinaryTree result;
result.m_root = node;
return result;
}
/**
* @brief 线
*/
BinaryTreeNode<T> *threaded(Traversal order) {
BinaryTreeNode<T> *ret = nullptr;
LinkedQueue<BinaryTreeNode<T> *> queue;
traversal(order, queue);
ret = connect(queue);
this->m_root = nullptr;
return ret;
}
Iterator begin() { return Iterator(dynamic_cast<BinaryTreeNode<T> *>(this->m_root)); }
Iterator end() { return Iterator(nullptr); }
protected:
BinaryTreeNode<T> *find(BinaryTreeNode<T> *node, const T &value) const {
BinaryTreeNode<T> *ret = nullptr;
if (node != nullptr) {
if (node->value == value) {
ret = node;
} else {
if (ret == nullptr) {
ret = find(node->left, value);
}
if (ret == nullptr) {
ret = find(node->right, value);
}
}
}
return ret;
}
/**
* @brief node为根结点的树中查找obj结点
*/
bool find(BinaryTreeNode<T> *node, BinaryTreeNode<T> *obj) const {
if ((node == nullptr) || (obj == nullptr)) return false;
if (node == obj) return true;
bool ret = find(node->left, obj);
if (!ret) ret = find(node->right, obj);
return ret;
}
/**
* @brief node插入到parent的pos节点
*/
bool insert(BinaryTreeNode<T> *node, BinaryTreeNode<T> *parent, Pos pos) {
bool ret = false;
if (pos == Any) {
if (parent->left == nullptr) {
parent->left = node;
ret = true;
} else if (parent->right == nullptr) {
parent->right = node;
ret = true;
}
} else if (pos == Left) {
if (parent->left == nullptr) {
parent->left = node;
ret = true;
}
} else if (pos == Right) {
if (parent->right == nullptr) {
parent->right = node;
ret = true;
}
}
return ret;
}
void free(BinaryTreeNode<T> *node) {
if (node == nullptr) return;
if (node->left != nullptr) {
free(node->left);
}
if (node->right != nullptr) {
free(node->right);
}
delete node;
}
int count(BinaryTreeNode<T> *node) const {
if (node == nullptr) return 0;
int ret = 1;
ret += count(node->left);
ret += count(node->right);
return ret;
}
size_t height(BinaryTreeNode<T> *node) const {
if (node == nullptr) return 0;
size_t ret = 0;
ret = height(node->left);
auto rightHeight = height(node->right);
if (rightHeight > ret) ret = rightHeight;
return ret + 1;
}
int degree(BinaryTreeNode<T> *node) const {
if (node == nullptr) return 0;
int ret = 0;
ret = (!!node->left) + (!!node->right);
BinaryTreeNode<T> *nodes[] = {node->left, node->right};
for (int i = 0; (i < 2) && (ret < 2); i++) {
int d = degree(nodes[i]);
if (d > ret) {
d = ret;
}
}
return ret;
}
BinaryTreeNode<T> *clone(BinaryTreeNode<T> *node) const {
if (node == nullptr) return nullptr;
auto ret = new BinaryTreeNode<T>(node->value);
ret->left = clone(node->left);
if (ret->left != nullptr) {
ret->left->parent = ret;
}
ret->right = clone(node->right);
if (ret->right != nullptr) {
ret->right->parent = ret;
}
return ret;
}
bool equal(const BinaryTreeNode<T> *lh, const BinaryTreeNode<T> *rh) const {
bool ret = false;
if (lh == rh) {
ret = true;
} else if (lh != nullptr && rh != nullptr) {
ret = (lh->value == rh->value) && equal(lh->left, rh->left) && equal(lh->right, rh->right);
}
return ret;
}
BinaryTreeNode<T> *add(BinaryTreeNode<T> *lh, BinaryTreeNode<T> *rh) const {
BinaryTreeNode<T> *ret = nullptr;
if ((lh != nullptr) && (rh == nullptr)) {
ret = clone(lh);
} else if ((lh == nullptr) && (rh != nullptr)) {
ret = clone(rh);
} else if ((lh != nullptr) && (rh != nullptr)) {
ret = new BinaryTreeNode<T>(lh->value + rh->value);
ret->left = add(lh->left, rh->left);
ret->right = add(lh->right, rh->right);
if (ret->left != nullptr) ret->left->parent = ret;
if (ret->right != nullptr) ret->right->parent = ret;
}
return ret;
}
void traversal(Traversal order, LinkedQueue<BinaryTreeNode<T> *> &queue) {
switch (order) {
case Preorder:
preOrderTraversal(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), queue);
break;
case Inorder:
inOrderTraversal(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), queue);
break;
case Postorder:
postOrderTraversal(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), queue);
break;
case Levelorder:
levelOrderTraversal(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), queue);
break;
default:
break;
}
}
/**
* @brief
*/
void preOrderTraversal(BinaryTreeNode<T> *node, LinkedQueue<BinaryTreeNode<T> *> &queue) {
if (node == nullptr) return;
queue.enqueue(node);
preOrderTraversal(node->left, queue);
preOrderTraversal(node->right, queue);
}
/**
* @brief
*/
void inOrderTraversal(BinaryTreeNode<T> *node, LinkedQueue<BinaryTreeNode<T> *> &queue) {
if (node == nullptr) return;
inOrderTraversal(node->left, queue);
queue.enqueue(node);
inOrderTraversal(node->right, queue);
}
void postOrderTraversal(BinaryTreeNode<T> *node, LinkedQueue<BinaryTreeNode<T> *> &queue) {
if (node == nullptr) return;
postOrderTraversal(node->left, queue);
postOrderTraversal(node->right, queue);
queue.enqueue(node);
}
/**
* @brief
*/
void levelOrderTraversal(BinaryTreeNode<T> *node, LinkedQueue<BinaryTreeNode<T> *> &queue) {
if (node == nullptr) return;
LinkedQueue<BinaryTreeNode<T> *> temp;
temp.enqueue(node);
while (temp.length() > 0) {
auto n = temp.dequeue();
if (n->left != nullptr) temp.enqueue(n->left);
if (n->right != nullptr) temp.enqueue(n->right);
queue.enqueue(n);
}
}
/**
* @brief queue的BinaryTreeNode连接成双向链表
*/
BinaryTreeNode<T> *connect(LinkedQueue<BinaryTreeNode<T> *> &queue) {
if (queue.empty()) return nullptr;
auto slider = queue.dequeue();
auto ret = slider;
slider->left = nullptr;
while (!queue.empty()) {
slider->right = queue.head();
queue.head()->left = slider;
slider = queue.dequeue();
}
slider->right = nullptr;
return ret;
}
};
} // namespace Kylin
#endif // BINARYTREE_H