Kylin/DataStructure/BinarySearchTree.h
2023-12-27 10:29:16 +08:00

241 lines
7.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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