平衡二叉树 AVL

笔记:
1、 在包含有n个结点的平衡树上查找的时间复杂度为 O(log n),深度也和O(log n)同数量级。
在平衡树上进行查找的过程和排序树相同,因此,在查找过程中和给定值进行比较的关键字个数不超过树的深度。
2、 二叉排序树又称为二叉查找树。
3、 平衡二叉树必须是二叉查找树。
4、 AVL树的查找、插入、删除操作在平均和最坏的情况下都是O(logn),这得益于它时刻维护着二叉树的平衡。如果我们需要查找的集合本身没有顺序,在频繁查找的同时也经常的插入和删除,AVL树是不错的选择。不平衡的二叉查找树在查找时的效率是很低的,因此,AVL如何维护二叉树的平衡是我们的学习重点。
注意:对于平衡因子的计算建议通过记录树的高度来计算比较方便,单纯的记录平衡因子会很麻烦。
推荐两个比较好的网址:
http://www.cnblogs.com/QG-whz/p/5167238.html
http://blog.csdn.net/whucyl/article/details/17289841
实现代码:

#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <math.h>
typedef int ATElemType;
using namespace std;

typedef struct ATNode
{
    ATElemType key;
    int height;
    struct ATNode *lChild;
    struct ATNode *rChild;
}ATNode, *AVLtree;
///Get height
int GetHeight(AVLtree root)
{
    if(root==NULL)
        return 0;
    else
        return root->height;
}
///Update height
void updateHeight(AVLtree &root)
{
    if(root!=NULL)
        root->height=max(GetHeight(root->lChild),GetHeight(root->rChild))+1;
}
///LL型,右旋
void rRotate(AVLtree &root)
{
    ATNode *p=root->lChild;
    root->lChild=p->rChild;
    p->rChild=root;
    updateHeight(root);
    updateHeight(p);
    root=p;
}
///RR型,左旋
void lRotate(AVLtree &root)
{
    ATNode *p=root->rChild;
    root->rChild=p->lChild;
    p->lChild=root;
    updateHeight(root);
    updateHeight(p);
    root=p;
}
///LR型,左旋再右旋
void LRrotate(AVLtree &root)
{
    lRotate(root->lChild);
    rRotate(root);
}
///RL型,右旋再左旋
void RLrotate(AVLtree &root)
{
    rRotate(root->rChild);
    lRotate(root);
}
///插入节点--递归
AVLtree insertElem_AVL(AVLtree &root,ATElemType eKey)
{
    if(root!=NULL)
    {
        if(root->key==eKey)
        {
            return root;
        }
        else if(root->key>eKey)  //插在左子树上
        {
            root->lChild=insertElem_AVL(root->lChild,eKey);
            updateHeight(root);
            if(GetHeight(root->lChild)-GetHeight(root->rChild)==2)
            {
                if(GetHeight(root->lChild->lChild)>GetHeight(root->lChild->rChild))  //LL
                    rRotate(root);
                else  //LR
                    LRrotate(root);
            }
        }
        else //root->key<eKey //插在右子树上
        {
            root->rChild=insertElem_AVL(root->rChild,eKey);
            updateHeight(root);
            if(GetHeight(root->lChild)-GetHeight(root->rChild)==-2)
            {
                if(GetHeight(root->rChild->rChild)>GetHeight(root->rChild->lChild))//RR
                    lRotate(root);
                else  //RL
                    RLrotate(root);
            }
        }
        return root;
    }
    else
    {
        root=(AVLtree)malloc(sizeof(ATNode));
        root->key=eKey;
        root->height=1;
        root->lChild=root->rChild=NULL;
        return root;
    }
}
///求一棵树中的最大值点
AVLtree maxValue_AVL(AVLtree root)
{
    if(root!=NULL)
    {
        ATNode *p;
        for(p=root;p->rChild!=NULL;p=p->rChild){}
        return p;
    }
}
///求一棵树中的最小值点
AVLtree minValue_AVL(AVLtree root)
{
    if(root!=NULL)
    {
        ATNode *p;
        for(p=root;p->lChild!=NULL;p=p->lChild){}
        return p;
    }
}
///删除指定的元素
AVLtree DeleteElem_AVL(AVLtree &root,ATElemType eKey)
{
    if(root!=NULL)
    {
        if(root->key==eKey)
        {
            if(root->lChild==NULL&&root->rChild==NULL)
            {
                free(root);
                root=NULL;
                return root;
            }
            else if(root->lChild==NULL)
            {
                ATNode *p=root;
                root=root->rChild;
                free(p);
                p=NULL;
                return root;
            }
            else if(root->rChild==NULL)
            {
                ATNode *p=root;
                root=root->lChild;
                free(p);
                p=NULL;
                return root;
            }
            else  //左右子树均不为空
            {
                if(GetHeight(root->lChild)>=GetHeight(root->rChild))  //左子树高
                {
                    root->key=maxValue_AVL(root->lChild)->key;
                    root->lChild=DeleteElem_AVL(root->lChild,root->key);
                    updateHeight(root);
                    if(GetHeight(root->rChild)-GetHeight(root->lChild)==2)//在左子树上删除结点相当于在右子树上插入节点
                    {
                        if(GetHeight(root->rChild->rChild)>GetHeight(root->rChild->lChild))
                            lRotate(root);
                        else
                            RLrotate(root);
                    }
                }
                else  //右子树高
                {
                    root->key=minValue_AVL(root->rChild)->key;
                    root->rChild=DeleteElem_AVL(root->rChild,root->key);
                    updateHeight(root);
                    if(GetHeight(root->lChild)-GetHeight(root->rChild)==2)//在右子树上删除结点相当于在左子树上插入节点
                    {
                        if(GetHeight(root->lChild->lChild)>GetHeight(root->lChild->rChild))
                            rRotate(root);
                        else
                            LRrotate(root);
                    }
                }
                return root;
            }
        }
        else if(root->key>eKey) //在左子树上
        {
            root->lChild=DeleteElem_AVL(root->lChild,eKey);
            updateHeight(root);
            if(GetHeight(root->rChild)-GetHeight(root->lChild)==2)//在左子树上删除结点相当于在右子树上插入节点
            {
                if(GetHeight(root->rChild->rChild)>GetHeight(root->rChild->lChild))
                    lRotate(root);
                else
                    RLrotate(root);
            }
            return root;
        }
        else  //在右子树上
        {
            root->rChild=DeleteElem_AVL(root->rChild,eKey);
            updateHeight(root);
            if(GetHeight(root->lChild)-GetHeight(root->rChild)==2)//在右子树上删除结点相当于在左子树上插入节点
            {
                if(GetHeight(root->lChild->lChild)>GetHeight(root->lChild->rChild))
                    rRotate(root);
                else
                    LRrotate(root);
            }
            return root;
        }
    }
    else
        return NULL;
}
///中序遍历
void Inorder_AVL(AVLtree root)
{
    if(root)
    {
        Inorder_AVL(root->lChild);
        printf("%d ",root->key);
        Inorder_AVL(root->rChild);
    }
}
///前序遍历
void PreOrder_AVL(AVLtree root)
{
    if(root)
    {
        printf("%d ",root->key);
        PreOrder_AVL(root->lChild);
        PreOrder_AVL(root->rChild);
    }
}
///后序遍历
void PostOrder_AVL(AVLtree root)
{
    if(root)
    {
        PostOrder_AVL(root->lChild);
        PostOrder_AVL(root->rChild);
        printf("%d ",root->key);
    }
}
///查找元素---递归
AVLtree searchElem_AVL(AVLtree root,ATElemType eKey)
{
    if(root)
    {
        if(root->key==eKey)
            return root;
        else if(root->key>eKey)
            searchElem_AVL(root->lChild,eKey);
        else
            searchElem_AVL(root->rChild,eKey);
    }
    else
        return NULL;
}
///查找元素---非递归
AVLtree searElemNoRecurse_AVL(AVLtree root,ATElemType eKey)
{
    ATNode *p=root;
    while(p)
    {
        if(p->key==eKey)
            return p;
        else if(p->key>eKey)
            p=p->lChild;
        else
            p=p->rChild;
    }
    return NULL;
}
///销毁AVL
void Destroy_AVL(AVLtree &root)
{
    if(root)
    {
        Destroy_AVL(root->lChild);
        Destroy_AVL(root->rChild);
        free(root);
        root=NULL;
    }
}

int main()
{
    AVLtree mAVL=NULL;
    //---test insert---
    insertElem_AVL(mAVL,5);
    insertElem_AVL(mAVL,8);
    insertElem_AVL(mAVL,7);
    insertElem_AVL(mAVL,2);
    insertElem_AVL(mAVL,3);
    insertElem_AVL(mAVL,4);
    insertElem_AVL(mAVL,6);
    insertElem_AVL(mAVL,9);
    int height=GetHeight(mAVL);
    printf("%d\n",height);
    Inorder_AVL(mAVL);
    printf("\n");
    //--test delete---
// DeleteElem_AVL(mAVL,5);
// height=GetHeight(mAVL);
// printf("%d\n",height);
// Inorder_AVL(mAVL);
// printf("\n");
// printf("%d\n",mAVL->key);
    //---test preOrder---
// PreOrder_AVL(mAVL);
// printf("\n");
    //---test postOrder---
// PostOrder_AVL(mAVL);
// printf("\n");
    //---test search(递归)---
// printf("%d\n",searchElem_AVL(mAVL,8)->key);
    //---test search(非递归)---
// printf("%d\n",searElemNoRecurse_AVL(mAVL,6)->key);
    //---test Destroy---
    Destroy_AVL(mAVL);
    printf("Test Destroy!\n");
    return 0;
}
    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/ortyijing/article/details/76407696
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞