建立維持平衡二叉樹(Root of AVL Tree)

原題鏈接

樹(中)課後練習題2,也是PAT 甲級 1066

解題思路

根據輸入結點建立一個AVL樹,輸出樹根即可。這個何老師將的旋轉類型是根據“麻煩結點”相對於“破壞節點”的位置來定義的,我這裏實現方式是參考算法筆記中的,R就表示右旋,L表示左旋,是根據旋轉的方向取得名字。貼一下圖,感覺很好理解。
左旋示意圖
右旋示意圖
插入過程中出現失衡情況的調整

源代碼

建樹過程和建立一棵BST比較類似,建立AVL樹要在插入過程中附帶上失衡的檢查和處理,一旦發現插入導致失衡,就通過表9-1的旋轉情況將樹調整爲平衡情況,最後返回樹根即可。

#include<iostream>
using namespace std;
const int maxn=23;
struct node
{
    int data,height;
    node* lchild;
    node* rchild;
};
node* root;//根節點
//生成一個新結點,data爲結點權值
node* newNode(int data)
{
    node* root=new node;
    root->data=data;
    root->height=1;
    root->lchild=root->rchild=NULL;
    return root;
}
//獲取以root爲根結點的子樹的當前height
int getHeight(node* root)
{
    if(root==NULL)//空結點高度爲0
        return 0;
    return root->height;
}
//更新結點root的height
void updateHeight(node* root)
{
    root->height=max(getHeight(root->lchild),getHeight(root->rchild))+1;
}
//計算結點root的平衡因子
int getBalanceFactor(node* root)
{
    int factor=getHeight(root->lchild)-getHeight(root->rchild);
    return factor;
}
//Left Rotation
void L(node* &root)
{
    node* temp=root->rchild;
    root->rchild=temp->lchild;
    temp->lchild=root;
    updateHeight(root);
    updateHeight(temp);
    root=temp;
}
//Right Rotation
void R(node* &root)
{
    node* temp=root->lchild;
    root->lchild=temp->rchild;
    temp->rchild=root;
    updateHeight(root);
    updateHeight(temp);
    root=temp;
}
//插入權值爲data的結點
void insertNode(node* &root,int data)
{
    if(root==NULL)
    {
        root=newNode(data);
        return ;
    }
    if(data < root->data)
    {
        insertNode(root->lchild,data);
        updateHeight(root);
        if(getBalanceFactor(root)==2)
        {
            if(getBalanceFactor(root->lchild)==1)//LL型
            {
                R(root);
            }
            else if(getBalanceFactor(root->lchild)==-1)//LR型
            {
                L(root->lchild);
                R(root);
            }
        }
    }
    else
    {
        insertNode(root->rchild,data);
        updateHeight(root);
        if(getBalanceFactor(root)==-2)
        {
            if(getBalanceFactor(root->rchild)==-1)//RR型
            {
                L(root);
            }
            else if(getBalanceFactor(root->rchild)==1)//RL型
            {
                R(root->rchild);
                L(root);
            }
        }
    }
}
//AVL樹的建立
node* create(int data[], int n)
{
    node* root=NULL;
    for(int i=0; i<n; i++)
    {
        insertNode(root,data[i]);
    }
    return root;
}
int main()
{
    int data[maxn];
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%d",&data[i]);
    }
    root=create(data,n);
    printf("%d\n",root->data);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章