#include <bits/stdc++.h>
using namespace std;
template<typename T>
struct Node
{
T key;
Node *left, *right;
Node(const T &k):key(k),left(nullptr),right(nullptr){}
};
template<typename T>
class AVLTree
{
public:
AVLTree<T>(){root=nullptr;}
private:
Node<T> *root;
inline int getHeight(Node<T> *node);
inline int getBalance(Node<T> *node);
inline Node<T>* rotationLeft(Node<T> *node);
inline Node<T>* rotationRight(Node<T> *node);
inline Node<T>* successor(Node<T> *node);
inline void inOrder(Node<T> *node);
inline void preOrder(Node<T> *node);
Node<T>* put(Node<T>* &node, const T &key);
Node<T>* del(Node<T> *node, const T &key);
public:
inline void put(const T &key);
inline void del(const T &key);
inline void inOrder();
inline void preOrder();
};
template<typename T>
inline int AVLTree<T>::getHeight(Node<T> *node)
{
if(node == nullptr)
return -1;
return max(getHeight(node->left), getHeight(node->right)) + 1;
}
template<typename T>
inline int AVLTree<T>::getBalance(Node<T> *node)
{
if(node == nullptr)
return 0;
return getHeight(node->left) - getHeight(node->right);
}
template<typename T>
inline Node<T>* AVLTree<T>::rotationLeft(Node<T>* x)
{
Node<T> *y = x->right;
x->right = y->left;
y->left = x;
return y;
}
template<typename T>
inline Node<T>* AVLTree<T>::rotationRight(Node<T>* x)
{
Node<T> *y = x->left;
x->left = y->right;
y->right = x;
return y;
}
template<typename T>
inline Node<T>* AVLTree<T>::successor(Node<T> *node)
{
while(node->left != nullptr)
node = node->left;
return node;
}
template<typename T>
Node<T>* AVLTree<T>::put(Node<T>* &node, const T &key)
{
if(node == nullptr)
return new Node<T>(key);
else if(key < node->key)
node->left = put(node->left, key);
else if(key > node->key)
node->right = put(node->right, key);
else
return node;
int balance = getBalance(node);
if(balance > 1)
{
if(key < node->left->key)
return rotationRight(node);
if(key > node->left->key)
{
node->left = rotationLeft(node->left);
return rotationRight(node);
}
}
else if(balance < -1)
{
if(key > node->right->key)
return rotationLeft(node);
if(key < node->right->key)
{
node->right = rotationRight(node->right);
return rotationLeft(node);
}
}
return node;
}
template<typename T>
inline void AVLTree<T>::put(const T &key)
{
root = put(root, key);
}
template<typename T>
inline Node<T>* AVLTree<T>::del(Node<T> *node, const T &key)
{
if(node == nullptr)
return node;
if(key < node->key)
node->left = del(node->left, key);
else if(key > node->key)
node->right = del(node->right, key);
else
{
Node<T> *tmp = nullptr;
if(node->left != nullptr && node->right != nullptr)
{
tmp = successor(node->right);
node->key = tmp->key;
node->right = del(node->right, tmp->key);
}
else if(node->right == nullptr)
{
tmp = node;
node = node->left;
delete tmp;
}
else if(node->left == nullptr)
{
tmp = node;
node = node->right;
delete tmp;
}
else
{
delete node;
}
}
int balance = getBalance(node);
if(balance > 1)
{
if(getBalance(node->left) >= 0)
return rotationRight(node);
else
{
node->left = rotationLeft(node->left);
return rotationRight(node);
}
}
else if(balance < -1)
{
if(getBalance(node->right) <= 0)
return rotationLeft(node);
else
{
node->right = rotationRight(node->right);
return rotationLeft(node);
}
}
return node;
}
template<typename T>
inline void AVLTree<T>::del(const T &key)
{
root = del(root, key);
}
template<typename T>
inline void AVLTree<T>::inOrder(Node<T> *node)
{
if(node == nullptr)
return ;
inOrder(node->left);
cout << node->key << " ";
inOrder(node->right);
}
template<typename T>
inline void AVLTree<T>::preOrder(Node<T> *node)
{
if(node == nullptr)
return ;
cout << node->key << " ";
preOrder(node->left);
preOrder(node->right);
}
template<typename T>
inline void AVLTree<T>::inOrder()
{
cout << " in: " ;
inOrder(root);
cout << endl;
}
template<typename T>
inline void AVLTree<T>::preOrder()
{
cout << "pre: ";
preOrder(root);
cout << endl;
}
int main()
{
AVLTree<int> avlT;
vector<int> vec{1,2,3,4,5,6,7};
cout << "insert: " << endl;
for(int i=0;i<int(vec.size());i++)
{
avlT.put(vec[i]);
avlT.inOrder();
avlT.preOrder();
}
cout << "delete: " << endl;
for(int i=0;i<int(vec.size());i++)
{
avlT.del(vec[i]);
avlT.inOrder();
avlT.preOrder();
}
return 0;
}
测试结果
insert:
in: 1
pre: 1
in: 1 2
pre: 1 2
in: 1 2 3
pre: 2 1 3
in: 1 2 3 4
pre: 2 1 3 4
in: 1 2 3 4 5
pre: 2 1 4 3 5
in: 1 2 3 4 5 6
pre: 4 2 1 3 5 6
in: 1 2 3 4 5 6 7
pre: 4 2 1 3 6 5 7
delete:
in: 2 3 4 5 6 7
pre: 4 2 3 6 5 7
in: 3 4 5 6 7
pre: 4 3 6 5 7
in: 4 5 6 7
pre: 6 4 5 7
in: 5 6 7
pre: 6 5 7
in: 6 7
pre: 6 7
in: 7
pre: 7
in:
pre: