#ifndef BINARYTREE_H #define BINARYTREE_H #include "DynamicArray.h" #include "LinkedQueue.h" #include "SharedPointer.h" #include "Tree.h" namespace Kylin { template class BinaryTreeNode : public TreeNode { public: BinaryTreeNode(const T &value, BinaryTreeNode *parent = nullptr) : TreeNode(value, parent) {} BinaryTreeNode *left = nullptr; BinaryTreeNode *right = nullptr; }; template class BinaryTree : public Tree { public: enum Pos { //子树节点位置 Any, Left, Right }; enum Traversal { //遍历顺序 Preorder, //先序遍历 Inorder, //中序遍历 Postorder, //后续遍历 Levelorder //层次遍历 }; class Iterator { public: Iterator(BinaryTreeNode *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 *m_pos = nullptr; LinkedQueue *> m_queue; }; BinaryTree() = default; BinaryTree(const BinaryTree &other) { this->m_root = clone(dynamic_cast *>(other.m_root)); } BinaryTree(BinaryTree &&other) { this->m_root = other.m_root; other.m_root = nullptr; } ~BinaryTree() { clear(); } virtual BinaryTreeNode *root() const { return dynamic_cast *>(this->m_root); } int degree() const { return degree(dynamic_cast *>(this->m_root)); } int height() const { return height(dynamic_cast *>(this->m_root)); } int count() const { return count(dynamic_cast *>(this->m_root)); } void clear() { free(dynamic_cast *>(this->m_root)); this->m_root = nullptr; } BinaryTree operator+(const BinaryTree &other) { BinaryTree result; result.m_root = add(dynamic_cast *>(this->m_root), dynamic_cast *>(other.m_root)); return result; } BinaryTree &operator=(const BinaryTree &other) { if (&other != this) { clear(); this->m_root = clone(other.m_root); } return *this; } bool operator==(const BinaryTree &other) const { return equal(dynamic_cast *>(this->m_root), dynamic_cast *>(other.m_root)); } bool operator!=(const BinaryTree &other) const { return !(*this == other); } DynamicArray traversal(Traversal order) { LinkedQueue *> queue; traversal(order, queue); auto size = queue.size(); DynamicArray result(size); for (size_t i = 0; i < size; i++) { result[i] = queue.dequeue()->value; } return result; } bool insert(TreeNode *node) override { return insert(node, Any); } virtual bool insert(TreeNode *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 *>(node), dynamic_cast *>(node->parent), pos); } bool insert(const T &value, TreeNode *parent, Pos pos) { bool ret = false; auto n = new BinaryTreeNode(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 *find(const T &value) const { return find(dynamic_cast *>(this->m_root), value); } bool find(TreeNode *node) const { return find(dynamic_cast *>(this->m_root), dynamic_cast *>(node)); } BinaryTree remove(const T &value) { auto node = find(dynamic_cast *>(this->m_root), value); if (node == nullptr) return BinaryTree(); auto parent = dynamic_cast *>(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; } BinaryTree remove(TreeNode *node) { auto status = find(dynamic_cast *>(this->m_root), dynamic_cast *>(node)); if (!status) return BinaryTree(); auto parent = dynamic_cast *>(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 *threaded(Traversal order) { BinaryTreeNode *ret = nullptr; LinkedQueue *> queue; traversal(order, queue); ret = connect(queue); this->m_root = nullptr; return ret; } Iterator begin() { return Iterator(dynamic_cast *>(this->m_root)); } Iterator end() { return Iterator(nullptr); } protected: BinaryTreeNode *find(BinaryTreeNode *node, const T &value) const { BinaryTreeNode *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 *node, BinaryTreeNode *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 *node, BinaryTreeNode *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 *node) { if (node == nullptr) return; if (node->left != nullptr) { free(node->left); } if (node->right != nullptr) { free(node->right); } delete node; } int count(BinaryTreeNode *node) const { if (node == nullptr) return 0; int ret = 1; ret += count(node->left); ret += count(node->right); return ret; } size_t height(BinaryTreeNode *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 *node) const { if (node == nullptr) return 0; int ret = 0; ret = (!!node->left) + (!!node->right); BinaryTreeNode *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 *clone(BinaryTreeNode *node) const { if (node == nullptr) return nullptr; auto ret = new BinaryTreeNode(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 *lh, const BinaryTreeNode *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 *add(BinaryTreeNode *lh, BinaryTreeNode *rh) const { BinaryTreeNode *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(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 *> &queue) { switch (order) { case Preorder: preOrderTraversal(dynamic_cast *>(this->m_root), queue); break; case Inorder: inOrderTraversal(dynamic_cast *>(this->m_root), queue); break; case Postorder: postOrderTraversal(dynamic_cast *>(this->m_root), queue); break; case Levelorder: levelOrderTraversal(dynamic_cast *>(this->m_root), queue); break; default: break; } } /** * @brief 先序遍历 */ void preOrderTraversal(BinaryTreeNode *node, LinkedQueue *> &queue) { if (node == nullptr) return; queue.enqueue(node); preOrderTraversal(node->left, queue); preOrderTraversal(node->right, queue); } /** * @brief 中序遍历 */ void inOrderTraversal(BinaryTreeNode *node, LinkedQueue *> &queue) { if (node == nullptr) return; inOrderTraversal(node->left, queue); queue.enqueue(node); inOrderTraversal(node->right, queue); } void postOrderTraversal(BinaryTreeNode *node, LinkedQueue *> &queue) { if (node == nullptr) return; postOrderTraversal(node->left, queue); postOrderTraversal(node->right, queue); queue.enqueue(node); } /** * @brief 层次遍历 */ void levelOrderTraversal(BinaryTreeNode *node, LinkedQueue *> &queue) { if (node == nullptr) return; LinkedQueue *> 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 *connect(LinkedQueue *> &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