avl

来源:互联网 发布:java session 原理 编辑:程序博客网 时间:2024/05/17 09:24
 
avl树,不管是插入,还是查找,还是搜索,平均的时间都是logn的复杂度
其中有四个基本旋转LL,LR,RR,RL
另外,删除的实现还是比较繁琐的,之前写过插入的实现,删除不过有现成实现的,现在整理如下:
**********************************************************************************************************************

#include<iostream>

using namespace std; 

#define MAX(a, b) ((a) > (b) ? (a) : (b))

#define HEIGHT(t) ((t) == NULL ? -1 : (t)->height)

struct node_t {

    struct node_t *lchild, *rchild; /* 分别指向左右子树 */

    int height;                     /* 树的高度 */

    /* 以下为用户数据,根据自己的需要进行修改 */

    int data;

};

/**

 *  向根为treeAVL树插入数据。

 *

 *  tree指向插入数据前AVL树的根。

 *  node指向包含待插入数据的node_t节点。

 *  compar指向节点之间的比较函数,由用户定义。

 *

 *  返回插入数据后AVL树的根。

 */

struct node_t *avlinsert(struct node_t *tree, struct node_t *node, 

                         int(*compar)(const void *, const void *));

/**

 *  从根为treeAVL树删除数据。

 *

 *  tree指向删除数据前AVL树的根。

 *  node指向包含待匹配数据的node_t节点。

 *  rmnode为一个二次指针,删除成功时*rmnode存放的是被删除节点指针,失败则为NULL

 *  compar指向节点之间的比较函数,由用户定义。

 *

 *  返回删除数据后AVL树的根。

 */

struct node_t *avlremove(struct node_t *tree, struct node_t *node, 

                         struct node_t **rmnode, 

                         int(*compar)(const void *, const void *));

/**

 *  从根为treeAVL树中搜索数据。

 *

 *  tree指向AVL树的根。

 *  node指向包含待匹配数据的node_t节点。

 *  compar指向节点之间的比较函数,由用户定义。

 *

 *  返回匹配数据节点,或者NULL

 */

struct node_t *avlsearch(struct node_t *tree, struct node_t *node, 

                         int(*compar)(const void *, const void *));

/**

 *  从根为treeAVL树中搜索最小数据节点。

 *

 *  返回最小数据节点,或者NULL(空树)。

 */

struct node_t *avlgetmin(struct node_t *tree);

/**

 *  从根为treeAVL树中搜索最大数据节点。

 *

 *  返回最大数据节点,或者NULL(空树)。

 */

struct node_t *avlgetmax(struct node_t *tree);

static struct node_t *avlsinglerotateleft(struct node_t *tree);

static struct node_t *avlsinglerotateright(struct node_t *tree);

static struct node_t *avldoublerotateleft(struct node_t *tree);

static struct node_t *avldoublerotateright(struct node_t *tree);

struct node_t *

avlinsert(struct node_t *tree, struct node_t *node, 

          int(*compar)(const void *, const void *))

{

    int ret;

    if (tree == NULL) {

        node->lchild = NULL;

        node->rchild = NULL;

        node->height = 0;

        return node;

    }

    /* insert */

    ret = compar(node, tree);

    if (ret < 0) {

        tree->lchild = avlinsert(tree->lchild, node, compar);

        if (HEIGHT(tree->lchild) - HEIGHT(tree->rchild) == 2) {

            /* 

                because the new node has been insert to tree->lchild 

                successfully and the tree's balance is broken, 

                the data must be not equal to tree->lchild->data.

            */

            ret = compar(node, tree->lchild);

            if (ret < 0) {                     //LL

                /* insert new node into the left branch fo the tree->lchild 

                   like below:

                         tree --> o

                                 /

                                o

                               /

                              o

                */

                tree = avlsinglerotateleft(tree);

            } else if (ret > 0) {             //LR

                /* insert new node into the left branch fo the tree->lchild

                   like below:

                         tree --> o

                                 /

                                o

                                 \

                                  o

                */

                tree = avldoublerotateleft(tree);

            }

        } else {

            tree->height = MAX(HEIGHT(tree->lchild), HEIGHT(tree->rchild)) + 1;    //修正高度这个域

        }

    } else if (ret > 0) {                                              //对应的右边也是如此

        tree->rchild = avlinsert(tree->rchild, node, compar); 

        if (HEIGHT(tree->rchild) - HEIGHT(tree->lchild) == 2) {

            ret = compar(node, tree->rchild);

            if (ret < 0) {                      //RL

                /*

                    tree --> o

                              \

                               o

                              /

                             o

                */

                tree = avldoublerotateright(tree);  //双右旋转

            } else if (ret > 0) {                  //

                /*

                    tree --> o

                              \

                               o

                                \

                                 o

                */

                tree = avlsinglerotateright(tree);    //RR

            }

        } else {

            tree->height = MAX(HEIGHT(tree->lchild), HEIGHT(tree->rchild)) + 1;

        }

    }

    /* else exist! return the original tree normally */

    return tree;

}

static struct node_t *

avlsinglerotateleft(struct node_t *tree)

{

    struct node_t *newtree;

    /*

        tree --> 1                  newtree --> 2

                /                              / \

               2        ---->                 3   1

              /

             3

    */

    /* 2 */

    newtree = tree->lchild;

    /* 1 */

    tree->lchild = newtree->rchild;

    tree->height = MAX(HEIGHT(tree->lchild), HEIGHT(tree->rchild)) + 1;

    /* 2 */

    newtree->rchild = tree;

    newtree->height = MAX(HEIGHT(newtree->lchild), HEIGHT(newtree->rchild)) + 1;

    return newtree;

}

static struct node_t *

avlsinglerotateright(struct node_t *tree)

{

    struct node_t *newtree;

    /*

        tree --> 1                  newtree --> 2

                  \                            / \

                   2    ---->                 1   3

                    \

                     3

    */

    /* 2 */

    newtree = tree->rchild;

    /* 1 */

    tree->rchild = newtree->lchild;

    tree->height = MAX(HEIGHT(tree->lchild), HEIGHT(tree->rchild)) + 1;

    /* 2 */

    newtree->lchild = tree;

    newtree->height = MAX(HEIGHT(newtree->lchild), HEIGHT(newtree->rchild)) + 1;

    return newtree;

}

static struct node_t *

avldoublerotateleft(struct node_t *tree)

{

    struct node_t *newtree;

    /*

        tree --> 1                  newtree --> 3

                /                              / \

               2        ---->                 2   1

                \

                 3

    */

    /* 3 */

    newtree = tree->lchild->rchild;

    /* 2 */

    tree->lchild->rchild = newtree->lchild;

    tree->lchild->height = MAX(HEIGHT(tree->lchild->lchild), HEIGHT(tree->lchild->rchild)) + 1;

    /* 3 */

    newtree->lchild = tree->lchild;

    /* 1 */

    tree->lchild = newtree->rchild;

    tree->height = MAX(HEIGHT(tree->lchild), HEIGHT(tree->rchild)) + 1;

    /* 3 */

    newtree->rchild = tree;

    newtree->height = MAX(HEIGHT(newtree->lchild), HEIGHT(newtree->rchild)) + 1;

    return newtree;

}

static struct node_t *

avldoublerotateright(struct node_t *tree)

{

    struct node_t *newtree;

    /*

        tree --> 1                  newtree --> 3

                  \                            / \

                   2    ---->                 1   2

                  /

                 3

    */

    /* 3 */

    newtree = tree->rchild->lchild;

    /* 2 */

    tree->rchild->lchild = newtree->rchild;

    tree->rchild->height = MAX(HEIGHT(tree->rchild->lchild), HEIGHT(tree->rchild->rchild)) + 1;

    /* 3 */

    newtree->rchild = tree->rchild;

    /* 1 */

    tree->rchild = newtree->lchild;

    tree->height = MAX(HEIGHT(tree->lchild), HEIGHT(tree->rchild)) + 1;

    /* 3 */

    newtree->lchild = tree;

    newtree->height = MAX(HEIGHT(newtree->lchild), HEIGHT(newtree->rchild)) + 1;

    return newtree;

}

struct node_t *

avlremove(struct node_t *tree, struct node_t *node, struct node_t **rmnode, 

          int(*compar)(const void *, const void *))

{

    int ret;

    if (rmnode)

        *rmnode = NULL;

    ret = compar(node, tree);

    if (ret == 0) {

        struct node_t *tmpnode;

        /* found */

        if (tree->lchild != NULL && tree->rchild != NULL) {

            /* 2 child */

            tmpnode = avlgetmin(tree->rchild);

            tree->rchild = avlremove(tree->rchild, tmpnode, rmnode, compar);

            tmpnode->lchild = tree->lchild;

            tmpnode->rchild = tree->rchild;

            if (rmnode)

                *rmnode = tree;

            tree = tmpnode;

        } else {

            /* 1 or 0 child */

            if (tree->lchild)

                tmpnode = tree->lchild;

            else if (tree->rchild)

                tmpnode = tree->rchild;

            else 

                tmpnode = NULL;

            if (rmnode)

                *rmnode = tree;

            return tmpnode;

        }

    } else if (ret < 0) {

        if (tree->lchild != NULL)

            tree->lchild = avlremove(tree->lchild, node, rmnode, compar);

    } else {

        /* ret > 0 */

        if (tree->rchild != NULL)

            tree->rchild = avlremove(tree->rchild, node, rmnode, compar);

    }

    /* check balance */

    if (HEIGHT(tree->lchild) - HEIGHT(tree->rchild) == 2) {

        /* left rotate */

        if (HEIGHT(tree->lchild->lchild) - HEIGHT(tree->rchild) == 1

            && HEIGHT(tree->lchild->rchild) - HEIGHT(tree->rchild) == 1)

        {

            /*

                tree --> o

                        /

                       o

                      / \

                     o   o

            */

            tree = avlsinglerotateleft(tree);

        } else if (HEIGHT(tree->lchild->lchild) - HEIGHT(tree->rchild) == 1) {

            /*

                tree --> o

                        /

                       o

                      /

                     o

            */

            tree = avlsinglerotateleft(tree);

        } else if (HEIGHT(tree->lchild->rchild) - HEIGHT(tree->rchild) == 1) {

            /*

                tree --> o

                        /

                       o

                        \

                         o

            */

            tree = avldoublerotateleft(tree);

        }

    } else if (HEIGHT(tree->rchild) - HEIGHT(tree->lchild) == 2) {

        /* right rotate */

        if (HEIGHT(tree->rchild->rchild) - HEIGHT(tree->lchild) == 1

            && HEIGHT(tree->rchild->lchild) - HEIGHT(tree->lchild) == 1)

        {

            /*

                tree --> o

                          \

                           o

                          / \

                         o   o

            */

            tree = avlsinglerotateright(tree);

        } else if (HEIGHT(tree->rchild->rchild) - HEIGHT(tree->lchild) == 1) {

            /*

                tree --> o

                          \

                           o

                            \

                             o

            */

            tree = avlsinglerotateright(tree);

        } else if (HEIGHT(tree->rchild->lchild) - HEIGHT(tree->lchild) == 1) {

            /*

                tree --> o

                          \

                           o

                          /

                         o

            */

            tree = avldoublerotateright(tree);

        }

    }

    tree->height = MAX(HEIGHT(tree->lchild), HEIGHT(tree->rchild)) + 1;

    return tree;

}

struct node_t *

avlsearch(struct node_t *tree, struct node_t *node, 

          int(*compar)(const void *, const void *))

{

    int ret;

    struct node_t *t;

    t = tree;

    while (t != NULL) {

        ret = compar(node, t);

        if (ret < 0) {

            t = t->lchild;

        } else if (ret > 0) {

            t = t->rchild;

        } else {

            /* found */

            return t;

        }

    }

    return NULL;

}

struct node_t *

avlgetmin(struct node_t *tree)

{

    struct node_t *t;

    if (tree == NULL)

        return NULL;

    t = tree;

    while (t->lchild != NULL)

        t = t->lchild;

    return t;

}

struct node_t *

avlgetmax(struct node_t *tree)

{

    struct node_t *t;

    if (tree == NULL)

        return NULL;

    t = tree;

    while (t->rchild != NULL)

        t = t->rchild;

    return t;

}

static int compar(const void *a, const void *b)

{

    if (((struct node_t *)a)->data > ((struct node_t *)b)->data)

        return 1;

    else if (((struct node_t *)a)->data < ((struct node_t *)b)->data)

        return -1;

    else

        return 0;

}

void disp(node_t *tree)  //括号表示法输出 

{

  if(tree!=NULL){

  cout<<tree->data;

  if(tree->lchild!=NULL||tree->rchild!=NULL)

  {

     cout<<"(";

    // if(node->lchild!=NULL)

       disp(tree->lchild);

    // cout<<",";

     if(tree->rchild!=NULL)

       cout<<",";

     disp(tree->rchild);

       cout<<")"; 

  } 

 }

}

int main()

{

    int a[] = { 16,3,7,11,9,26,18,14,15};   //数据结构书上的图9.14 

    node_t *nodemery[9];

    node_t *root=NULL;

    for(int i=0;i<9;i++)

     {

       nodemery[i]=new node_t;

       nodemery[i]->data=a[i];

       root=avlinsert(root,nodemery[i],compar);

     }

    cout<<"after insertthe tree is: \n";

    disp(root); 

    cout<<endl;

    root=avlremove(root,nodemery[3],&nodemery[3],compar);

    root=avlremove(root,nodemery[4],&nodemery[4],compar);

    

    cout<<"after remove 11,9,the tree is:\n";

    disp(root);

    cout<<endl;

    

    node_t *found=avlsearch(root,nodemery[5],compar);

    if(found==NULL)

     cout<<"没有该数据";

    else

     cout<<"你要找的值是:"<<found->data<<endl;

     

    node_t *found2=avlsearch(root,nodemery[3],compar);

    if(found2==NULL)

     cout<<"没有该数据";

    else

     cout<<"你要找的值是:"<<found2->data<<endl; 

     cout<<endl;

    

    system("pause");

}

有关资料:

http://zh.wikipedia.org/wiki/AVL%E6%A0%91

http://hi.baidu.com/bellgrade/blog/item/6c7d72614e8370ca8db10dea.html