思路学习博客https://www.cnblogs.com/coding-nerver-die/p/10975599.html
主要是理解其中维持其平衡进行的旋转操作,分两种情况
第一种情况只需要旋转一次
第二中情况需要先旋转下不平衡子树的子树,使其满足是一条递减的线,再旋转
直接上代码
template <typename T>
struct AVLTreeNode{
AVLTreeNode(T val,AVLTreeNode<T>* left,AVLTreeNode<T>* right)
:val(val),left(left),right(right){}
T val;
int height;
AVLTreeNode<T>* left;
AVLTreeNode<T>* right;
AVLTreeNode<T>* parent;
};
template <typename T>
struct AVLTree
{
public:
AVLTree();
~AVLTree();
void insert(T key); //插入
void remove(T key); //删除某节点
AVLTreeNode<T>* find1(AVLTreeNode<T>* pnode,T key); //递归查找某节点
AVLTreeNode<T>* find2(AVLTreeNode<T>* pnode,T key); //非递归查找某节点
int height(); //获取树的高度
void preOrder(); //前序遍历AVL树
void InOrder(); //中序遍历AVL树
void postOrder(); //后序遍历AVL树
private:
AVLTreeNode<T>* head;
int height(AVLTreeNode<T>* pnode) ; //任意一节点的高度
AVLTreeNode<T>* insert(AVLTreeNode<T>* &pnode, T key);
AVLTreeNode<T>* remove(AVLTreeNode<T>* & pnode, T key);
AVLTreeNode<T>* leftRotation(AVLTreeNode<T>* pnode); //单旋:左旋操作
AVLTreeNode<T>* rightRotation(AVLTreeNode<T>* pnode); //单旋:右旋操作
AVLTreeNode<T>* leftRightRotation(AVLTreeNode<T>* pnode); //双旋:先左旋后右旋操作
AVLTreeNode<T>* rightLeftRotation(AVLTreeNode<T>* pnode); //双旋:先右旋后左旋操作
};
//构造函数
template <typename T>
AVLTree<T>::AVLTree(){
head = NULL;
}
//销毁每个节点
template <typename T>
AVLTree<T>::~AVLTree(){
}
template <typename T>
int AVLTree<T>::height(AVLTreeNode<T>* pnode) //返回任一节点子树的高度
{
if (pnode != NULL)
{
return pnode->height;
}
return 0; //如果是空树,高度为0
};
template <typename T>
int AVLTree<T>::height()
{
return height(head);
};
template <typename T>
AVLTreeNode<T>* AVLTree<T>::leftRotation(AVLTreeNode<T> *pnode) {
AVLTreeNode<T>* p = pnode->right;
pnode->right = p->left;
p->left = pnode;
pnode->height = max(height(pnode->left),height(pnode->right))+1; //更新改变高度的两个节点
p->height = height(p)+1;
}
template <typename T>
AVLTreeNode<T>* AVLTree<T>::leftRightRotation(AVLTreeNode<T>* pnode)
{
pnode->lchild= leftRotation(pnode->lchild); //先把根节点的子树旋转一下,在旋转根节点
return rightRotation(pnode);
}
template <typename T>
AVLTreeNode<T>* AVLTree<T>::insert(AVLTreeNode<T>* &pnode, T key){
if(pnode== NULL){ //创建一个节点
pnode = new AVLTreeNode<T>(key,NULL,NULL);
}
else if(key > pnode->val){ //如果Key大于当前根节点,就在根节点的右子树上插入
pnode->right = insert(pnode->right,key); //递归插入
if(height(pnode->right) - height(pnode->left) == 2){
if(key > pnode->right->val)
pnode = leftRotation(pnode);
else
pnode = rightRotation(pnode);
}
}
else if(key < pnode->val){
pnode->left = insert(pnode->left,key);
if(height(pnode->left) - height(pnode->right) == 2){
if(key > pnode->left->val)
pnode = leftRotation(pnode);
else
pnode = rightRotation(pnode);
}
}
pnode->height = max(height(pnode->left), height(pnode->right)) + 1;
return pnode;
}
template <typename T>
void AVLTree<T>::insert(T key) //从根节点开始插入
{
insert(head, key);
};
template <typename T>
AVLTreeNode<T>* AVLTree<T>::find1(AVLTreeNode<T>*root,T key) {
if(head != NULL){
if(key == root->val)
return root;
else if(key > root->val)
return find1(root->right,key);
else
return find1(root->left,key);
}
}
template <typename T>
AVLTreeNode<T>* AVLTree<T>::find2(AVLTreeNode<T>*root,T key){
while(root != NULL){
if(key == root->val)
return root;
else if(key > root->val)
root = root->right;
else
root = root->left;
}
}