重要概念:AVL tree——是一种二叉树,通过对二叉查找树的节点强加平衡约束来避免失衡问题, 特点是树中的每个元素的两棵子树之间的高度之差不超过1,若超过则将执行子树旋转以恢复平衡,旋转方式包括:单旋转和双旋转。
#ifndef MYAVLTREE_H
#define MYAVLTREE_H
#define MAX(a,b) ((a)>(b)?(a):(b))
template <class T>
class AVLTree
{
public:
struct ANode
{
ANode():val(T()), height(0), left(0), right(0) {}
ANode(const T& t, ANode* p = 0, ANode* l = 0, ANode* r = 0):val(t), height(0), left(l), right(r) {}
T val;
int height;
ANode* left;
ANode* right;
};
private:
ANode* root;
void insertNode(ANode*&, const T&); //递归插入节点
void rotateWithLeftChild(ANode*&); //单旋转
void rotateWithRightChild(ANode*&);
void doubleRotateWithLeftChild(ANode*&); //双旋转
void doubleRotateWithRightChild(ANode*&);
int getHeight(ANode*); //返回节点高度
void out(ANode*); //中序遍历输出
public:
AVLTree(){}
AVLTree(const T& t):root(new ANode(t)) {}
~AVLTree();
void insert(const T&);
//void remove(const T&);
void print();
};
template <class T>
AVLTree<T>::~AVLTree()
{
if (!root) delete root;
}
template <class T>
int AVLTree<T>::getHeight(ANode* node)
{
return node == 0 ? -1:node->height;
}
template <class T>
void AVLTree<T>::print()
{
out(root);
}
template <class T>
void AVLTree<T>::out(ANode* temp) //中序遍历输出
{
if (!temp) return ;
out(temp->left);
cout<<temp->val<<" ";
out(temp->right);
}
template <class T>
void AVLTree<T>::insert(const T& t)
{
insertNode(root, t);
}
template <class T>
void AVLTree<T>::insertNode(ANode*& node, const T& t)
{
if (!node) node = new ANode(t);
if (t < node->val)
{
insertNode(node->left, t);
if (getHeight(node->left) - getHeight(node->right) == 2)
{
if (node->left->val > t)
rotateWithLeftChild(node);
else
doubleRotateWithLeftChild(node);
}
}
if (t > node->val)
{
insertNode(node->right, t);
if (getHeight(node->right) - getHeight(node->left) == 2)
{
if (node->right->val < t)
rotateWithRightChild(node);
else
doubleRotateWithRightChild(node);
}
}
node->height = MAX(getHeight(node->left), getHeight(node->right)) + 1;
}
template <class T>
void AVLTree<T>::rotateWithLeftChild(ANode*& node)
{
ANode* new_node = node->left;
node->left = new_node->right;
new_node->right = node;
new_node->right->height -= 1;
new_node->height = MAX(getHeight(new_node->left), getHeight(new_node->right)) + 1;
node->height = MAX(getHeight(node->left), getHeight(node->right)) + 1;
node = new_node;
}
template <class T>
void AVLTree<T>:: rotateWithRightChild(ANode*& node)
{
ANode* new_node = node->right;
node->right = new_node->left;
new_node->left = node;
new_node->left->height -= 1;
new_node->height = MAX(getHeight(new_node->left), getHeight(new_node->right)) + 1;
node->height = MAX(getHeight(node->left), getHeight(node->right)) + 1;
node = new_node;
}
template <class T>
void AVLTree<T>:: doubleRotateWithLeftChild(ANode*& node)
{
rotateWithRightChild(node->left); //双旋转,注意顺序,先右转后左转
rotateWithLeftChild(node);
}
template <class T>
void AVLTree<T>:: doubleRotateWithRightChild(ANode*& node)
{
rotateWithLeftChild(node->right); //双旋转,注意顺序,先左转后右转
rotateWithRightChild(node);
}
#endif
测试函数:
int _tmain(int argc, _TCHAR* argv[])
{
AVLTree<string> tree1("DE");
tree1.insert("PA");
tree1.insert("NJ");
tree1.insert("GA");
tree1.insert("CT");
tree1.insert("MA");
tree1.insert("MD");
tree1.insert("SC");
tree1.insert("NH");
tree1.insert("VA");
tree1.print();
return 0;
}
AVL树结构: GA
/ \
DE NJ
/ / \
CT MD SC
/ \ / \
MA NH PA VA
输出结果(中序遍历):CT DE GA MA MD NH NJ PA SC VA