思路學習博客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;
}
}