RBTree/Windows_RBTree/AVLTree.hpp

612 lines
15 KiB
C++
Raw Permalink Normal View History

#pragma once
#include <iostream>
#include <stack>
#include <queue>
namespace Lenyiin
{
template <class K, class V>
struct AVLTreeNode
{
AVLTreeNode<K, V>* _left;
AVLTreeNode<K, V>* _right;
AVLTreeNode<K, V>* _parent;
int _bf; // balance factor ƽ<><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::pair<K, V> _kv; // key-value
// <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>
AVLTreeNode(const std::pair<K, V>& kv)
: _left(nullptr), _right(nullptr), _parent(nullptr), _bf(0), _kv(kv)
{
}
};
template <class K, class V>
class AVLTree
{
private:
typedef AVLTreeNode<K, V> Node;
public:
bool Insert(const std::pair<K, V>& kv)
{
// 1. <20>Ȱ<EFBFBD><C8B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD>
if (_root == nullptr)
{
_root = new Node(kv);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (cur->_kv.first > kv.first)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_kv.first < kv.first)
{
parent = cur;
cur = cur->_right;
}
else
{
return false; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>ʾ<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
}
}
// <20>ҵ<EFBFBD>λ<EFBFBD><CEBB>
cur = new Node(kv);
if (parent->_kv.first > kv.first)
{
parent->_left = cur;
cur->_parent = parent;
}
else
{
parent->_right = cur;
cur->_parent = parent;
}
// 2. <20><><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (parent)
{
if (cur == parent->_right)
{
parent->_bf++; // <20><><EFBFBD><EFBFBD><EFBFBD>ұ<EFBFBD>, ƽ<><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>++
}
else
{
parent->_bf--; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ƽ<><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>--
}
if (parent->_bf == 0)
{
// ˵<><CBB5> parent <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶Ȳ<DFB6><C8B2><EFBFBD>, <20><><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
break;
}
else if (parent->_bf == 1 || parent->_bf == -1)
{
// ˵<><CBB5> parent <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ߶ȱ<DFB6><C8B1><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD>
cur = parent;
parent = parent->_parent;
}
else if (parent->_bf == 2 || parent->_bf == -2)
{
// parent <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>Ҫ<EFBFBD><D2AA>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
// 1. <20><>תǰ<D7AA><C7B0><EFBFBD>DZ<EFBFBD><C7B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2. <20><>ת<EFBFBD><D7AA>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>
if (parent->_bf == 2)
{
if (cur->_bf == 1)
{
// <20><><EFBFBD><EFBFBD>
RotateL(parent);
}
else if (cur->_bf == -1)
{
// <20><><EFBFBD><EFBFBD>˫<EFBFBD><CBAB>
RotateRL(parent);
}
}
else if (parent->_bf == -2)
{
if (cur->_bf == -1)
{
// <20><><EFBFBD><EFBFBD>
RotateR(parent);
}
else if (cur->_bf == 1)
{
// <20><><EFBFBD><EFBFBD>˫<EFBFBD><CBAB>
RotateLR(parent);
}
}
// <20><>ת<EFBFBD><D7AA><EFBFBD>ɺ<EFBFBD>, parent <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ĸ߶Ȼָ<C8BB><D6B8><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD>ڵ<EFBFBD>ǰ<EFBFBD>ĸ߶<C4B8>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>û<EFBFBD><C3BB>Ӱ<EFBFBD><D3B0>, <20><><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
break;
}
}
return true;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void RotateL(Node* parent)
{
Node* ppNode = parent->_parent;
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
{
subRL->_parent = parent;
}
subR->_left = parent;
parent->_parent = subR;
// 1. ԭ<><D4AD> parent <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>, <20><><EFBFBD><EFBFBD> subR <20>Ǹ<EFBFBD>
if (parent == _root)
{
_root = subR;
subR->_parent = nullptr;
}
// 2. parent Ϊ<><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>, <20>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ӹ<EFBFBD>ϵ, <20><>ô subR Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subR;
}
else
{
ppNode->_right = subR;
}
subR->_parent = ppNode;
}
parent->_bf = subR->_bf = 0;
}
// <20>ҵ<EFBFBD><D2B5><EFBFBD>
void RotateR(Node* parent)
{
Node* ppNode = parent->_parent;
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR)
{
subLR->_parent = parent;
}
subL->_right = parent;
parent->_parent = subL;
if (parent == _root)
{
_root = subL;
subL->_parent = nullptr;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subL;
}
else
{
ppNode->_right = subL;
}
subL->_parent = ppNode;
}
parent->_bf = subL->_bf = 0;
}
// <20><><EFBFBD><EFBFBD>˫<EFBFBD><CBAB>
void RotateRL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
int bf = subRL->_bf;
RotateR(parent->_right);
RotateL(parent);
if (bf == -1)
{
parent->_bf = 0;
subR->_bf = 1;
subRL->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = -1;
subR->_bf = 0;
subRL->_bf = 0;
}
else if (bf == 0)
{
parent->_bf = 0;
subR->_bf = 0;
subRL->_bf = 0;
}
}
// <20><><EFBFBD><EFBFBD>˫<EFBFBD><CBAB>
void RotateLR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
RotateL(subL);
RotateR(parent);
if (bf == 1)
{
parent->_bf = 0;
subL->_bf = -1;
subLR->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 1;
subL->_bf = 0;
subLR->_bf = 0;
}
else if (bf == 0)
{
parent->_bf = 0;
subL->_bf = 0;
subLR->_bf = 0;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// void _InOrder(Node* root)
//{
// if (root == nullptr)
// {
// return;
// }
// _InOrder(root->_left);
// std::cout << root->_kv.first << ":" << root->_kv.second << std::endl;
// _InOrder(root->_right);
//}
// void InOrder()
//{
// _InOrder(_root);
// std::cout << std::endl;
// }
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ǵݹ<C7B5>
void InOrder()
{
std::stack<Node*> stack;
Node* cur = _root;
while (cur != nullptr || !stack.empty())
{
// <20>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵĽڵ<C4BD>
while (cur != nullptr)
{
stack.push(cur);
cur = cur->_left;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>
cur = stack.top();
stack.pop();
std::cout << cur->_kv.first << ":" << cur->_kv.second << std::endl;
// ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cur = cur->_right;
}
std::cout << std::endl;
}
// ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵݹ<C4B5>ʵ<EFBFBD><CAB5>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// void _PreOrder(Node* root)
//{
// if (root == nullptr)
// {
// return;
// }
// std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; // <20><><EFBFBD>ʸ<EFBFBD><CAB8>ڵ<EFBFBD>
// _PreOrder(root->_left); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// _PreOrder(root->_right); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//}
// void PreOrder()
//{
// _PreOrder(_root);
// std::cout << std::endl;
// }
// ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķǵݹ<C7B5>ʵ<EFBFBD><CAB5>
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->_kv.first << ":" << cur->_kv.second << std::endl; // <20><><EFBFBD>ʵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>
// <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
if (cur->_right != nullptr)
{
stack.push(cur->_right);
}
if (cur->_left != nullptr)
{
stack.push(cur->_left);
}
}
std::cout << std::endl;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵݹ<C4B5>ʵ<EFBFBD><CAB5>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// void _PostOrder(Node* root) {
// if (root == nullptr)
// {
// return;
// }
// _PostOrder(root->_left); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// _PostOrder(root->_right); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; // <20><><EFBFBD>ʸ<EFBFBD><CAB8>ڵ<EFBFBD>
//}
// void PostOrder()
//{
// _PostOrder(_root);
// std::cout << std::endl;
// }
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķǵݹ<C7B5>ʵ<EFBFBD><CAB5>
void PostOrder()
{
if (_root == nullptr)
{
return;
}
std::stack<Node*> st;
Node* cur = _root;
Node* lastNode = nullptr; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵĽڵ<C4BD>
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->_kv.first << ":" << top->_kv.second << std::endl;
lastNode = top;
st.pop();
}
else
{
cur = top->_right;
}
}
std::cout << std::endl;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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->_kv.first << ":" << cur->_kv.second << std::endl; // <20><><EFBFBD>ʵ<EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>
if (cur->_left != nullptr)
{
queue.push(cur->_left); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
if (cur->_right != nullptr)
{
queue.push(cur->_right); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
std::cout << std::endl;
}
// <20><><EFBFBD>Һ<EFBFBD><D2BA>̽ڵ<CCBD>
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->_kv.first < cur->_kv.first)
{
successor = cur;
cur = cur->_left;
}
else if (node->_kv.first > cur->_kv.first)
{
cur = cur->_right;
}
else
{
break;
}
}
return successor;
}
// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ڵ<EFBFBD>
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->_kv.first < cur->_kv.first)
{
cur = cur->_left;
}
else if (node->_kv.first > cur->_kv.first)
{
predecessor = cur;
cur = cur->_right;
}
else
{
break;
}
}
return predecessor;
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>ĸ߶<C4B8>
int Height(Node* root)
{
if (root == nullptr)
{
return 0;
}
int leftHeight = Height(root->_left);
int rightHeight = Height(root->_right);
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool _IsBalance(Node* root)
{
if (root == nullptr)
{
return true;
}
int leftHeight = Height(root->_left);
int rightHeight = Height(root->_right);
if (abs(leftHeight - rightHeight) > 1)
{
return false;
}
return _IsBalance(root->_left) && _IsBalance(root->_right);
}
bool IsBalance()
{
return _IsBalance(_root);
}
// <20><><EFBFBD><EFBFBD> <20>ǵݹ<C7B5>
// Node* Find(const K& key)
//{
// Node* cur = _root;
// while (cur)
// {
// if (cur->_kv.first > key)
// {
// cur = cur->_left;
// }
// else if (cur->_kv.first < key)
// {
// cur = cur->_right;
// }
// else
// {
// return cur;
// }
// }
// return nullptr;
//}
// <20><><EFBFBD>ҵĵݹ<C4B5>ʵ<EFBFBD><CAB5>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Node* _find(Node* root, const K& key)
{
if (root == nullptr || root->_kv.first == key)
{
return root;
}
if (key < root->_kv.first)
{
return _find(root->_left, key);
}
else
{
return _find(root->_right, key);
}
}
// <20><><EFBFBD>ҽڵ<D2BD>
Node* Find(const K& key)
{
return _find(_root, key);
}
private:
Node* _root = nullptr;
};
}