Kylin/DataStructure/BinarySearchTree.h

241 lines
7.6 KiB
C
Raw Normal View History

2023-12-27 10:29:16 +08:00
#ifndef BINARYSEARCHTREE_H
#define BINARYSEARCHTREE_H
#include "BinaryTree.h"
namespace Kylin {
/**
* @brief The BinarySearchTree class.
* 1.
* 2.
* 3.
* 4.no duplicate nodes
*/
template <typename T>
class BinarySearchTree : public BinaryTree<T> {
public:
using NodeT = BinaryTreeNode<T>;
class ConstIterator : public Object {
public:
ConstIterator() = default;
ConstIterator(NodeT *pos) : pos(pos) {
}
ConstIterator &operator++() {
if (pos == nullptr) return *this;
if (pos->right) {
pos = pos->right;
while (pos->left) pos = pos->left;
} else {
while ((pos->parent != nullptr) && (dynamic_cast<NodeT *>(pos->parent)->right == pos))
pos = dynamic_cast<NodeT *>(pos->parent);
pos = dynamic_cast<NodeT *>(pos->parent);
}
return *this;
}
const T &operator*() {
return pos->value;
}
bool operator!=(const ConstIterator &iter) {
return pos != iter.pos;
}
const NodeT *pos = nullptr;
};
ConstIterator begin() const {
auto node = this->root();
while (node->left != nullptr) node = node->left;
return ConstIterator(node);
}
ConstIterator end() const {
return ConstIterator();
}
BinaryTreeNode<T> *find(const T &value) const override {
return find(dynamic_cast<BinaryTreeNode<T> *>(this->m_root), value);
}
T maximum() {
auto node = maximumOfNode(dynamic_cast<BinaryTreeNode<T> *>(this->m_root));
if (node != nullptr)
return node->value;
else
return T();
}
T minimum() {
auto node = minimumOfNode(dynamic_cast<BinaryTreeNode<T> *>(this->m_root));
if (node != nullptr)
return node->value;
else
return T();
}
/**
* @brief Find the maxinum node which these node are smaller than arg node.
* @param node
* @return
*/
BinaryTreeNode<T> *predecessor(BinaryTreeNode<T> *node) {
if (node == nullptr) return node;
if (node->left != nullptr) return maximumOfNode(node->left);
auto parent = dynamic_cast<BinaryTreeNode<T> *>(node->parent);
while ((parent != nullptr) && (parent->left == node)) {
node = parent;
parent = dynamic_cast<BinaryTreeNode<T> *>(node->parent);
}
return parent;
}
/**
* @brief successor Find the mininum node which these node are bigger than arg node.
* @param node
* @return
*/
BinaryTreeNode<T> *successor(BinaryTreeNode<T> *node) {
if (node == nullptr) return node;
if (node->right != nullptr) return minimumOfNode(node->right);
auto parent = dynamic_cast<BinaryTreeNode<T> *>(node->parent);
if (node->right == nullptr && parent->left == node) return parent;
while ((parent != nullptr) && (parent->right == node)) {
node = parent;
parent = dynamic_cast<BinaryTreeNode<T> *>(node->parent);
}
return parent;
}
bool insert(const T &value) {
auto node = new NodeT(value);
if (node == nullptr) return false;
return insert(node);
}
void remove(const T &value) {
BinaryTreeNode<T> *node = find(value);
if (node == nullptr) return;
auto del = remove(node, dynamic_cast<BinaryTreeNode<T> *>(this->m_root));
if (del != nullptr) delete del;
}
protected:
/**
* @brief find
* @param node the root of sub-tree
* @param value
* @return
*/
BinaryTreeNode<T> *find(BinaryTreeNode<T> *node, const T &value) const {
if ((node == nullptr) || (node->value == value)) return node;
if (value < node->value)
return find(node->left, value);
else if (value > node->value)
return find(node->right, value);
return nullptr;
}
BinaryTreeNode<T> *find1(BinaryTreeNode<T> *node, const T &value) const {
while ((node != nullptr) && (node->value != value)) {
if (value > node->value)
node = node->right;
else if (value < node->value)
node = node->left;
}
return node;
}
BinaryTreeNode<T> *maximumOfNode(BinaryTreeNode<T> *node) {
if (node == nullptr) return node;
while (node->right != nullptr) node = node->right;
return node;
}
/**
* @brief minimumOfNode Find the maxinum node of the sub-tree which root is arg node.
* @param node
* @return
*/
BinaryTreeNode<T> *minimumOfNode(BinaryTreeNode<T> *node) {
if (node == nullptr) return node;
while (node->left != nullptr) node = node->left;
return node;
}
/**
* @brief insert Insert node to the sub-tree which root is arg node.
*/
bool insert(NodeT *node) {
if (node == nullptr) return false;
auto n = reinterpret_cast<NodeT **>(&(this->m_root));
NodeT *parent = nullptr;
while (*n != nullptr) {
parent = *n;
n = (node->value <= (*n)->value) ? &((*n)->left) : &((*n)->right);
}
node->parent = parent;
*n = node;
return true;
}
/**
* @brief remove
* @param node The tree which we want remove
* @param tree
* @return
*/
BinaryTreeNode<T> *remove(BinaryTreeNode<T> *node, BinaryTreeNode<T> *tree) {
auto parent = dynamic_cast<BinaryTreeNode<T> *>(node->parent);
if ((node->left == nullptr) || (node->right == nullptr)) {
}
if ((node->left == nullptr) && (node->right == nullptr)) { // node没有左右子树
if (parent->left == node)
parent->left = nullptr;
else
parent->right = nullptr;
} else if ((node->left != nullptr) && (node->right == nullptr)) {
if (parent->left == node)
parent->left = node->left;
else
parent->right = node->left;
} else if ((node->left == nullptr) && (node->right != nullptr)) {
if (parent->left == node)
parent->left = node->right;
else
parent->right = node->right;
} else {
auto n = successor(node);
n->left = node->left;
if (parent->left == node)
parent->left = node->right;
else
parent->right = node->right;
}
return node;
/*
BinaryTreeNode<T> *del = nullptr;
BinaryTreeNode<T> *n = nullptr;
if((node->left==nullptr)||(node->right==nullptr)) del = node;
else del = successor(node);
if(del->left!=nullptr) n = del->left;
else n =del->right;
if(n != nullptr) n->parent = del->parent;
if(del->parent==nullptr) tree = n;
else if (del == del->parent->left) del->parent->left=n;
else del->parent->right=n;
if(del!=node) tree->value=del->value;
return del;
*/
}
};
} // namespace Kylin
#endif // BINARYSEARCHTREE_H