AVL树模板

Posted 君凌烟阁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVL树模板相关的知识,希望对你有一定的参考价值。

  花了半天时间学习AVL树,AVL树只要有LL,RR,LR,RL四种旋转操作,动态增加与减少都需要四种操作结合。AVL树比普通二叉树的结构体多了一个高度,用于保证左右子节点高度差小于2。在计算高度的时候,最好自己写一个函数,因为要判断是否为NULL,NULL则表示为0。如果用指针去取高度,为NULL的时候会报错。并且在计算高度差的时候,要注意是左节点减去右节点还是右节点减去左节点。

  主要灵感来源于:http://blog.csdn.net/whucyl/article/details/17289841

  

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;

struct Node
{
    int val;
    int height;
    Node* left;
    Node* right;
    Node()
    {
        height = 1;
        left = NULL;
        right = NULL;
    }
    //更新高度
    void UpdateHeight()
    {
        int leftheight = left ? left->height : 0;
        int rightheight = right ? right->height : 0;
        height = max(leftheight,rightheight)+1;
    }
    //左右子孩子高度差
    int DisHeight()
    {
        int leftheight = left ? left->height : 0;
        int rightheight = right ? right->height : 0;
        return leftheight-rightheight;
    }
};

Node* LL(Node* anode)
{
    Node* bnode = anode->left;
    Node* cnode = bnode->right;
    bnode->right = anode;
    anode->left = cnode;
    //更新高度时,anode一定要先更新
    anode->UpdateHeight();
    bnode->UpdateHeight();
    return bnode;
}

Node* RR(Node* anode)
{
    Node* bnode = anode->right;
    Node* cnode = bnode->left;
    bnode->left = anode;
    anode->right = cnode;
    anode->UpdateHeight();
    bnode->UpdateHeight();
    return bnode;
}

Node* LR(Node* anode)
{
    anode->left = RR(anode->left);
    return LL(anode);
}

Node* RL(Node* anode)
{
    anode->right = LL(anode->right);
    return RR(anode);
}

Node* Insert(Node* node,int val)
{
    if(node == NULL)
    {
        node = new Node();
        node->val = val;
    }
    else if(val > node->val)
    {
        node->right = Insert(node->right,val);
        int disH = node->DisHeight();
        if(disH == -2)
        {
            if(val > node->right->val) node = RR(node);
            else node = RL(node);
        }
    }
    else if(val < node->val)
    {
        node->left = Insert(node->left,val);
        int disH = node->DisHeight();
        if(disH == 2)
        {
            if(val < node->left->val) node = LL(node);
            else node = LR(node);
        }
    }
    node->UpdateHeight();
    return node;
}

Node* Delete(Node* node,int val)
{
    if(node == NULL){return NULL;}
    else if(node->val < val)
    {
        node->right = Delete(node->right,val);
    }
    else if(node->val > val)
    {
        node->left = Delete(node->left,val);
    }
    else
    {
        if(node->left)
        {
            Node* nd;
            for(nd=node->left;nd->right != NULL;nd = nd->right);
            node->val = nd->val;
            node->left = Delete(node->left,nd->val);
        }
        else if(node->right)
        {
            Node* nd;
            for(nd=node->right;nd->left != NULL;nd = nd->left);
            node->val = nd->val;
            node->right = Delete(node->right,nd->val);
        }
        else
        {
            delete node;
            return NULL;
        }
    }

    if(node->DisHeight()==2)
    {
        if(node->left->DisHeight()==1)
            node = LL(node);
        else node = LR(node);
    }
    else if(node->DisHeight()==-2)
    {
        if(node->right->DisHeight()==-1)
            node = RR(node);
        else node = RL(node);
    }

    node->UpdateHeight();
    return node;
}

void pre_travel(Node* node)
{
    if(node==NULL) return;
    printf("%d ",node->val);
    pre_travel(node->left);
    pre_travel(node->right);
}
void in_travel(Node* node)
{
    if(node==NULL) return;
    in_travel(node->left);
    printf("%d ",node->val);
    in_travel(node->right);
}

int main()
{
    //test code
    Node *root = NULL;
    root = Insert(root,5);
    root = Insert(root,6);
    root = Insert(root,3);
    root = Insert(root,2);
    root = Insert(root,4);
    root = Insert(root,1);
    root = Insert(root,9);
    root = Insert(root,8);
    root = Insert(root,7);

    printf("先序遍历:\n");
    pre_travel(root);
    printf("\n");
    printf("中序遍历:\n");
    in_travel(root);
    printf("\n");

    root = Delete(root,6);
    root = Delete(root,1);
    printf("\n先序遍历:\n");
    pre_travel(root);
    printf("\n");
    printf("中序遍历:\n");
    in_travel(root);
    printf("\n");
    return 0;
}

 

PAT1066,简单AVL的插入操作。

技术分享
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

struct Node
{
    int val;
    int H;
    Node* left;
    Node* right;
    Node()
    {
        H = 1;
        left = NULL;
        right = NULL;
    }
    int LH(){return left?left->H:0;}
    int RH(){return right?right->H:0;}
    void UpdateH(){H = max(LH(),RH())+1;}
    int DisH(){return LH() - RH();}
};

Node* LL(Node* anode)
{
    Node *bnode = anode->left;
    Node *cnode = bnode->right;
    bnode->right = anode;
    anode->left = cnode;
    anode->UpdateH();
    bnode->UpdateH();
    return bnode;
}

Node* RR(Node* anode)
{
    Node *bnode = anode->right;
    Node *cnode = bnode->left;
    bnode->left = anode;
    anode->right = cnode;
    anode->UpdateH();
    bnode->UpdateH();
    return bnode;
}

Node* LR(Node* anode)
{
    anode->left = RR(anode->left);
    return LL(anode);
}

Node* RL(Node* anode)
{
    anode->right = LL(anode->right);
    return RR(anode);
}

Node* Insert(Node* node,int val)
{
    if(node==NULL)
    {
        node = new Node();
        node->val = val;
    }
    else if(val > node->val)
    {
        node->right = Insert(node->right,val);
        if(node->DisH()==-2)
        {
            if(val > node->right->val) node = RR(node);
            else node = RL(node);
        }
    }
    else if(val < node->val)
    {
        node->left = Insert(node->left,val);
        if(node->DisH()==2)
        {
            if(val < node->left->val) node = LL(node);
            else node = LR(node);
        }
    }

    node->UpdateH();
    return node;
}

int main()
{
    int n;
    scanf("%d",&n);
    Node* root = NULL;
    for(int i=0;i<n;++i)
    {
        int val;
        scanf("%d",&val);
        root = Insert(root,val);
    }
    printf("%d\n",root->val);
    return 0;
}
View Code

 

以上是关于AVL树模板的主要内容,如果未能解决你的问题,请参考以下文章

PTA Root of AVL Tree (AVL树模板+四种旋转+指针)

PAT.1066 Root of AVL Tree(平衡树模板题)

PAT.1066 Root of AVL Tree(平衡树模板题)

平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板超详解

STL源码笔记(18)—平衡二叉树AVL(C++封装+模板)

avl树