586 lines
14 KiB
C++
586 lines
14 KiB
C++
|
#pragma once
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <stack>
|
||
|
#include <queue>
|
||
|
|
||
|
namespace Lenyiin
|
||
|
{
|
||
|
template <class K, class V>
|
||
|
struct BSTreeNode
|
||
|
{
|
||
|
BSTreeNode(const K &key = K(), const V &value = V())
|
||
|
: _key(key), _value(value), _left(nullptr), _right(nullptr)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
K _key;
|
||
|
V _value;
|
||
|
BSTreeNode<K, V> *_left;
|
||
|
BSTreeNode<K, V> *_right;
|
||
|
};
|
||
|
|
||
|
template <class K, class V>
|
||
|
class BSTree
|
||
|
{
|
||
|
private:
|
||
|
typedef BSTreeNode<K, V> Node;
|
||
|
|
||
|
Node *_Copy(Node *root)
|
||
|
{
|
||
|
if (root == nullptr)
|
||
|
{
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
Node *cur = new Node(root->_key, root->_value);
|
||
|
cur->_left = _Copy(root->_left);
|
||
|
cur->_right = _Copy(root->_right);
|
||
|
|
||
|
return cur;
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
// 默认构造
|
||
|
BSTree()
|
||
|
: _root(nullptr)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
// 拷贝构造
|
||
|
BSTree(const BSTree<K, V> &tree)
|
||
|
{
|
||
|
_root = _Copy(tree._root);
|
||
|
}
|
||
|
|
||
|
// 非递归插入
|
||
|
// bool Insert(const K& key, const V& value)
|
||
|
//{
|
||
|
// // 如果根为空, 直接插入
|
||
|
// if (_root == nullptr)
|
||
|
// {
|
||
|
// _root = new Node(key, value);
|
||
|
// return true;
|
||
|
// }
|
||
|
|
||
|
// // 如果根不为空, 找到插入位置
|
||
|
// Node* parent = nullptr;
|
||
|
// Node* cur = _root;
|
||
|
// while (cur)
|
||
|
// {
|
||
|
// if (cur->_key > key)
|
||
|
// {
|
||
|
// parent = cur;
|
||
|
// cur = cur->_left;
|
||
|
// }
|
||
|
// else if (cur->_key < key)
|
||
|
// {
|
||
|
// parent = cur;
|
||
|
// cur = cur->_right;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// return false; // 如果相等, 表示我已经有了, 不需要插入了
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
// // 插入节点
|
||
|
// cur = new Node(key, value);
|
||
|
// if (parent->_key > key)
|
||
|
// {
|
||
|
// parent->_left = cur;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// parent->_right = cur;
|
||
|
// }
|
||
|
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
// 递归插入
|
||
|
// 辅助函数
|
||
|
Node *_insert(Node *root, const K &key, const V &value)
|
||
|
{
|
||
|
if (root == nullptr)
|
||
|
{
|
||
|
return new Node(key, value);
|
||
|
}
|
||
|
if (key < root->_key)
|
||
|
{
|
||
|
root->_left = _insert(root->_left, key, value);
|
||
|
}
|
||
|
else if (key > root->_key)
|
||
|
{
|
||
|
root->_right = _insert(root->_right, key, value);
|
||
|
}
|
||
|
return root;
|
||
|
}
|
||
|
|
||
|
// 插入
|
||
|
void Insert(const K &key, const V &value)
|
||
|
{
|
||
|
_root = _insert(_root, key, value);
|
||
|
}
|
||
|
|
||
|
// 非递归查找节点
|
||
|
// Node* Find(const K& key)
|
||
|
//{
|
||
|
// Node* cur = _root;
|
||
|
// while (cur)
|
||
|
// {
|
||
|
// if (cur->_key > key)
|
||
|
// {
|
||
|
// cur = cur->_left;
|
||
|
// }
|
||
|
// else if (cur->_key < key)
|
||
|
// {
|
||
|
// cur = cur->_right;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// return cur;
|
||
|
// }
|
||
|
// }
|
||
|
// return nullptr;
|
||
|
//}
|
||
|
|
||
|
// 递归查找节点
|
||
|
// 辅助函数
|
||
|
Node *_find(Node *root, const K &key)
|
||
|
{
|
||
|
if (root == nullptr || root->_key == key)
|
||
|
{
|
||
|
return root;
|
||
|
}
|
||
|
if (key < root->_key)
|
||
|
{
|
||
|
return _find(root->_left, key);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _find(root->_right, key);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 查找节点
|
||
|
Node *Find(const K &key)
|
||
|
{
|
||
|
return _find(_root, key);
|
||
|
}
|
||
|
|
||
|
// 非递归删除节点
|
||
|
// bool Erase(const K& key)
|
||
|
//{
|
||
|
// // 找到要删除的节点
|
||
|
// Node* parent = nullptr;
|
||
|
// Node* cur = _root;
|
||
|
// while (cur)
|
||
|
// {
|
||
|
// if (cur->_key > key)
|
||
|
// {
|
||
|
// parent = cur;
|
||
|
// cur = cur->_left;
|
||
|
// }
|
||
|
// else if (cur->_key < key)
|
||
|
// {
|
||
|
// parent = cur;
|
||
|
// cur = cur->_right;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// break;
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
// // 没找到
|
||
|
// if (cur == nullptr)
|
||
|
// {
|
||
|
// return false;
|
||
|
// }
|
||
|
|
||
|
// // 找到了
|
||
|
// // 1. 要删除的节点没有左孩子
|
||
|
// if (cur->_left == nullptr)
|
||
|
// {
|
||
|
// if (cur == _root)
|
||
|
// {
|
||
|
// _root = cur->_right;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// if (parent->_left == cur)
|
||
|
// {
|
||
|
// parent->_left = cur->_right;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// parent->_right = cur->_right;
|
||
|
// }
|
||
|
// }
|
||
|
// delete cur;
|
||
|
// }
|
||
|
// // 2. 要删除的节点没有右孩子
|
||
|
// else if (cur->_right == nullptr)
|
||
|
// {
|
||
|
// if (cur == _root)
|
||
|
// {
|
||
|
// _root = cur->_left;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// if (parent->_left == cur)
|
||
|
// {
|
||
|
// parent->_left = cur->_left;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// parent->_right = cur->_left;
|
||
|
// }
|
||
|
// }
|
||
|
// delete cur;
|
||
|
// }
|
||
|
// // 3. 左右都不为空, 不能直接删除, 使用替换法删除
|
||
|
// // 可以找左子树的最大节点或者右子树的最小节点去替代它
|
||
|
// else
|
||
|
// {
|
||
|
// // 右子树最小节点
|
||
|
// Node* rightMinParent = cur;
|
||
|
// Node* rightMin = cur->_right;
|
||
|
// while (rightMin->_left)
|
||
|
// {
|
||
|
// rightMinParent = rightMin;
|
||
|
// rightMin = rightMin->_left;
|
||
|
// }
|
||
|
|
||
|
// // 替换删除的节点
|
||
|
// std::swap(cur->_key, rightMin->_key);
|
||
|
// std::swap(cur->_value, rightMin->_value);
|
||
|
|
||
|
// // 把问题转换成删除 rightMin
|
||
|
// if (rightMinParent->_left == rightMin)
|
||
|
// {
|
||
|
// rightMinParent->_left = rightMin->_right;
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// rightMinParent->_right = rightMin->_right;
|
||
|
// }
|
||
|
|
||
|
// delete rightMin;
|
||
|
// }
|
||
|
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
// 递归删除节点
|
||
|
// 辅助函数
|
||
|
Node *_erase(Node *root, const K &key)
|
||
|
{
|
||
|
if (root == nullptr)
|
||
|
{
|
||
|
return root;
|
||
|
}
|
||
|
if (key < root->_key)
|
||
|
{
|
||
|
root->_left = _erase(root->_left, key);
|
||
|
}
|
||
|
else if (key > root->_key)
|
||
|
{
|
||
|
root->_right = _erase(root->_right, key);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (root->_left == nullptr)
|
||
|
{
|
||
|
Node *ret = root->_right;
|
||
|
delete root;
|
||
|
return ret;
|
||
|
}
|
||
|
if (root->_right == nullptr)
|
||
|
{
|
||
|
Node *ret = root->_left;
|
||
|
delete root;
|
||
|
return ret;
|
||
|
}
|
||
|
Node *minNode = getMin(root->_right);
|
||
|
root->_key = minNode->_key;
|
||
|
root->_right = _erase(root->_right, minNode->_key);
|
||
|
}
|
||
|
return root;
|
||
|
}
|
||
|
|
||
|
Node *getMin(Node *node)
|
||
|
{
|
||
|
while (node->_left != nullptr)
|
||
|
{
|
||
|
node = node->_left;
|
||
|
}
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
// 删除节点
|
||
|
void Erase(const K &key)
|
||
|
{
|
||
|
_erase(_root, key);
|
||
|
}
|
||
|
|
||
|
// 递归中序遍历
|
||
|
// 辅助函数
|
||
|
// void _InOrder(Node* root)
|
||
|
//{
|
||
|
// if (root == nullptr)
|
||
|
// {
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// _InOrder(root->_left);
|
||
|
// //std::cout << root->_key << " : " << root->_value << std::endl;
|
||
|
// std::cout << root->_key << " ";
|
||
|
// _InOrder(root->_right);
|
||
|
//}
|
||
|
|
||
|
// void InOrder()
|
||
|
//{
|
||
|
// _InOrder(_root);
|
||
|
// std::cout << std::endl;
|
||
|
// }
|
||
|
|
||
|
// 非递归中序遍历
|
||
|
void InOrder()
|
||
|
{
|
||
|
std::stack<Node *> stack;
|
||
|
Node *cur = _root;
|
||
|
|
||
|
while (cur != nullptr || !stack.empty())
|
||
|
{
|
||
|
// 找到最左边的节点
|
||
|
while (cur != nullptr)
|
||
|
{
|
||
|
stack.push(cur);
|
||
|
cur = cur->_left;
|
||
|
}
|
||
|
|
||
|
// 处理当前节点
|
||
|
cur = stack.top();
|
||
|
stack.pop();
|
||
|
std::cout << cur->_key << " ";
|
||
|
|
||
|
// 转向右子树
|
||
|
cur = cur->_right;
|
||
|
}
|
||
|
std::cout << std::endl;
|
||
|
}
|
||
|
|
||
|
// 递归前序遍历
|
||
|
// 辅助函数
|
||
|
// void _PreOrder(Node* root)
|
||
|
//{
|
||
|
// if (root == nullptr)
|
||
|
// {
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// std::cout << root->_key << " "; // 访问根节点
|
||
|
// _PreOrder(root->_left); // 访问左子树
|
||
|
// _PreOrder(root->_right); // 访问右子树
|
||
|
//}
|
||
|
|
||
|
// void PreOrder()
|
||
|
//{
|
||
|
// _PreOrder(_root);
|
||
|
// std::cout << std::endl;
|
||
|
// }
|
||
|
|
||
|
// 非递归前序遍历
|
||
|
void PreOrder()
|
||
|
{
|
||
|
if (_root == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
std::stack<Node *> stack;
|
||
|
stack.push(_root);
|
||
|
|
||
|
while (!stack.empty())
|
||
|
{
|
||
|
Node *cur = stack.top();
|
||
|
stack.pop();
|
||
|
std::cout << cur->_key << " "; // 访问当前节点
|
||
|
|
||
|
// 先压入右子树再压入左子树(确保左子树先处理)
|
||
|
if (cur->_right != nullptr)
|
||
|
{
|
||
|
stack.push(cur->_right);
|
||
|
}
|
||
|
if (cur->_left != nullptr)
|
||
|
{
|
||
|
stack.push(cur->_left);
|
||
|
}
|
||
|
}
|
||
|
std::cout << std::endl;
|
||
|
}
|
||
|
|
||
|
// 递归后序遍历
|
||
|
// 辅助函数
|
||
|
// void _PostOrder(Node* root) {
|
||
|
// if (root == nullptr)
|
||
|
// {
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// _PostOrder(root->_left); // 访问左子树
|
||
|
// _PostOrder(root->_right); // 访问右子树
|
||
|
// std::cout << root->_key << " "; // 访问根节点
|
||
|
//}
|
||
|
|
||
|
// void PostOrder()
|
||
|
//{
|
||
|
// _PostOrder(_root);
|
||
|
// std::cout << std::endl;
|
||
|
// }
|
||
|
|
||
|
// 非递归后序遍历
|
||
|
void PostOrder()
|
||
|
{
|
||
|
if (_root == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
std::stack<Node *> st;
|
||
|
Node *cur = _root;
|
||
|
Node *lastNode = nullptr; // 最近访问的节点
|
||
|
while (cur || !st.empty())
|
||
|
{
|
||
|
while (cur)
|
||
|
{
|
||
|
st.push(cur);
|
||
|
cur = cur->_left;
|
||
|
}
|
||
|
|
||
|
Node *top = st.top();
|
||
|
if ((top->_right == nullptr) || (lastNode == top->_right))
|
||
|
{
|
||
|
std::cout << top->_key << " ";
|
||
|
lastNode = top;
|
||
|
st.pop();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cur = top->_right;
|
||
|
}
|
||
|
}
|
||
|
std::cout << std::endl;
|
||
|
}
|
||
|
|
||
|
// 层序遍历
|
||
|
void LevelOrder()
|
||
|
{
|
||
|
if (_root == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
std::queue<Node *> queue;
|
||
|
queue.push(_root);
|
||
|
|
||
|
while (!queue.empty())
|
||
|
{
|
||
|
Node *cur = queue.front();
|
||
|
queue.pop();
|
||
|
std::cout << cur->_key << " "; // 访问当前节点
|
||
|
|
||
|
if (cur->_left != nullptr)
|
||
|
{
|
||
|
queue.push(cur->_left); // 将左子树压入队列
|
||
|
}
|
||
|
if (cur->_right != nullptr)
|
||
|
{
|
||
|
queue.push(cur->_right); // 将右子树压入队列
|
||
|
}
|
||
|
}
|
||
|
std::cout << std::endl;
|
||
|
}
|
||
|
|
||
|
// 查找前驱节点
|
||
|
Node *findMax(Node *node)
|
||
|
{
|
||
|
while (node->_right != nullptr)
|
||
|
{
|
||
|
node = node->_right;
|
||
|
}
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
Node *FindPredecessor(Node *node)
|
||
|
{
|
||
|
if (node->_left != nullptr)
|
||
|
{
|
||
|
return findMax(node->_left);
|
||
|
}
|
||
|
|
||
|
Node *cur = _root;
|
||
|
Node *predecessor = nullptr;
|
||
|
while (cur != nullptr)
|
||
|
{
|
||
|
if (node->_key < cur->_key)
|
||
|
{
|
||
|
cur = cur->_left;
|
||
|
}
|
||
|
else if (node->_key > cur->_key)
|
||
|
{
|
||
|
predecessor = cur;
|
||
|
cur = cur->_right;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return predecessor;
|
||
|
}
|
||
|
|
||
|
// 查找后继节点
|
||
|
Node *findMin(Node *node)
|
||
|
{
|
||
|
while (node->_left != nullptr)
|
||
|
{
|
||
|
node = node->_left;
|
||
|
}
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
Node *FindSuccessor(Node *node)
|
||
|
{
|
||
|
if (node->_right != nullptr)
|
||
|
{
|
||
|
return findMin(node->_right);
|
||
|
}
|
||
|
|
||
|
Node *cur = _root;
|
||
|
Node *successor = nullptr;
|
||
|
while (cur != nullptr)
|
||
|
{
|
||
|
if (node->_key < cur->_key)
|
||
|
{
|
||
|
successor = cur;
|
||
|
cur = cur->_left;
|
||
|
}
|
||
|
else if (node->_key > cur->_key)
|
||
|
{
|
||
|
cur = cur->_right;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return successor;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
Node *_root = nullptr;
|
||
|
};
|
||
|
}
|