612 lines
15 KiB
C++
612 lines
15 KiB
C++
|
#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;
|
|||
|
};
|
|||
|
}
|