AVL树

这里只介绍生成AVL树的代码。

AVL树插入先按照普通有序二叉树的方法插入节点。插入了之后,父节点新插入方向上的子树高度增1。如果是左侧,平衡因子–,右侧++。++和–都代表某侧的高度在增加。

AVL树允许两边子树有1层差距,超过之后需要调整。细分有LL型,LR型,RL型,RR型,4种情况。调整是对2-3个节点局部中序重排。LL型RR型调整2个节点,有一个子树迁移,LR型RL型调整3个节点,有两个子树迁移。重排后原则上每个节点的平衡因子都为0, 除了LR型RL型中间那个节点两个子树不一样高的情况, 这时除了矮的那棵子树, 这些节点周围的其他3个子树都一样高。

下面是code:

#include <stdio.h>

struct node {
        int key;
        int tag;
        struct node *parent;
        struct node *left;
        struct node *right;
};


struct tree_rec {
        struct node *root;
};

插入操作:

int insert(struct tree_rec *tree, int key)
{
        struct node *p;
        struct node *next;
        struct node *left, *right, *mid;

        p = tree->root;
loc:
        if (key> p->key) next = p->right;
        else if(key <p->key) next = p->left;
        else return 0;

        if (next) {
                p = next;
                goto loc;
        }

        next = (struct node*) malloc(sizeof(struct node));
        next->key=key;
        next->tag=0;
        next->parent=p;
        next->left=next->right=NULL;
        if (key>p->key) {
                p->right=next;
                p->tag++;
        }
        else {
                p->left=next;
                p->tag--;
        }

up:
        if (p->tag==0) return 1;
        next = p->parent;
        if (next == NULL)return 1;
        if (p==next->left) next->tag--;
        else next->tag++;

        if (next->tag==2) {
                if (p->tag==1) {
                        left = p->left;
                        p->left = next;
                        next->right= left;
                        if (left) left->parent=next;
                        p->tag=0;
                        next->tag=0;
                        if( next->parent==NULL) {
                                p->parent=NULL;
                                tree->root=p;
                        }
                        else {
                                p->parent=next->parent;
                                if (next==next->parent->left)
                                        next->parent->left =p;
                                else next->parent->right=p;
                        }
                        next->parent=p;
                        return 1;
                }
                else { /* p->tag==-1 */
                        mid = p->left;
                        left = mid->left;
                        right = mid->right;
                        mid->left = next;
                        mid->right = p;
                        next->right = left;
                        if(left) left->parent = next;
                        p->left = right;
                        if(right) right->parent =p;

                        if (mid->tag==0) {
                                next->tag=p->tag=mid->tag=0;
                        }
                        else if(mid->tag==1) {
                                next->tag=-1;
                                p->tag=mid->tag=0;
                        }
                        else {
                                next->tag = mid->tag=0;
                                p->tag = 1;
                        }

                        if (next->parent==NULL) {
                                mid->parent = NULL;
                                tree->root = mid;
                        }
                        else {
                                mid->parent = next->parent;
                                if (next==next->parent->left)
                                        next->parent->left =mid;
                                else next->parent->right=mid;
                        }
                        next->parent = mid;
                        p->parent = mid;
                        return 1;
                }

        }
        else if(next->tag==-2) {
                if (p->tag==-1) {
                        right = p->right;
                        p->right = next;
                        next->left= right;
                        if (right) right->parent=next;
                        p->tag=0;
                        next->tag=0;
                        if( next->parent==NULL) {
                                p->parent=NULL;
                                tree->root=p;
                        }
                        else {
                                p->parent=next->parent;
                                if (next==next->parent->left)
                                        next->parent->left =p;
                                else next->parent->right=p;
                        }
                        next->parent=p;
                        return 1;
                }
                else { /* p->tag==1 */
                        mid = p->right;
                        left = mid->left;
                        right = mid->right;
                        mid->left = p;
                        mid->right = next;
                        p->right = left;
                        if(left) left->parent = p;
                        next->left = right;
                        if(right) right->parent =next;

                        if (mid->tag==0) {
                                next->tag=p->tag=mid->tag=0;
                        }
                        else if(mid->tag==1) {
                                p->tag=-1;
                                next->tag=mid->tag=0;
                        }
                        else {
                                p->tag = mid->tag=0;
                                next->tag = 1;
                        }

                        if (next->parent==NULL) {
                                mid->parent = NULL;
                                tree->root = mid;
                        }
                        else {
                                mid->parent = next->parent;
                                if (next==next->parent->left)
                                        next->parent->left =mid;
                                else next->parent->right=mid;
                        }
                        next->parent = mid;
                        p->parent = mid;
                        return 1;
                }
        }
        else {
                p = next;
                goto up;
        }
}

以下测试代码:

int keys[] = {
        35, 36, 37, 38, 39, 40,
        8,9,10, 11,12, 13, 14,
        41,42, 43,44,45,
        58,59,60,
        1, 2,3,4, 5, 6, 7,
        21, 22, 23, 24, 25, 26,27,
        15, 16, 17,18, 19, 20,
        51,52,53,54,55,56,57,
        28, 29, 30, 31, 32, 33, 34,
        46,47,48,49, 50,
};

int level(struct node *p)
{
        int i=0;
        while (p){
                ++i;
                p= p->parent;
        }
        return i-1;
}

void printtree(struct tree_rec *tree)
{
        struct node *p;
        int i;
        int curlevel;
        struct node *queue[200];
        int first, last;

        first=last=0;
        curlevel=0;


        p = tree->root;
        if(p) {
                printf("%d: ", curlevel);
                printf("%d",p->key);
                if(p->left) queue[last++] = p->left;
                if(p->right) queue[last++] = p->right;
        }

        while(first<last) {
                p = queue[first++];
                if (level(p)>curlevel) {
                        printf("\n");
                        curlevel++;
                        printf("%d:", curlevel);
                }
                if(p==p->parent->left) printf(" %d(<-%d)",p->key,p->parent->key)
;
                else printf(" (%d->)%d",p->parent->key,p->key);
                if(p->left) queue[last++] = p->left;
                if(p->right) queue[last++] = p->right;
        }
        printf("\n");
}

int main()
{
        struct tree_rec r;
        int i;

        srand(time(0));
        for(i=0; i<20; i++) {
                int a, b;
                a= rand()%(sizeof(keys)/sizeof(int));
                b= rand()%(sizeof(keys)/sizeof(int));
                if (a!=b) {
                        int t;
                        t=keys[a];
                        keys[a]=keys[b];
                        keys[b]=t;
                }
        }

        r.root = (struct node*)malloc(sizeof(struct node));
        r.root->key=keys[0];
        r.root->tag=0;
        r.root->parent=NULL;
        r.root->left=r.root->right=NULL;


        for( i=1; i<60; i++) {
                insert( &r, keys[i]);
                printtree(&r);
        }

        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值