AVL搜索树

来源:互联网 发布:腾讯游戏有mac版吗 编辑:程序博客网 时间:2024/05/23 01:13

AVL搜索树是二叉排序数的一个改进,在AVL中任何两个儿子子树的高度差不超过1,故查找、删除、插入在平均和最坏情况下都是O(logn)。

代码如下:

#include<iostream>#include<cstdlib>#include<ctime>#include<cstdio>#include<cmath>using namespace std;typedef struct AVLTree{  int nData,nHeight;  struct AVLTree* pLeft;  struct AVLTree* pRight;}AVLTree;int max(int a,int b);int Height(AVLTree* pNode);AVLTree* Insert(int nData,AVLTree *pNode);AVLTree* LLRotate(AVLTree* pNode);AVLTree* RRRotate(AVLTree* pNode);AVLTree* LRRotate(AVLTree* pNode);AVLTree* RLRotate(AVLTree* pNode);void DeleteTree(AVLTree** ppRoot);void PrintTree(AVLTree* pRoot);int main(){    int i,x;    AVLTree* pRoot = NULL;    srand((unsigned int)time(NULL));    for (i = 0; i < 20; i++){        x = rand() % 100;        cout<<x<<' ';        pRoot = Insert(x,pRoot);    }    cout<<endl;    PrintTree(pRoot);    DeleteTree(&pRoot);    return 0;}int max(int a,int b){    return (a>b?a:b);}int Height(AVLTree* pNode){    if (pNode == NULL) return -1;    return pNode -> nHeight;}AVLTree* Insert(int nData,AVLTree *pNode){    if (pNode == NULL){        pNode = (AVLTree* )malloc(sizeof(AVLTree));        pNode->nData = nData;        pNode->nHeight = 0;        pNode->pLeft = pNode->pRight = NULL;    } else if ( nData < pNode->nData )//插入到左子树中去    {        pNode -> pLeft = Insert(nData, pNode -> pLeft);        if ( Height(pNode -> pLeft) - Height(pNode -> pRight) == 2)        {            if (nData < pNode -> pLeft -> nData){                pNode = LLRotate(pNode);//LL型旋转            } else pNode = LRRotate(pNode);//LR型旋转        }    } else if ( nData > pNode -> nData)//插入到右子树中去    {        pNode -> pRight = Insert(nData, pNode -> pRight);        if ( Height(pNode -> pRight) - Height(pNode -> pLeft) == 2)        {            if (nData < pNode -> pRight -> nData){                pNode = RLRotate(pNode);//RL型旋转            } else pNode = RRRotate(pNode);//RR型旋转        }    }    pNode -> nHeight = max(Height(pNode -> pLeft),Height(pNode -> pRight)) + 1;    return pNode;}AVLTree* LLRotate(AVLTree* pNode){    AVLTree* p1;    p1 = pNode -> pLeft;    pNode -> pLeft = p1 -> pRight;    p1 -> pRight = pNode;    pNode -> nHeight = max(Height(pNode -> pLeft),Height(pNode -> pRight)) + 1;    p1 -> nHeight = max(Height(p1 -> pLeft),pNode -> nHeight) + 1;    return p1;}AVLTree* RRRotate(AVLTree* pNode){    AVLTree* p1;    p1 = pNode -> pRight;    pNode -> pRight = p1 -> pLeft;    p1 -> pLeft = pNode;    pNode -> nHeight = max(Height(pNode -> pLeft),Height(pNode -> pRight)) + 1;    p1 -> nHeight = max(Height(p1 -> pRight),pNode -> nHeight) + 1;    return p1;}AVLTree* LRRotate(AVLTree* pNode){    pNode -> pLeft = RRRotate(pNode -> pLeft);    return LLRotate(pNode);}AVLTree* RLRotate(AVLTree* pNode){    pNode -> pRight = LLRotate(pNode -> pRight);    return RRRotate(pNode);}void DeleteTree(AVLTree** ppRoot){    if ( ppRoot == NULL || *ppRoot == NULL)        return ;    DeleteTree(&((*ppRoot) -> pLeft));    DeleteTree(&((*ppRoot) -> pRight));    free( *ppRoot);    *ppRoot = NULL;}void PrintTree(AVLTree* pRoot){    if (pRoot == NULL ) return;    static int n = 0;    PrintTree(pRoot -> pLeft);    printf("[%d]nData = %d %d\n",++n,pRoot -> nData, pRoot -> nHeight);    PrintTree(pRoot -> pRight);}
这里只写了插入操作,查询操作比较简单,删除和插入也很相似,不过要考虑删除当前节点后,用该节点的哪个儿子来代替自己的位置。

插入操作时会出现当前搜索树不再是AVL搜索树的情况,这时需要对树进行维护,有4种情况LL型、LR型、RR型、RL型,学AVL搜索树主要要把这四种情况的维护了解,基本就学会了。

在整个代码过程中,要记得更新节点的高度,方便后续操作。

具体可以看下维基百科:https://zh.wikipedia.org/wiki/AVL%E6%A0%91

例题:poj2418  Hardwood Species 

可以用AVL树练习一下,也可以用其它方法做,代码会在其它blog上贴出

0 0