• <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>

            那誰(shuí)的技術(shù)博客

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

            二叉查找樹(shù)的解析與實(shí)現(xiàn)

            二叉查找樹(shù)是二叉樹(shù)的一個(gè)特化,它具有的特殊性質(zhì)是:對(duì)于樹(shù)中的任何一個(gè)結(jié)點(diǎn),它的左子樹(shù)的所有結(jié)點(diǎn)的關(guān)鍵字都小于此結(jié)點(diǎn)的關(guān)鍵字,而右子樹(shù)的所有結(jié)點(diǎn)的關(guān)鍵字都大于此結(jié)點(diǎn)的關(guān)鍵字.

            二叉查找樹(shù)的這種特殊性質(zhì)使得它在查找元素的時(shí)候特別的方便,每一次查找都可以去掉一半的元素,因此查找的時(shí)間是O(logN).

            二叉查找樹(shù)的插入和查找算法也是很簡(jiǎn)單的,就是與當(dāng)前結(jié)點(diǎn)的關(guān)鍵字作比較決定在右邊還是左邊繼續(xù)操作.

            二叉查找樹(shù)最復(fù)雜的算法就是刪除結(jié)點(diǎn)的算法了,根據(jù)所要?jiǎng)h除的結(jié)點(diǎn)有兩個(gè)子結(jié)點(diǎn)還是只有一個(gè)或者沒(méi)有子結(jié)點(diǎn)會(huì)有不同的處理.有兩個(gè)子結(jié)點(diǎn)的情況一般的處理是找到右子樹(shù)中值最小的一個(gè)結(jié)點(diǎn),將它的值替代當(dāng)前的結(jié)點(diǎn)值,然后再把這個(gè)值最小的結(jié)點(diǎn)刪除,也就是說(shuō)有兩個(gè)子結(jié)點(diǎn)的情況是用最小的一個(gè)大于當(dāng)前結(jié)點(diǎn)關(guān)鍵字的結(jié)點(diǎn)替代了當(dāng)前的結(jié)點(diǎn)(很拗口,但愿我說(shuō)清楚了:)在只有一個(gè)或者沒(méi)有子結(jié)點(diǎn)的情況就比較的簡(jiǎn)單了,如果還有子結(jié)點(diǎn)就把子結(jié)點(diǎn)的位置往上挪,然后把當(dāng)前結(jié)點(diǎn)刪除.

            實(shí)現(xiàn)如下:
            1)BSTree.h
            /********************************************************************
            ????created:????2006/07/28
            ????filename:?????BSTree.h
            ????author:????????李創(chuàng)
            ????????????????
            http://www.shnenglu.com/converse/

            ????purpose:????二叉查找樹(shù)的實(shí)現(xiàn)代碼
            ********************************************************************
            */


            #ifndef?BINARY_SEARCH_TREE_H
            #define?BINARY_SEARCH_TREE_H

            #include?
            <stdio.h>

            template
            <typename?T>
            struct?BTreeNode
            {
            ????T????Data;
            ????BTreeNode
            *?pLeft;
            ????BTreeNode
            *?pRight;
            ????BTreeNode
            *?pParent;

            ????BTreeNode(????T?data?
            =?T(),?BTreeNode<T>*?Parent?=?NULL,?
            ????????????????BTreeNode
            <T>*?Left?=?NULL,?BTreeNode<T>*?Right?=?NULL)
            ????????????????:?Data(data),?pLeft(Left),?pRight(Right),?pParent(Parent)
            ????
            {
            ????}

            }
            ;

            template
            <typename?T>
            class?BSTree
            {
            protected:
            ????BTreeNode
            <T>*????m_pRootNode;

            public:
            ????BSTree(BTreeNode
            <T>*?pRoot?=?NULL)?
            ????????:?m_pRootNode(pRoot)
            ????
            {
            ????}

            ????
            ~BSTree();

            ????
            void????????????Display();
            ????BTreeNode
            <T>*????Insert(const?T&?data);
            ????BTreeNode
            <T>*????Find(const?T&?data);
            ????BTreeNode
            <T>*????FindMin();
            ????BTreeNode
            <T>*????FindMax();
            ????BTreeNode
            <T>*????Delete(const?T&?data);

            private:
            ????
            void????????????Display(BTreeNode<T>*?p);
            ????BTreeNode
            <T>*????Insert(const?T&?data,?BTreeNode<T>*?p);
            ????BTreeNode
            <T>*????Find(const?T&?data,?BTreeNode<T>*?p);
            ????BTreeNode
            <T>*????FindMin(BTreeNode<T>*?p);
            ????BTreeNode
            <T>*????FindMax(BTreeNode<T>*?p);
            ????BTreeNode
            <T>*????Delete(const?T&?data,?BTreeNode<T>*?p);

            ????
            void????????????DestructImpl(BTreeNode<T>*?p);
            }
            ;

            #endif

            2)BSTree.cpp
            /********************************************************************
            ????created:????2006/07/28
            ????filename:?????BSTree.cpp
            ????author:????????李創(chuàng)
            ????????????????
            http://www.shnenglu.com/converse/

            ????purpose:????二叉查找樹(shù)的實(shí)現(xiàn)代碼
            ********************************************************************
            */


            #include?
            <iostream>
            #include?
            "BSTree.h"

            template
            <typename?T>
            BSTree
            <T>::~BSTree()
            {
            ????DestructImpl(m_pRootNode);
            }


            template
            <typename?T>
            void?BSTree<T>::DestructImpl(BTreeNode<T>*?p)
            {
            ????
            if?(NULL?==?p)
            ????????
            return;

            ????DestructImpl(p
            ->pLeft);
            ????DestructImpl(p
            ->pRight);
            ????p
            ->pLeft?=?NULL;
            ????p
            ->pRight?=?NULL;
            ????p
            ->pParent?=?NULL;
            ????delete?p;
            ????p?
            =?NULL;
            }


            template
            <typename?T>
            void?BSTree<T>::Display()
            {
            ????Display(m_pRootNode);
            }


            //?中序打印出樹(shù)中的元素,這樣應(yīng)該是從小到大的順序
            template<typename?T>
            void?BSTree<T>::Display(BTreeNode<T>*?p)
            {
            ????
            if?(NULL?==?p)
            ????????
            return;

            ????Display(p
            ->pLeft);
            ????std::cout?
            <<?"Node?=?"?<<?p->Data?<<?std::endl;
            ????Display(p
            ->pRight);
            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::Insert(const?T&?data)
            {
            ????
            return?Insert(data,?m_pRootNode);
            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::Insert(const?T&?data,?BTreeNode<T>*?p)
            {
            ????
            if?(NULL?==?p)
            ????
            {
            ????????p?
            =?new?BTreeNode<T>(data);

            ????????
            if?(NULL?==?p)
            ????????
            {
            ????????????
            return?NULL;
            ????????}

            ????????
            else?if?(NULL?==?m_pRootNode)
            ????????
            {
            ????????????m_pRootNode?
            =?p;
            ????????}

            ????}

            ????
            else?if?(data?>?p->Data)
            ????
            {
            ????????p
            ->pRight?=?Insert(data,?p->pRight);
            ????????
            if?(NULL?!=?p->pRight)
            ????????
            {
            ????????????p
            ->pRight->pParent?=?p;
            ????????}

            ????}

            ????
            else
            ????
            {
            ????????p
            ->pLeft?=?Insert(data,?p->pLeft);
            ????????
            if?(NULL?!=?p->pLeft)
            ????????
            {
            ????????????p
            ->pLeft->pParent?=?p;
            ????????}

            ????}


            ????
            return?p;
            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::Find(const?T&?data)
            {
            ????
            return?Find(data,?m_pRootNode);
            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::Find(const?T&?data,?BTreeNode<T>*?p)
            {
            ????
            if?(NULL?==?p)
            ????
            {
            ????????
            return?NULL;
            ????}

            ????
            else
            ????
            {
            ????????
            if?(data?==?p->Data)
            ????????
            {
            ????????????
            return?p;
            ????????}

            ????????
            else?if?(data?>?p->Data)
            ????????
            {
            ????????????
            return?Find(data,?p->pRight);
            ????????}

            ????????
            else
            ????????
            {
            ????????????
            return?Find(data,?p->pLeft);
            ????????}

            ????}

            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::FindMin()
            {
            ????
            return?FindMin(m_pRootNode);
            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::FindMin(BTreeNode<T>*?p)
            {
            ????
            if?(NULL?==?p)
            ????
            {
            ????????
            return?NULL;
            ????}


            ????
            if?(NULL?!=?p->pLeft)
            ????
            {
            ????????
            return?FindMin(p->pLeft);
            ????}

            ????
            else
            ????
            {
            ????????
            return?p;
            ????}

            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::FindMax()
            {
            ????
            return?FindMax(m_pRootNode);
            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::FindMax(BTreeNode<T>*?p)
            {
            ????
            if?(NULL?==?p)
            ????
            {
            ????????
            return?NULL;
            ????}


            ????
            if?(NULL?!=?p->pRight)
            ????
            {
            ????????
            return?FindMax(p->pRight);
            ????}

            ????
            else
            ????
            {
            ????????
            return?p;
            ????}

            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::Delete(const?T&?data)
            {
            ????
            return?Delete(data,?m_pRootNode);
            }


            template
            <typename?T>
            BTreeNode
            <T>*?BSTree<T>::Delete(const?T&?data,?BTreeNode<T>*?p)
            {
            ????
            if?(NULL?==?p)
            ????
            {
            ????????
            return?NULL;
            ????}

            ????
            else?if?(data?<?p->Data)
            ????
            {
            ????????p
            ->pLeft?=?Delete(data,?p->pLeft);
            ????}

            ????
            else?if?(data?>?p->Data)
            ????
            {
            ????????p
            ->pRight?=?Delete(data,?p->pRight);
            ????}

            ????
            else?if?(NULL?!=?p->pLeft?&&?NULL?!=?p->pRight)
            ????
            {
            ????????
            //?找到結(jié)點(diǎn)且有兩個(gè)子結(jié)點(diǎn)
            ????????BTreeNode<T>*?pNode;
            ????????
            //?找到右子樹(shù)中最小的結(jié)點(diǎn),把它的值替換當(dāng)前結(jié)點(diǎn)值,然后刪除找到的那個(gè)結(jié)點(diǎn)
            ????????pNode?=?FindMin(p->pRight);
            ????????p
            ->Data?=?pNode->Data;
            ????????p
            ->pRight?=?Delete(p->Data,?p->pRight);
            ????}

            ????
            else
            ????
            {
            ????????
            //?找到結(jié)點(diǎn)但是只有一個(gè)或沒(méi)有子結(jié)點(diǎn)
            ????????
            //?如果有子結(jié)點(diǎn)就用子結(jié)點(diǎn)代替當(dāng)前結(jié)點(diǎn),然后刪除當(dāng)前結(jié)點(diǎn)
            ????????BTreeNode<T>*?pNode?=?p;
            ????????
            if?(NULL?==?p->pLeft)
            ????????
            {
            ????????????p?
            =?p->pRight;
            ????????}

            ????????
            else?if?(NULL?==?p->pRight)
            ????????
            {
            ????????????p?
            =?p->pLeft;
            ????????}

            ????????delete?pNode;
            ????????pNode?
            =?NULL;
            ????}


            ????
            return?p;
            }



            3)Main.cpp
            #include?"BSTree.h"
            #include?
            <stdlib.h>
            #include?
            <time.h>

            //?創(chuàng)建一個(gè)數(shù)組,元素值隨機(jī)設(shè)置
            void?CreateNewArray(int?array[],?int?length)
            {
            ????
            for?(int?i?=?0;?i?<?length;?i++)
            ????
            {
            ????????array[i]?
            =?rand()?%?256;
            ????}

            }


            int?main()
            {
            ????
            int?array[10];
            ????srand(time(NULL));

            ????CreateNewArray(array,?
            10);
            ????BSTree
            <int>?tree;
            ????
            for?(int?i?=?0;?i?<?10;?++i)
            ????
            {
            ????????tree.Insert(array[i]);
            ????}

            ????tree.Display();
            ????
            if?(NULL?!=?tree.Find(array[7]))
            ????
            {
            ????????std::cout?
            <<?"Find!\n";
            ????}


            ????BTreeNode
            <int>*?pNode;

            ????
            if?(NULL?!=?(pNode?=?tree.FindMin()))
            ????
            {
            ????????std::cout?
            <<?"Min?=?"?<<?pNode->Data?<<?std::endl;
            ????}


            ????
            if?(NULL?!=?(pNode?=?tree.FindMax()))
            ????
            {
            ????????std::cout?
            <<?"Max?=?"?<<?pNode->Data?<<?std::endl;
            ????}


            ????tree.Delete(array[
            7]);
            ????std::cout?
            <<?"\nafter?delete?"?<<?array[7]?<<?std::endl;
            ????tree.Display();

            ????system(
            "pause");
            ????
            return?0;
            }

            需要說(shuō)明一點(diǎn):上面做測(cè)試用的Main.cpp如果單獨(dú)寫(xiě)在一個(gè)文件中就會(huì)在鏈接的時(shí)候報(bào)錯(cuò),報(bào)的錯(cuò)誤是:
            BSTree error LNK2019: unresolved external symbol "public: struct BTreeNode<int> * __thiscall BSTree<int>::Insert(int const &)" (?Insert@?$BSTree@H@@QAEPAU?$BTreeNode@H@@ABH@Z) referenced in function _main
            BSTree error LNK2019: unresolved external symbol "public: __thiscall BSTree<int>::~BSTree<int>(void)" (??1?$BSTree@H@@QAE@XZ) referenced in function _main
            BSTree error LNK2019: unresolved external symbol "public: struct BTreeNode<int> * __thiscall BSTree<int>::Delete(int const &)" (?Delete@?$BSTree@H@@QAEPAU?$BTreeNode@H@@ABH@Z) referenced in function _main
            BSTree error LNK2019: unresolved external symbol "public: struct BTreeNode<int> * __thiscall BSTree<int>::FindMax(void)" (?FindMax@?$BSTree@H@@QAEPAU?$BTreeNode@H@@XZ) referenced in function _main
            BSTree error LNK2019: unresolved external symbol "public: struct BTreeNode<int> * __thiscall BSTree<int>::FindMin(void)" (?FindMin@?$BSTree@H@@QAEPAU?$BTreeNode@H@@XZ) referenced in function _main
            BSTree error LNK2019: unresolved external symbol "public: struct BTreeNode<int> * __thiscall BSTree<int>::Find(int const &)" (?Find@?$BSTree@H@@QAEPAU?$BTreeNode@H@@ABH@Z) referenced in function _main
            BSTree error LNK2019: unresolved external symbol "public: void __thiscall BSTree<int>::Display(void)" (?Display@?$BSTree@H@@QAEXXZ) referenced in function _main

            所以沒(méi)有辦法,我只能將main.cpp中的內(nèi)容copy到BSTree.cpp中才能鏈接過(guò)去.

            如果哪位朋友知道如何解決上面因?yàn)椴捎昧四0孱?lèi)出現(xiàn)的鏈接錯(cuò)誤,我不勝感激,謝謝!

            posted on 2006-07-29 00:33 那誰(shuí) 閱讀(6716) 評(píng)論(2)  編輯 收藏 引用 所屬分類(lèi): 算法與數(shù)據(jù)結(jié)構(gòu)

            評(píng)論

            # re: 二叉查找樹(shù)的解析與實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

            實(shí)際上,模板的實(shí)現(xiàn)應(yīng)該和它的聲明都放在頭文件中,這樣就可以將main.cpp單獨(dú)實(shí)現(xiàn)出來(lái)了。
            目前標(biāo)準(zhǔn)cpp中有一個(gè)關(guān)鍵字export可以讓模板的實(shí)現(xiàn)和聲明分開(kāi)在頭文件和.cpp文件中,但是目前只有一個(gè)編譯器實(shí)現(xiàn)了改功能(據(jù)我所知),而且即使分開(kāi)了來(lái)實(shí)現(xiàn),模板的.cpp實(shí)現(xiàn)也是必須要客戶(hù)端可見(jiàn)的(這和普通的.cpp文件那種將具體實(shí)現(xiàn)屏蔽的特性不一樣),而且export關(guān)鍵字引入給cpp帶來(lái)了很多麻煩的事情,大家目前對(duì)如何使用export也沒(méi)有什么經(jīng)驗(yàn)。
            2006-08-27 14:58 | wb

            # re: 二叉查找樹(shù)的解析與實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

            我覺(jué)得你的display函數(shù),中的<<操作符應(yīng)重載后再使用,既然使用了模板,就有可能會(huì)出現(xiàn)<<并不支持的類(lèi)型。
            2008-03-25 23:13 | cndx100
            精品久久久久久亚洲精品| 亚洲国产精品无码久久久秋霞2 | 中文精品99久久国产| 热99RE久久精品这里都是精品免费| 无码八A片人妻少妇久久| 色综合久久综合中文综合网| 日本精品久久久久中文字幕| 久久久久亚洲av成人无码电影| 国产成人精品综合久久久| 9久久9久久精品| 久久国产欧美日韩精品免费| 久久精品夜色噜噜亚洲A∨ | 久久久久久九九99精品| 97精品伊人久久久大香线蕉| 无码国内精品久久综合88| 久久国产综合精品五月天| 久久久精品2019免费观看| 久久无码国产| 91久久精品国产免费直播| 亚洲AV日韩精品久久久久| 欧美激情精品久久久久久| 国产福利电影一区二区三区久久老子无码午夜伦不| 欧美激情精品久久久久久久 | 精品久久国产一区二区三区香蕉 | 99精品伊人久久久大香线蕉| 久久亚洲精品中文字幕| 欧美精品国产综合久久| 久久综合五月丁香久久激情| 久久国产精品-国产精品| 久久影院综合精品| 久久无码人妻一区二区三区| 久久久久久久久久久精品尤物| 亚洲欧美久久久久9999| 久久综合色之久久综合| 久久久99精品成人片中文字幕 | 国产高清美女一级a毛片久久w | 热re99久久6国产精品免费| 97精品伊人久久大香线蕉| 久久亚洲国产最新网站| 久久青青色综合| 中文字幕久久久久人妻|