| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3193 人关注过本帖
标题:AVL树的实现代码
只看楼主 加入收藏
zhu224039
Rank: 8Rank: 8
等 级:贵宾
威 望:17
帖 子:862
专家分:792
注 册:2012-7-29
结帖率:59.52%
收藏
 问题点数:0 回复次数:5 
AVL树的实现代码

#include"stdio.h"
#include <stdlib.h>
#include"string.h"
typedef struct tree  /*树结构*/
{
    int i;     /*数据区*/
    int treehigh;  /*存放节点深度*/
    struct tree *lift;  
    struct tree *right;
}tree;

tree *creatjiedian()  /*创建节点*/
{
    tree *p;
    p=(tree*)malloc(sizeof(tree));
    if(p==NULL)
        printf("地址申请失败");
    else
    {
        p->lift=p->right=NULL;
        p->treehigh=0;
    }
    return p;
}

int ax(int a,int b)  /*比较数的大小*/
{
    if(a>b)
        return a;
    else
        return b;
}


        
tree *charujiedian(tree *p,int x)   /*将节点插入到AVL树里*/
{
    if(p==NULL)
    {
        p=creatjiedian();
        p->i=x;
    }
    else if(p->i>x)  
    {
        p->lift=charujiedian(p->lift,x);
        p->lift->treehigh=p->treehigh+1;  /*计算节点的深度*/
    }
    else if(p->i<x)
    {
        p->right=charujiedian(p->right,x);
        
        p->right->treehigh=p->treehigh+1; /*计算节点的深度*/
    }
    return p;
}

tree *zuodanxuan(tree *p)   /*在P的左儿子的左子树的插入 左旋转*/
{
    tree *p1;
    p1=p->lift;
    p->lift=p1->right;
    p1->right=p;
    return p1;
}

tree *youdanxuan(tree *p) /*在p的右儿子的右子树上的插入 右旋转*/
{
    tree *p1;
    p1=p->right;
    p->right=p1->lift;
    p1->lift=p;
    return p1;
}

tree *zuoshuangxuan(tree *p)  /*在P的左儿子的右子树上的插入 右单旋+左单旋转*/
{
    tree *p1;
    p1=p->lift;
    p->lift=youdanxuan(p1);
    return zuodanxuan(p);
}

tree *youshuangxuan(tree *p)  /*在P的右儿子的左子树上的插入*/
{
    tree *p1;
    p1=p->right;
    p->right=zuodanxuan(p1);
    return youdanxuan (p);
}

void zenggengxin(tree *p)   /*将P的所有子树深度加1*/
{
    if(p!=NULL)
    {
        p->treehigh++;
        zenggengxin(p->lift);
        zenggengxin(p->right);
    }   
}

void jiangengxin(tree *p)  /*将P的所有子树深度减1*/
{
    if(p!=NULL)
    {
    p->treehigh--;
    jiangengxin(p->lift);
    jiangengxin(p->right);
    }
}


void dayin(tree *p)          /*先序遍历*/
{   
    if(p!=NULL)
    {
        printf("%d %d\n",p->i,p->treehigh);
        
      dayin(p->lift);
      dayin(p->right);
    }
}

int high(tree *p)   /*计算P的树高*/
{
    int n;
    if(p==NULL)
        n=-1;
    else
    {
    if(p->lift==NULL&&p->right==NULL)
        n=0;
    else if(p->lift!=NULL&&p->right==NULL)
        n=1+high(p->lift);
    else if(p->lift==NULL&&p->right!=NULL)
        n=1+high(p->right);
    else
        n=1+ax(high(p->right),high(p->lift));
    }
   return n;
}

tree *avlpingheng(tree *p2,int x)   /*AVL树的自我平衡*/
{
    tree *p;
    if(x<p2->i&&x<p2->lift->i)
        {
        
            p=zuodanxuan(p2);
            if(p->lift!=NULL)          /*经过平衡后,重新更新子树的深度*/
            jiangengxin(p->lift);
            p->right->treehigh++;
            if(p->right->right!=NULL)
            zenggengxin(p->right->right);
        }
    else if(x<p2->i&&x>p2->lift->i)
        {
            p=zuoshuangxuan(p2);
            if(p->lift->right!=NULL)         /*经过平衡后,重新更新子树的深度*/
            jiangengxin(p->lift->right);
            if(p->right->lift!=NULL)
            jiangengxin(p->right->lift);
            if(p->right->right!=NULL)
            zenggengxin(p->right->right);
            p->right->treehigh++;
        }
    else if(x>p2->i&&x>p2->right->i)
    {      
            p=youdanxuan(p2);
            if(p->right!=NULL)
            jiangengxin(p->right);         /*经过平衡后,重新更新子树的深度*/
            p->lift->treehigh++;
            if(p->lift->lift!=NULL)
            zenggengxin(p->lift->lift);
    }
    else
    {
            p=youshuangxuan(p2);
            if(p->right->lift!=NULL)               /*经过平衡后,重新更新子树的深度*/
            jiangengxin(p->right->lift);      
            if(p->lift->right!=NULL)
            jiangengxin(p->lift->right);
            if(p->lift->lift!=NULL)
            zenggengxin(p->lift->lift);
            p->lift->treehigh++;
    }

     return p;   
}


void main()
{
    tree *p,*p1,*p2,*root,*p3,*p4;  /*root记录当前树根,P1用来查找从根到插入点的路径,p2记录每次查找的子树的父亲 p3记录失衡点的父亲,p4记录失衡点*/
    int i,j;                       /*i用来标记是否有失衡点(1个或者多个)j用来记录树结构体数据的*/
    p=creatjiedian();
    root=p;
    printf("请输入根节点数据:\n");
    scanf("%d",&j);
    p->i=j;
    i=0;
    printf("请输入节点数据:\n");
    scanf("%d",&j);
    charujiedian(root,j);
    p1=root;
    while(j!=0)                                /*创建AVL树约定输入0为结束*/
    {
        charujiedian(root,j);
        while(p1->i!=j)             /*遍历从根到插入数据的路径*/
        {   
            if(high(p1->lift)-high(p1->right)==2||high(p1->lift)-high(p1->right)==-2)    /*判定是否为失衡点,并找出最接近插入点的失衡点*/
            {
                i++;
                p3=p2;
                p4=p1;
                if(j>p1->i)
                {
                    p2=p1;
                    p1=p1->right;
                }
                else
                {
                    p2=p1;
                    p1=p1->lift;
                }
            }
            else
            {
                if(j>p1->i)
                {
                p2=p1;
                p1=p1->right;
                }
                else
                {  
                    p2=p1;
                    p1=p1->lift;
                }
            }
            
        }
        
        if(i==1)   /*i=1 代表根是不平衡点*/
        {
            root=avlpingheng(p4,j);
            root->treehigh--;
        }
        else if(i>1)   /*代表子树是不平衡点*/
        {
            p4=avlpingheng(p4,j);
            if(p4->i<p3->i)
            p3->lift=p4;
            else
                p3->right=p4;
            p4->treehigh=p3->treehigh+1;
        }
        p1=root;                       /*p1也必须重置,因为只两个是循环和判断的起始*/
        i=0;                           /*i值必须重置*/
        printf("请输入节点数据:\n");
        scanf("%d",&j);
    }
dayin(root);                          /*打印*/

}
搜索更多相关主题的帖子: include return 
2012-08-05 07:47
zhu224039
Rank: 8Rank: 8
等 级:贵宾
威 望:17
帖 子:862
专家分:792
注 册:2012-7-29
收藏
得分:0 
送给  伸手党

我要成为嘿嘿的黑客,替天行道
2012-09-17 18:24
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
意义何在?AVL的代码这么长?那我还不如继续用treap
2012-09-17 23:54
zhu224039
Rank: 8Rank: 8
等 级:贵宾
威 望:17
帖 子:862
专家分:792
注 册:2012-7-29
收藏
得分:0 
意义在于我理解了自然语言表述下的AVL树的各种属性有
意义在于我讲自然语言用C语言让计算机也明白我要干什么了,并且我正确的和计算机实现良好的沟通,并得到了正确的回应。
意义在于前人留下的经典思想,我又继承了一点

你的意义在于看到了代码 好长哟 感叹词!!!!!!
你的意义在于我有treep 好牛X  感叹词!!!!!!
你还有个意义在于  你好无聊啊 我发出的感叹词!!!!!!!!!!!!

我要成为嘿嘿的黑客,替天行道
2012-09-19 06:11
zhu224039
Rank: 8Rank: 8
等 级:贵宾
威 望:17
帖 子:862
专家分:792
注 册:2012-7-29
收藏
得分:0 
这个可以上去了

我要成为嘿嘿的黑客,替天行道
2012-11-21 07:10
nowhyz1234
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2013-1-3
收藏
得分:0 
表示不知道你这个该怎么用
2013-01-04 21:03
快速回复:AVL树的实现代码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016599 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved