| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5280 人关注过本帖
标题:AVL树(迭代版本)
只看楼主 加入收藏
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
结帖率:95.65%
收藏
已结贴  问题点数:100 回复次数:41 
AVL树(迭代版本)
这并不是高效的迭代版本,原来在于使用了绝对高度,而对高度函数的两次调用让迭代获得的些许速度优势荡然无存。

目前还没想到怎么处理高度,如果你有好的建议,请提出,不胜感谢。

程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define T AVLTREE
typedef struct T *T;

struct T {
    int Element;
    T Left;
    T Right;
};

void
Insert( T *RootPP, int X ); 

void
Print( T Root );



int
main( void )
{
    T Root;
    int ix,i;

    Root = NULL;
    srand( ( unsigned )time( NULL ) );


    for( ix = 0; 20 > ix; ++ix )
        i = rand() % 1000, fprintf( stderr,"待插入的值是 %d\n", i ), Insert( &Root, i );

    Print( Root );

    return 0;
}

void
Print( T Root )
{
    if( NULL == Root )
        return;


    Print( Root->Left );
    printf( "%5d ", Root->Element );
    Print( Root->Right );
}


int
Heigh( T Root );

T
SingleRotateWithLeft( T Node );
T
SingleRotateWithRight( T Node );
T
DoubleRotateWithLeft( T Node );
T
DoubleRotateWithRight( T Node );


void
Insert( T *RootPP, int X )
{
    T New;
    T Next;
    T *This;
    int L_Heigh, R_Heigh;

    This = RootPP;

    while( NULL != ( Next = *This ) ) 
    {
        if( X > Next->Element )

            This = &Next->Right;
        else if( X < Next->Element )

            This = &Next->Left;
        else
            return;
    }


    New = ( T )malloc( sizeof( struct T ) );
    if( NULL == New )
        exit( EXIT_FAILURE );
    New->Element = X;
    New->Left = NULL;
    New->Right = NULL;
    *This = New;
    printf( "\n\n" );


    while( NULL != *RootPP ) 
    {

        L_Heigh = Heigh( (*RootPP)->Left );
        R_Heigh = Heigh( (*RootPP)->Right);
        printf( "左子树高度 = %d, 右子树高度 = %d\n", L_Heigh, R_Heigh );

        if( X > (*RootPP)->Element )
        {
            if( 2 <= R_Heigh - L_Heigh )
            {
                if( X > (*RootPP)->Right->Element )
                    fprintf( stderr,"越界点:1\n" ), *RootPP = SingleRotateWithRight( *RootPP );
                else
                    fprintf( stderr,"越界点:2\n" ), *RootPP = DoubleRotateWithRight( *RootPP );
                continue;
            }

            RootPP = &(*RootPP)->Right;
        }
        else if( X < (*RootPP)->Element )
        {

            if( 2 <= L_Heigh - R_Heigh )
            {
                if(  X < (*RootPP)->Left->Element )
                    fprintf( stderr,"越界点:3\n" ), *RootPP = SingleRotateWithLeft( *RootPP );                                
                else
                    fprintf( stderr,"越界点:4\n" ), *RootPP = DoubleRotateWithLeft( *RootPP );
                continue;
            }

            RootPP = &(*RootPP)->Left;
        }
        else
            return;
    }



}    


int
Heigh( T Root )
{
    int u, v;

    if( NULL == Root )
        return -1;

    u = Heigh( Root->Left );
    v = Heigh( Root->Right );

    if( u > v )
        return u + 1;
    else
        return v + 1;
}


T
SingleRotateWithLeft( T Node )
{
    T Temp;

    Temp = Node->Left;
    Node->Left = Temp->Right;
    Temp->Right = Node;

    return Temp;
    
}


T
SingleRotateWithRight( T Node )
{
    T Temp;

    Temp = Node->Right;
    Node->Right = Temp->Left;
    Temp->Left = Node;

    return Temp;
}


T
DoubleRotateWithLeft( T Node )
{
/*    Node->Left = SingleRotateWithRight( Node->Left );
    return SingleRotateWithLeft( Node );
*/
    T K1, K2;

    K1 = Node->Left;
    K2 = K1->Right;

    K1->Right = K2->Left;
    Node->Left = K2->Right;
    K2->Left = K1;
    K2->Right = Node;

    return K2;
}


T
DoubleRotateWithRight( T K1 )
{
/*    Node->Right = SingleRotateWithLeft( Node->Right );
    return SingleRotateWithRight( Node ); 
*/

    T K2, K3;

    K3 = K1->Right;
    K2 = K3->Left;

    K1->Right = K2->Left;
    K3->Left = K2->Right;
    K2->Left = K1;
    K2->Right = K3;

    return K2;

    
}


[此贴子已经被作者于2017-6-12 18:10编辑过]

搜索更多相关主题的帖子: color 
2017-06-12 06:30
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:50 
哇~很简单的AVL树呀~打算下一个目标是看看红黑树~看来实现这短期目标可能性不太大~还是先弄弄删除节点的操作吧~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-06-12 06:37
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
这种方法效率插入较低~我第一次发AVL树那代码求高度方法类似这样~每次插入都要要遍历高度这样会严重影响效率~虽然我第二次发的高度那里有点偏差~但是求高度的时间可以理解为o(1)~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-06-12 06:40
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
找到原因了~看看是不是这样~还是AVL树旋转理解不太透彻~singlerotatewithleft对doulberotatewithright这里匹配出问题了~另一半旋转也是这样~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-06-12 06:57
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 4楼 九转星河
如果可以你修改一下旋转哪里,然后编译看看。我现在在上班,没办法修改调试。


另外高度问题,跌代版本比预料中的要复杂很多,这就是我一直没想到办法解决的问题。所以不得不求输的绝对高度。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-06-12 07:28
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:50 
扑通

DO IT YOURSELF !
2017-06-12 07:51
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 5楼 renkejun1942
刚刚调试过了~改了旋转那那里还是这样~还要再认真看看才行~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-06-12 09:03
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 6楼 wp231957
W版主如此大礼,小弟怎么承受的起?

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-06-12 10:33
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 7楼 九转星河
我反复看了几次旋转,应该不是那里的问题。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-06-12 10:34
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 9楼 renkejun1942
感觉要大改才行~迭代遍历这样会出问题的~

因为逻辑顺序出问题了~
是先插入节点然后在回溯的时候调节平衡~

你这个是先调节平衡再插入节点这样会出问题的~

你下一次插入的数据和上一次插入的数据不一定相等~怎么会拿下一次插入的数据来对上一次的平衡作为比较?~~

不用递归的话还是乖乖地用栈来实现吧~

[此贴子已经被作者于2017-6-12 11:14编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-06-12 11:13
快速回复:AVL树(迭代版本)
数据加载中...
 
   



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

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