• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            那誰的技術(shù)博客

            感興趣領(lǐng)域:高性能服務(wù)器編程,存儲(chǔ),算法,Linux內(nèi)核
            隨筆 - 210, 文章 - 0, 評(píng)論 - 1183, 引用 - 0
            數(shù)據(jù)加載中……

            AVL樹的實(shí)現(xiàn)代碼

            /********************************************************************
            created:    
            2007/08/28
            filename:     avltree.c
            author:        Lichuang

            purpose:    AVL樹的實(shí)現(xiàn)代碼, 
                        參考資料
            <<數(shù)據(jù)結(jié)構(gòu)與算法分析-C語言描述>>, 作者Allen Weiss
            *********************************************************************/

            #include 
            <stdio.h>
            #include 
            <stdlib.h>
            #include 
            <time.h>

            typedef struct AVLTree
            {
                
            int nData;
                struct AVLTree
            * pLeft;
                struct AVLTree
            * pRight;
                
            int nHeight;
            }AVLTree;

            int Max(int a, int b);
            int Height(AVLTree* pNode);
            AVLTree
            * Insert(int nData, AVLTree* pNode);
            AVLTree
            * SingleRotateWithLeft(AVLTree* pNode);
            AVLTree
            * SingleRotateWithRight(AVLTree* pNode);
            AVLTree
            * DoubleRotateWithLeft(AVLTree* pNode);
            AVLTree
            * DoubleRotateWithRight(AVLTree* pNode);
            void DeleteTree(AVLTree
            ** ppRoot);
            void PrintTree(AVLTree
            * pRoot);

            int main()
            {
                
            int i;
                AVLTree
            * pRoot = NULL;

                srand((unsigned 
            int)::time(NULL));
                
                
            for (i = 0; i < 100000000++i)
                {
                    pRoot 
            = Insert(::rand(), pRoot);
                }

                
            //PrintTree(pRoot);

                DeleteTree(
            &pRoot);

                return 
            0;
            }

            int Max(int a, int b)
            {
                return (a 
            > b ? a : b);
            }

            int Height(AVLTree* pNode)
            {
                
            if (NULL == pNode)
                    return 
            -1;

                return pNode
            ->nHeight;
            }

            AVLTree
            * Insert(int nData, AVLTree* pNode)
            {
                
            if (NULL == pNode)
                {
                    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)    // AVL樹不平衡
                    {
                        
            if (nData < pNode->pLeft->nData)
                        {
                            
            // 插入到了左子樹左邊, 做單旋轉(zhuǎn)
                            pNode 
            = SingleRotateWithLeft(pNode);
                        }
                        
            else 
                        {
                            
            // 插入到了左子樹右邊, 做雙旋轉(zhuǎn)
                            pNode 
            = DoubleRotateWithLeft(pNode);
                        }
                    }
                }
                
            else if (nData > pNode->nData)          // 插入到右子樹中
                {
                    pNode
            ->pRight = Insert(nData, pNode->pRight);
                    
            if (Height(pNode->pRight) - Height(pNode->pLeft) == 2)    // AVL樹不平衡
                    {
                        
            if (nData > pNode->pRight->nData)
                        {
                            
            // 插入到了右子樹右邊, 做單旋轉(zhuǎn)
                            pNode 
            = SingleRotateWithRight(pNode);
                        }
                        
            else 
                        {
                            
            // 插入到了右子樹左邊, 做雙旋轉(zhuǎn)
                            pNode 
            = DoubleRotateWithRight(pNode);
                        }
                    }
                }

                pNode
            ->nHeight = Max(Height(pNode->pLeft), Height(pNode->pRight)) + 1;

                return pNode;
            }

            /********************************************************************
                  pNode                                pNode
            ->pLeft 
                  
            /                                             \
            pNode
            ->pLeft                      ==>              pNode
                       
            \                                       /
                      pNode
            ->pLeft->pRight                   pNode->pLeft->pRight
            *********************************************************************/
            AVLTree
            * SingleRotateWithLeft(AVLTree* pNode)
            {
                AVLTree
            * pNode1;

                pNode1 
            = pNode->pLeft;
                pNode
            ->pLeft = pNode1->pRight;
                pNode1
            ->pRight = pNode;

                
            // 結(jié)點(diǎn)的位置變了, 要更新結(jié)點(diǎn)的高度值
                pNode
            ->nHeight = Max(Height(pNode->pLeft), Height(pNode->pRight)) + 1;
                pNode1
            ->nHeight = Max(Height(pNode1->pLeft), pNode->nHeight) + 1;

                return pNode1;
            }

            /********************************************************************
            pNode                                   pNode
            ->pRight
                 
            \                                  /
                 pNode
            ->pRight           ==>    pNode 
                 
            /                                   \
            pNode
            ->pRight->pLeft                     pNode->pRight->pLeft
            *********************************************************************/
            AVLTree
            * SingleRotateWithRight(AVLTree* pNode)
            {
                AVLTree
            * pNode1;

                pNode1 
            = pNode->pRight;
                pNode
            ->pRight = pNode1->pLeft;
                pNode1
            ->pLeft = pNode;

                
            // 結(jié)點(diǎn)的位置變了, 要更新結(jié)點(diǎn)的高度值
                pNode
            ->nHeight = Max(Height(pNode->pLeft), Height(pNode->pRight)) + 1;
                pNode1
            ->nHeight = Max(Height(pNode1->pRight), pNode->nHeight) + 1;

                return pNode1;
            }

            AVLTree
            * DoubleRotateWithLeft(AVLTree* pNode)
            {
                pNode
            ->pLeft = SingleRotateWithRight(pNode->pLeft);

                return SingleRotateWithLeft(pNode);
            }

            AVLTree
            * DoubleRotateWithRight(AVLTree* pNode)
            {
                pNode
            ->pRight = SingleRotateWithLeft(pNode->pRight);

                return SingleRotateWithRight(pNode);
            }

            // 后序遍歷樹以刪除樹
            void DeleteTree(AVLTree
            ** ppRoot)
            {
                
            if (NULL == ppRoot || NULL == *ppRoot)
                    return;

                DeleteTree(
            &((*ppRoot)->pLeft));
                DeleteTree(
            &((*ppRoot)->pRight));
                free(
            *ppRoot);
                
            *ppRoot = NULL;
            }

            // 中序遍歷打印樹的所有結(jié)點(diǎn), 因?yàn)樽蠼Y(jié)點(diǎn) < 父結(jié)點(diǎn) < 右結(jié)點(diǎn), 因此打印出來數(shù)據(jù)的大小是遞增的
            void PrintTree(AVLTree
            * pRoot)
            {
                
            if (NULL == pRoot)
                    return;

                static 
            int n = 0;

                PrintTree(pRoot
            ->pLeft);
                printf(
            "[%d]nData = %d\n"++n, pRoot->nData);
                PrintTree(pRoot
            ->pRight);
            }

            另外,關(guān)于AVL樹,chinaunix的win_hate有一段精彩的講述,在這個(gè)地址:
            http://bbs.chinaunix.net/viewthread.php?tid=692071

            posted on 2007-08-29 22:06 那誰 閱讀(8583) 評(píng)論(7)  編輯 收藏 引用 所屬分類: 算法與數(shù)據(jù)結(jié)構(gòu)

            評(píng)論

            # re: AVL樹的實(shí)現(xiàn)代碼  回復(fù)  更多評(píng)論   

            不能刪除單個(gè)結(jié)點(diǎn)?
            2008-03-29 21:17 | BaluWu

            # re: AVL樹的實(shí)現(xiàn)代碼  回復(fù)  更多評(píng)論   

            有刪除的實(shí)現(xiàn)部分嗎?
            http://blog.chinaunix.net/u1/53908/
            2008-06-02 14:32 | linfengfeiye

            # re: AVL樹的實(shí)現(xiàn)代碼  回復(fù)  更多評(píng)論   

            學(xué)習(xí)了!多謝!
            2008-10-23 20:09 | ashizl

            # re: AVL樹的實(shí)現(xiàn)代碼  回復(fù)  更多評(píng)論   

            for (i = 0; i < 100000000; ++i)
            {
            pRoot = Insert(::rand(), pRoot);
            }
            我是一個(gè)算法初學(xué)者,這里有的問題啊:pRoot應(yīng)該是指向新插入節(jié)點(diǎn),那么這樣的話,每次插入都是從新節(jié)點(diǎn)開始,而不是從根節(jié)點(diǎn)開始吧??
            2011-04-06 00:33 | 劉學(xué)金

            # re: AVL樹的實(shí)現(xiàn)代碼  回復(fù)  更多評(píng)論   

            insert之中沒有處理插入已經(jīng)存在的節(jié)點(diǎn)的情況啊!
            2012-08-06 13:39 | lz

            # re: AVL樹的實(shí)現(xiàn)代碼  回復(fù)  更多評(píng)論   

            我覺得里面有一處是有問題,請(qǐng)您看看是不是,在執(zhí)行插入之后,那個(gè)節(jié)點(diǎn)的高度是0才對(duì),但是在下面執(zhí)行的時(shí)候又賦值為1了。我覺得應(yīng)該在最后插入的時(shí)候應(yīng)該有一個(gè)return,這樣葉子節(jié)點(diǎn)的高度為0.
            2013-10-27 12:17 | qq471876425

            # re: AVL樹的實(shí)現(xiàn)代碼  回復(fù)  更多評(píng)論   

            謝了
            2014-01-04 00:22 | sicily
            蜜臀av性久久久久蜜臀aⅴ麻豆| 久久精品国产精品青草app| 久久亚洲视频| 久久国产欧美日韩精品免费| 日韩美女18网站久久精品 | 日本久久久久亚洲中字幕| 久久综合亚洲欧美成人| 久久免费精品一区二区| 久久久久亚洲精品天堂久久久久久| 久久综合亚洲色一区二区三区| 久久精品蜜芽亚洲国产AV| 久久综合成人网| 久久婷婷久久一区二区三区| 狠狠色丁香久久婷婷综合图片| 国产成人久久精品一区二区三区 | 午夜精品久久久久久影视riav| 久久精品人人做人人爽电影蜜月| 久久毛片免费看一区二区三区| 精品久久久久久国产潘金莲| 九九精品久久久久久噜噜| 99久久精品无码一区二区毛片| 亚洲国产精品18久久久久久| 欧美伊人久久大香线蕉综合69| 久久精品国产亚洲沈樵| 浪潮AV色综合久久天堂| 国产精品一区二区久久精品涩爱| 国产毛片久久久久久国产毛片| 国产欧美一区二区久久| 久久亚洲精品成人av无码网站| 久久精品国产99国产精品亚洲| 久久强奷乱码老熟女网站| 精品久久久久中文字幕一区| 成人免费网站久久久| 色婷婷久久综合中文久久蜜桃av| 伊人色综合久久天天人守人婷 | 色偷偷久久一区二区三区| 天堂久久天堂AV色综合| 久久精品亚洲一区二区三区浴池| 色狠狠久久AV五月综合| 国产婷婷成人久久Av免费高清| 久久亚洲国产成人精品性色|