最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 詳解數(shù)據(jù)結(jié)構(gòu)中的搜索二叉樹

 更新時間:2022年04月15日 10:55:32   作者:m0_52012656  
搜索二叉樹是一種具有良好排序和查找性能的二叉樹數(shù)據(jù)結(jié)構(gòu),包括多種操作,本篇只介紹插入,排序(遍歷),和刪除操作,重點是刪除操作比較復(fù)雜

定義

搜索二叉樹,也稱有序二叉樹,排序二叉樹,是指一棵空樹或者具有下列性質(zhì)的二叉樹:

1、若任意節(jié)點的左子樹不空,則左子樹上的所有節(jié)點的值均小于它的根節(jié)點的值

2、若任意節(jié)點的右子樹不空,則右子樹上的所有節(jié)點的值均大于它的根節(jié)點的值

3、任意節(jié)點的左右子樹也稱為二叉查找樹。

4、沒有鍵值相等的節(jié)點。

5、搜索二叉樹中序遍歷為有序數(shù)組。

結(jié)構(gòu)代碼實現(xiàn)

template<class K>
struct BSTreeNode
{
    BSTreeNode<K>* _left;
    BSTreeNode<K>* _right;
    
    K _key;
    
    BSTreeNode(const K& key)
        :_left(left)
        ,_right(right)
        ,_key(key)
    {}
};

查找某個元素

在搜索二叉樹b中查找x的過程

  • 若樹是一個空樹,則搜索失敗,否則:
  • 若x等于b的根節(jié)點的鍵值,則查找成功;否則:
  • 若x小于b的根節(jié)點的鍵值,則搜索左子樹;否則:
  • 若x大于b的根節(jié)點的鍵值,則搜索右子樹。

非遞歸實現(xiàn)

typrdef BSTreeNode<K> Node;
?
Node* find(const K& key)
{
    Node*cur =_root;
    while(cur)
    {
        if(cur->_key<key)
            cur=cur->right;
        else if(cur->_key>key)
            cur=cur->left;
        else
            return cur;
    }
    return nullptr;
}

遞歸實現(xiàn)

typrdef BSTreeNode<K> Node;
?
Node* _findr(Node* root,const K& key)
{
    if(root==nullptr)
    {
        return nullptr;
    }
    if(root->_key<key)
    {
        return _findr(root->_right);
    }
    else if(root->_key>key)
    {
        return _findr(root->_left);
    }
    else
        return root;
    
}

構(gòu)造搜索二叉樹

  • 若樹為空樹,則直接插入;否則
  • 若插入值大于根節(jié)點的鍵值,則插入到右子樹中,以此遞歸;否則
  • 若插入值小于根節(jié)點的鍵值,則插入到左子樹中

非遞歸實現(xiàn):

bool insert(const K& key)
{
    if(_root==nullptr)
    {
        _root=new Node(key);
        return true;
    }
    Node* parent=nullptr;
    Node* cur=_root;
    while(cur)
    {
        if(cur->_key<key)
        {
            parent=cur;
            cur=cur->_right;
        }
        else if(cur->_key>key)
        {
            parent=cur;
            cur=cur->_left;
        }
        else
            return false;
    }
    cur=new Node(key);
    if(parent->_key<key)
    {
        parent->_right=cur;
    }
    else
        parent->_left=cur;
    return true;
}

遞歸實現(xiàn):

bool _insertR(Node* &root,const K&key)
{
    if(root==NULL)
    {
        root=new Node(key);
        return true;
    }
    if(root->_key<key)
        return _insertR(root->_right,key);
    else if(root->_key>key)
        return _insertR(root->_left,key);
    else
        return false;
}

往搜索二叉樹中插入元素

向一個二叉搜索樹b中插入一個節(jié)點s的算法,過程為:

  • 若b是空樹,則將s所指結(jié)點作為根節(jié)點插入,否則:
  • 若s->data等于b的根節(jié)點的數(shù)據(jù)域之值,則返回,否則:
  • 若s->data小于b的根節(jié)點的數(shù)據(jù)域之值,則把s所指節(jié)點插入到左子樹中,否則:
  • 把s所指節(jié)點插入到右子樹中。(新插入節(jié)點總是葉子節(jié)點)

搜索二叉樹刪除節(jié)點

重難點

二叉搜索樹的結(jié)點刪除比插入較為復(fù)雜,總體來說,結(jié)點的刪除可歸結(jié)為三種情況:

  • 如果結(jié)點z沒有孩子節(jié)點,那么只需簡單地將其刪除,并修改父節(jié)點,用NULL來替換z;
  • 如果結(jié)點z只有一個孩子,那么將這個孩子節(jié)點提升到z的位置,并修改z的父節(jié)點,用z的孩子替換z;
  • 如果結(jié)點z有2個孩子,那么查找z的后繼y,此外后繼一定在z的右子樹中,然后讓y替換z

非遞歸實現(xiàn)

bool Erase(const K& key)
{
    Node* parent=nullptr;
    Node* cur=_root;
    while(cur)
    {
        if(cur->_key<key)
        {
            parent=cur;
            cur=cur->_right;
        }
        else if(cur->_key>key)
        {
            parent=cur;
            cur=cur->left;
        }
        else
        {
            //找到了,開始刪除
            if(cur->_left==nullptr)
            {
                if(cur==_root)
                {
                    _root=cur->_right;
                }
                else
                {
                    if(parent->_left==cur)
                    {
                        parent->_left=cur->_right;
                    }
                    else
                    {
                        parent->_right=cur->_right;
                    }
                }
                delete cur;
            }
            else if(cur->_right==nullptr)
            {
                if(cur==_root)
                {
                    _root=cur->_left;
                }
                else
                {
                    if(parent->_left==cur)
                    {
                        parent->_left=cur->_left;
                    }
                    else
                    {
                        parent->_right=cur->_right;
                    }
                }
            }
            else   //左右都不為空
            {
                Node* minRight=cur->_right;
                while(minRight->_left)
                {
                    minRight=minRight->_left;
                }
                k min = minRight->_key;
                this->Erase(min);
                
                cur->_key=min;
            }
            return true;
        }
    }
    return false;
}

遞歸實現(xiàn)

// 如果樹中不存在key,返回false
// 存在,刪除后,返回true
bool _EraseR(Node*& root, const K& key)
{
    if(root==nullptr)
        return false;
    if(root->_key<key)
        return _EraseR(root->_right,key);
    else if(root->_key>key)
        return _EraseR(root->_left,key);
    else
    {
        //找到了,root就是要刪除的節(jié)點
        if(root->_left == nullptr)
        {
            Node* del=root;
            root=root->_right;
            delete del;
        }
        else if(root->_right==nullptr)
        {
            Node* del = root;
            root=root->_left;
            delete del;
        }
        else
        {
            Node* minRight=root->_right;
            while(minRight->_left)
            {
                minRight=minRight->_left;
            }
            K min=minRight->_key;
            
            //轉(zhuǎn)化為root的右子樹刪除min
            _EraseR(root->_right,min);
            root->_key=min;
            
        }
        return true;
    }
}

到此這篇關(guān)于C++ 詳解數(shù)據(jù)結(jié)構(gòu)中的搜索二叉樹的文章就介紹到這了,更多相關(guān)C++ 搜索二叉樹內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實現(xiàn)控制臺掃雷小游戲

    C語言實現(xiàn)控制臺掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)控制臺掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C語言指針學(xué)習(xí)經(jīng)驗總結(jié)淺談

    C語言指針學(xué)習(xí)經(jīng)驗總結(jié)淺談

    指針是C語言的難點和重點,但指針也是C語言的靈魂 。
    2013-03-03
  • C++11新特性之四種類型轉(zhuǎn)換cast說明

    C++11新特性之四種類型轉(zhuǎn)換cast說明

    類型轉(zhuǎn)換是項目中常使用的一種語法規(guī)則,幾乎每個編程語言都不可避免的涉及到這方面,下面這篇文章主要給大家介紹了關(guān)于C++11新特性之四種類型轉(zhuǎn)換cast說明的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • C語言strlen和sizeof在數(shù)組中的使用詳解

    C語言strlen和sizeof在數(shù)組中的使用詳解

    對于 strlen 和 sizeof,相信不少程序員會混淆其功能。雖然從表面上看它們都可以求字符串的長度,但二者卻存在著許多不同之處及本質(zhì)區(qū)別
    2021-10-10
  • C/C++?Qt?數(shù)據(jù)庫QSql增刪改查組件應(yīng)用教程

    C/C++?Qt?數(shù)據(jù)庫QSql增刪改查組件應(yīng)用教程

    Qt?SQL模塊是Qt中用來操作數(shù)據(jù)庫的類,該類封裝了各種SQL數(shù)據(jù)庫接口,可以很方便的鏈接并使用。本文主要介紹了Qt數(shù)據(jù)庫QSql增刪改查組件的應(yīng)用教程,感興趣的同學(xué)可以學(xué)習(xí)一下
    2021-12-12
  • C語言驅(qū)動開發(fā)之通過ReadFile與內(nèi)核層通信

    C語言驅(qū)動開發(fā)之通過ReadFile與內(nèi)核層通信

    驅(qū)動與應(yīng)用程序的通信是非常有必要的,內(nèi)核中執(zhí)行代碼后需要將其動態(tài)顯示給應(yīng)用層。為了實現(xiàn)內(nèi)核與應(yīng)用層數(shù)據(jù)交互則必須有通信的方法,微軟為我們提供了三種通信方式,本文先來介紹通過ReadFile系列函數(shù)實現(xiàn)的通信模式
    2022-09-09
  • C++實現(xiàn)掃雷程序開發(fā)

    C++實現(xiàn)掃雷程序開發(fā)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)掃雷程序開發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C語言驅(qū)動開發(fā)之內(nèi)核通過PEB獲取進(jìn)程參數(shù)

    C語言驅(qū)動開發(fā)之內(nèi)核通過PEB獲取進(jìn)程參數(shù)

    PEB結(jié)構(gòu)(Process Envirorment Block Structure)其中文名是進(jìn)程環(huán)境塊信息。本文將通過PEB實現(xiàn)獲取進(jìn)程參數(shù),感興趣的小伙伴可以了解一下
    2022-10-10
  • C語言制作貪吃蛇小游戲

    C語言制作貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了C語言制作貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • C語言的結(jié)構(gòu)體你了解嗎

    C語言的結(jié)構(gòu)體你了解嗎

    這篇文章主要為大家詳細(xì)介紹了C語言的結(jié)構(gòu)體,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02

最新評論

金川县| 峨山| 洪湖市| 开封市| 油尖旺区| 黎城县| 饶河县| 新竹县| 肃南| 上犹县| 雷山县| 秦皇岛市| 岳普湖县| 江源县| 石楼县| 伊宁县| 库伦旗| 兴业县| 寿光市| 吉安市| 山西省| 施甸县| 河北区| 新巴尔虎左旗| 吐鲁番市| 白朗县| 凤山县| 睢宁县| 西盟| 绥阳县| 冕宁县| 宁蒗| 华容县| 青冈县| 乳源| 大冶市| 莫力| 龙州县| 新绛县| 潮安县| 黄冈市|