日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

真c++ 从二叉树到红黑树(3)之二叉搜索树BST

發布時間:2023/12/8 c/c++ 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 真c++ 从二叉树到红黑树(3)之二叉搜索树BST 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??此文章為從二叉樹到紅黑樹系列文章的第三節,主要介紹介紹二叉搜索樹BST,為AVL和RedBlack打下基礎


文章目錄

  • 一、前面文章鏈接~(點擊右邊波浪線可以返回目錄)
  • 二、二叉搜索樹BST的定義~
  • 三、二叉搜索樹類~
    • (一)定義變量和接口~
      • 1.需要的變量~
      • 2.需要的接口~
      • 3.重要輔助函數~
      • 4.BST.h~
    • (二)查找search~
      • 1._hot節點的作用~
      • 2.查找遞歸版~
      • 3.查找迭代版~
      • 4.search復雜度分析~
    • (三)插入insert~
      • 1.插入代碼~
      • 2.插入示例(動圖演示!)~
      • 3.insert復雜度分析~
    • (四)刪除remove~
      • 1.最重要的刪除函數(動圖演示!)~
        • (1)該節點沒有子樹~
        • (2)該節點只有一顆子樹~
          • a.只有左子樹~
          • b.只有右子樹~
        • (3)該節點有兩顆子樹~
          • a.右孩子就是該節點的直接后繼~
          • b.該節點的直接后繼在右孩子的左子樹中~
        • (4)刪除靜態函數代碼~
      • 2.BST的刪除代碼~
      • 3.remove復雜度分析~
    • (五)完整BST.h~
  • 四、BST測試代碼~
  • 五、BST的缺點~
  • 五、后序文章鏈接~

一、前面文章鏈接~(點擊右邊波浪線可以返回目錄)

??在閱讀本文前,強烈建議你看下前面的文章的目錄、前言以及基本介紹,否則你無法理解后面的內容。鏈接如下:

  • 基本二叉樹節點,通用函數 二叉樹節點
  • 基本二叉樹類的定義和實現 二叉樹基類


  • 二、二叉搜索樹BST的定義~

    ??確認一顆樹的中序遍歷序列十分容易。即將樹中每一個元素都投影到底部就可以了。

    ??當一顆樹的中序遍歷序列是單調非減的時候,那么這顆樹就必為一顆BST,即二叉搜索樹。

    ??更準確一點的定義為:根節點的值大于其左子樹中任意一個節點的值,小于其右節點中任意一節點的值。其左子樹和右子樹也都滿足這個條件。

    ??二叉搜索樹,又稱二叉排序樹,二叉查找樹。

    如下圖所示



    三、二叉搜索樹類~

    ??既然二叉搜索樹屬于二叉樹的特例,故自然可以基于BinTree模板類(見此系列文章第二部分)

    ??由于BST繼承于普通二叉樹。而普通二叉樹的大部分函數和變量都是屬于public或者protected的。自然BST可以沿用這些函數和變量。

    ??并由于BST本身特殊的性質(單調非減),因此需要對某些函數進行重寫(override)。以及擴增一些新的功能。

    ??在此,為了方便性起見,我們默認BST中沒有重復的數(讀者可以自行更改search接口的判斷條件來進行擴充)。

    (一)定義變量和接口~

    1.需要的變量~

    ??_hot節點,此節點的設定至關重要,有了這個節點,就能簡化很多步驟,方便BST包括后序的AVL,RedBlack的插入和刪除。讀者看到后面的插入和刪除算法的實現的時候,自然能夠體會到這個節點的作用。

    BinNodePtr _hot;//"命中節點"的"父親"

    2.需要的接口~

    ??由于BST是繼承于BinTree的,因此,很多接口都可以沿用BinTree的接口,比如遍歷,判空,獲取當前高度等等。但依然有些接口是需要進行擴充和重寫的。

    比如:

    查找樹中有沒有這個節點search 在樹中插入一個節點insert 在樹中刪除一個節點remove

    3.重要輔助函數~

    ??對于BST本身,有了上面的查找,插入和刪除,已經可以滿足BST本身的要求了,但是對于后序的AVL和RedBlack而言,還遠遠不夠,因此在此處會引入兩個重要的輔助函數,并且我會在介紹AVL的時候,詳細說明這兩個輔助函數的作用。在介紹RedBlack的時候,也會引入一個指向AVL的鏈接。

    ??關于下面兩個函數的實現,我不會在本節進行解析,我會在AVL中再進行解析。

    3+4重構 connect34 對該節點及其父親、祖父做統一旋轉調整rotateAt

    4.BST.h~

    ??由于BST屬于二叉樹的一種,因此,可以將BST繼承自我們在第二部分定義的BinTree。

    template<typename T=int> class BST :public BinTree<T> { protected:using BinNodePtr = BinNode<T>*;protected:BinNodePtr _hot;//"命中節點"的"父親"public:BST():_hot(nullptr){}//調用構造函數時,先調用子類的,再調用父類,析構則相反virtual~ BST() = default;//由于刪除全部交給b樹模板類,所以這里不需要去額外刪除protected:BinNode<T>* connect34(//3+4重構,可以用于AVL,RedBlackBinNode<T>*, BinNode<T>*, BinNode<T>*,BinNode<T>*, BinNode<T>*, BinNode<T>*, BinNode<T>*);BinNode<T>* rotateAt(BinNode<T>* v);//對v及其父親、祖父做統一旋轉調整private:BinNode<T>*& search_R(const T& data);//查找遞歸版public:BinNode<T>*& search(const T& data);//查找//返回引用,便于插入刪除//接受者一般要加個引用接收virtual BinNode<T>* insert(const T& data)override;//插入節點virtual bool remove(const T& data);//刪除節點};//class BST

    (二)查找search~

    ??從樹根出發,逐步地縮小查找范圍,直到發現目標(成功)或縮小至空樹(失敗)。由于BST的中序遍歷是有序的,所以可以用二分查找法

    比如下方查找22和23


    ??找22時,先與根節點比較大小,其比根節點16大,則進入右子樹查找。下一次與25相比,22比25小,所以進入左子樹查找。然后與19對比,自然進入右分支,最后正好命中22這個節點。即查找成功。

    ??找23時,也會經過這樣一條道路,由于22的右子樹為空,所以查找失敗。

    1._hot節點的作用~

    ??若查找成功,則search()的返回值都將如下圖(a)所示,指向一個數值為e且真實存在的節點;
    ??若查找失敗,則返回值的數值雖然為NULL,但是它作為引用將如下圖(b)所示,指向最后一次試圖轉向的空節點。


    ??由上圖可以得知,無論查找成功或者失敗,查找的返回值都是等效地指向“命中節點”,而命中節點的父親節點就是_hot節點。有了_hot節點,對于插入和刪除,都會變得相對容易一點。

    2.查找遞歸版~

    ??眾所周知,二分查找可以寫成遞歸或者迭代形式。并且幸運的是,對于二叉樹而言,其二分查找的算法,與一般數組的查找算法相比,本質上沒有任何區別,甚至可以說比一般的二分查找算法更加簡單一點。

    ??由于遞歸算法需要不斷地調用自身,并且為了保持與非遞歸算法的接口傳入參數的一致性,所以不妨將遞歸的部分與不需要遞歸的部分分離開來。

    ??下面是主要查找函數的接口。當需要查找一個數據時,就從根節點開始,進行二分遞歸查找。并同時更新_hot節點的值,方便后續的插入和刪除。

    ??并且返回值注意為引用類型。這點對于刪除算法而言至關重要。

    template<typename T> BinNode<T>*& BST<T>::search_R(const T& data) {using mybst::search_In;return search_In(this->_root, data, _hot = nullptr); }

    下方為二分查找的遞歸算法

    //=================查找================// namespace mybst {template<typename T,typename BinNodePtr>static BinNode<T>*& search_In(BinNodePtr& current, const T& data, BinNodePtr& hot) {//必須加引用,不然地址改變的話,原地址不能改變if (!current || data == current->_data)return current;//遞歸基,當當前節點為空或者找到了對應的節點,就退出hot = current;//hot 記錄父親節點的位置return search_In((data < current->_data ? current->_lchild : current->_rchild), data, hot);//二分遞歸查找} }//namespace mybst

    3.查找迭代版~

    ??比起分開寫的遞歸算法,筆者認為迭代版的查找算法的可讀性相對更高一點,并且效率也更高一點。同樣,也要注意返回的是引用。
    ??后面在插入和查找過程中,都默認用的是迭代版算法。

    template<typename T> BinNode<T>*& BST<T>::search(const T& data) {if (!this->_root || data == this->_root->_data) {//如果根節點不為空,或者正好根節點就是要找的節點_hot = nullptr;return this->_root;}_hot = this->_root;//更新_hotwhile (true){//current的地址與_hot的孩子綁定,不能與_hot綁定。BinNodePtr& current = ((data < _hot->_data) ? _hot->_lchild : _hot->_rchild);if (!current || data == current->_data)return current;_hot = current;//更新_hot位置} }

    4.search復雜度分析~

    ??在二叉搜索樹的每一層,查找算法至多訪問一個節點,且只需常數時間,故總體所需時間應線性正比于查找路徑的長度,或最終返回節點的深度,在最壞情況下不超過全樹的高度。



    (三)插入insert~

    ??對于BST而言,無論是插入還是刪除而言,先前都必將要經過查找操作。對于在此系列定義的BST而言,里面存放的都是不可重復的數據。因此,對于插入而言,如果這個元素存在BST中,則不插入,如果在BST中不存在這個元素,就在適合的位置插入這個元素。

    ??在此,_hot節點的作用就體現出來了,如果不存在這個元素,_hot節點也必將是假設這個不存在的元素存在時的父親節點。

    1.插入代碼~

    //=================插入================// template<typename T> BinNode<T>* BST<T>::insert(const T& data) {BinNodePtr& x = search(data);//查找有無這個節點//必須用引用,這樣其才必然是_hot的孩子if (x)//若有,則返回這個節點,插入失敗return x;x = new BinNode<T>(data, _hot);//若無,則新建一個節點,并將_hot節點作為其父節點連接到樹上this->_size++;//更新規模this->updateHeightAbove(x);//更新高度。return x; }

    ??請讀者好好體會這段簡短但不簡單的代碼所表達的意思。特別是引用的用處。
    ??并且插入后也要更新相應的節點高度,以及其祖先節點的高度。關于高度更新的算法實現,請見本系列文章第二部分。

    2.插入示例(動圖演示!)~

    在下圖中插入21

    3.insert復雜度分析~

    ??節點插入操作所需的時間,主要消耗于對算法search()及updateHeightAbove()的調用。后者與前者一樣,在每一層次至多涉及一個節點,僅消耗O(1)時間,故其時間復雜度也同樣取決于新節點的深度,在最壞情況下不超過全樹的高度。



    (四)刪除remove~

    ??理解BST的刪除算法,可以說是BST最重要的一點,弄懂了BST的刪除,那么你就懂了BST,接下來介紹一個最重要的刪除靜態函數,這個函數不僅對于BST有用,對于AVL,RedBlack都有用。

    1.最重要的刪除函數(動圖演示!)~

    ??刪除一顆BST的節點,并且保持BST的性質,需要分以下3種大情況來考慮。

    (1)該節點沒有子樹~

    直接刪除該節點既可,并且修改對應指針地址 如下圖刪除節點21

    (2)該節點只有一顆子樹~

    a.只有左子樹~
    則其左子樹接替它的位置,并且修改對應指針地址 如下圖刪除節點29

    b.只有右子樹~
    則其右子樹接替它的位置,并且修改對應指針地址 如下圖刪除節點29

    (3)該節點有兩顆子樹~

    ??在此,需要借用在本系列文章第一部分提到的關于求當前節點的直接后繼算法。建議看完這個算法的實現,再來理解這種情況,否則你會感到迷惑。

    ??首先要在心里明確一個事實:即直接后繼,必然沒有左孩子。

    a.右孩子就是該節點的直接后繼~

    ??在這種情況下,可以得知,該右孩子必然沒有左孩子(可能有右孩子),不然其右孩子不可能作為其直接后繼。此時,就將該節點與其后繼(也就是右孩子)的值進行交換(看下面代碼你就能明白交換比直接刪這個節點更好)。再重新連接指針即可。

    下面圖示為了簡單起見,沒有體現交換的過程 如下圖刪除節點20

    b.該節點的直接后繼在右孩子的左子樹中~

    ??在這種情況下,可以得知,該節點的直接后繼必然是左孩子。此時,就將該節點與其后繼(也就是右孩子)的值進行交換。再重新連接指針即可。

    下面圖示為了簡單起見,沒有體現交換的過程 如下圖刪除節點65

    (4)刪除靜態函數代碼~

    此代碼為刪除算法的難點,重點,理解好此代碼,你才能理解進一步的AVL,RedBlack!

    ??其中HasLChid等全局函數,位于第一部分定義的BInNode_Macro.h中,succ()算法位于第一部分求直接后繼的算法中,release刪除函數位于第二部分定義的release.h中。

    //=================刪除================// template<typename T>//適用于AVL Splay,RedBlack等,必須這么設計,才能做到完美刪除,且保持BST的性質 static BinNode<T>* removeAt(BinNode<T>*& x, BinNode<T>*& hot) {//這里x必須用引用,才不會使指針亂指using BinNodePtr = BinNode<T>*; //記錄x的地址里面保存的值,若刪除temp里面的值,即刪除x里面的值,但x的本身地址不會影響temp,反之亦然。BinNodePtr temp = x;//替代被刪除節點的接替者,一般為被刪除節點的左孩子或者右孩子,而不是x的左孩子或者右孩子BinNodePtr replacer = nullptr;if (!HasLChild(x)) {//如果x沒有左孩子,或者x左右孩子均無,則將x的右孩子作為x,并將接替者設為x的右孩子x = x->_rchild;replacer = x;}else if (!HasRChild(x)) {//如果x沒有右孩子,則將x的左孩子作為x,并將接替者設為x的左孩子x = x->_lchild;replacer = x;}else {temp = temp->succ();//取得中序遍歷的后繼//這個后繼必將沒有左孩子std::swap(x->_data, temp->_data);//交換對應的值if (temp->_parent == x) {//如果后繼的父親是原來的x,后繼必然為x的右孩子replacer = temp->_rchild; //就將后繼的右孩子作為父親的右孩子temp->_parent->_rchild = replacer;}else {//如果后繼的父親不是原來的x,后繼必然為某一節點的左孩子replacer = temp->_rchild;temp->_parent->_lchild=replacer;//就將后繼的右孩子作為這個節點左孩子}}//hot即被刪除節點的父親。而temp正是要刪除的節點。hot = temp->_parent;if (replacer)//若replacer存在,則必須將其父指針指向hot。不然如同x->_rchild的父親指向的還是原來的replacer->_parent = hot;//釋放原來x所指的堆區的數據,或者x的后繼的堆區的數據release(temp->_data);release(temp);return replacer; }

    2.BST的刪除代碼~

    ??理解了上面的代碼,就能很容易理解BST的刪除。

    ??同樣先前都必將要經過查找操作。對于在此系列定義的BST而言,里面存放的都是不可重復的數據。因此,對于刪除而言,如果這個元素存在BST中,則進行刪除,如果在BST中不存在這個元素,就返回false。

    ??在此,_hot節點的作用就體現出來了,如果存在這個元素,在經過removeAt算法后,_hot節點也必將是被刪除節點的父親節點,此時,更新高度,只需要更新_hot節點的高度既可。

    template<typename T> bool BST<T>::remove(const T& data) {BinNodePtr& x = search(data);//接收返回的值,這里用引用if (x == nullptr)//若沒找到return false;//返回falseremoveAt(x, _hot);//刪除找到的節點this->_size--;//更新規模this->updateHeightAbove(_hot);//更新高度return true; }

    3.remove復雜度分析~

    ??刪除操作所需的時間,主要消耗于對search()、succ()和updateHeightAbove()的調用。在樹中的任一高度,它們至多消耗O(1)時間。故總體的漸進時間復雜度,亦不超過全樹的高度。



    (五)完整BST.h~

    ??注意,connect34算法和rotateAt算法,我會在AVL中再進行介紹

    #pragma once #include "BinTree.h"namespace mytree {using namespace mytree_marcro;template<typename T=int>class BST :public BinTree<T> {protected:using BinNodePtr = BinNode<T>*;protected:BinNodePtr _hot;//"命中節點"的"父親"public:BST():_hot(nullptr){}//調用構造函數時,先調用子類的,再調用父類,析構則相反virtual~ BST() = default;//由于刪除全部交給b樹模板類,所以這里不需要去額外刪除protected:BinNode<T>* connect34(//3+4重構,可以用于AVL,RedBlackBinNode<T>*, BinNode<T>*, BinNode<T>*,BinNode<T>*, BinNode<T>*, BinNode<T>*, BinNode<T>*);BinNode<T>* rotateAt(BinNode<T>* v);//對v及其父親、祖父做統一旋轉調整private:BinNode<T>*& search_R(const T& data);//查找遞歸版public:BinNode<T>*& search(const T& data);//查找//返回引用,便于插入刪除//接受者一般要加個引用接收virtual BinNode<T>* insert(const T& data)override;//插入節點virtual bool remove(const T& data);//刪除節點};//class BSTtemplate<typename T>BinNode<T>* BST<T>::connect34(BinNode<T>* a, BinNode<T>* b, BinNode<T>* c,BinNode<T>* T1, BinNode<T>* T2, BinNode<T>* T3, BinNode<T>* T4){a->_lchild = T1; if (T1)T1->_parent = a;a->_rchild = T2; if (T2)T2->_parent = a; this->updateHeight(a);c->_lchild = T3; if (T3)T3->_parent = c;c->_rchild = T4; if (T4)T4->_parent = c; this->updateHeight(c);b->_lchild = a; a->_parent = b;b->_rchild = c; c->_parent = b; this->updateHeight(b);return b;}template<typename T>BinNode<T>* BST<T>::rotateAt(BinNode<T>* v) //返回調整后局部子樹根節點的位置{if (v == nullptr) {printf("Error!"); exit(0);}BinNode<T>* p = v->_parent; BinNode<T>* g = p->_parent;//設定v的父親與祖父//視v、p和g相對位置分四種情況if (IsLChild(p)) {//Lif (IsLChild(v)) {//LLp->_parent = g->_parent;//向上連接return connect34(v, p, g, v->_lchild, v->_rchild, p->_rchild, g->_rchild);}else {//LRv->_parent = g->_parent;//向上連接return connect34(p, v, g, p->_lchild, v->_lchild, v->_rchild, g->_rchild);}}else {//Rif (IsRChild(v)) {//RRp->_parent = g->_parent;//向上連接return connect34(g, p, v, g->_lchild, p->_lchild, v->_lchild, v->_rchild);}else {//RLv->_parent = g->_parent;//向上連接return connect34(g, v, p, g->_lchild, v->_lchild, v->_rchild, p->_rchild);}}}//=================查找================//namespace mybst {template<typename T,typename BinNodePtr>static BinNode<T>*& search_In(BinNodePtr& current, const T& data, BinNodePtr& hot) {//必須加引用,不然地址改變的話,原地址不能改變if (!current || data == current->_data)return current;//遞歸基,當當前節點為空或者找到了對應的節點,就退出hot = current;//hot 記錄父親節點的位置return search_In((data < current->_data ? current->_lchild : current->_rchild), data, hot);//二分遞歸查找}}//namespace mybsttemplate<typename T>BinNode<T>*& BST<T>::search_R(const T& data) {using mybst::search_In;return search_In(this->_root, data, _hot = nullptr);}template<typename T>BinNode<T>*& BST<T>::search(const T& data) {if (!this->_root || data == this->_root->_data) {//如果根節點不為空,或者正好根節點就是要找的節點_hot = nullptr;return this->_root;}_hot = this->_root;//更新_hotwhile (true){//current的地址與_hot的孩子綁定,不能與_hot綁定。BinNodePtr& current = ((data < _hot->_data) ? _hot->_lchild : _hot->_rchild);if (!current || data == current->_data)return current;_hot = current;//更新_hot位置}}//=================插入================//template<typename T>BinNode<T>* BST<T>::insert(const T& data) {BinNodePtr& x = search(data);//查找有無這個節點//必須用引用,這樣其才必然是_hot的孩子if (x)//若有,則返回這個節點,插入失敗return x;x = new BinNode<T>(data, _hot);//若無,則新建一個節點,并將_hot節點作為其父節點連接到樹上this->_size++;//更新規模this->updateHeightAbove(x);//更新高度。return x;}//=================刪除================//template<typename T>//適用于AVL Splay,RedBlack等,必須這么設計,才能做到完美刪除,且保持BST的性質static BinNode<T>* removeAt(BinNode<T>*& x, BinNode<T>*& hot) {//這里x必須用引用,才不會使指針亂指using BinNodePtr = BinNode<T>*; //記錄x的地址里面保存的值,若刪除temp里面的值,即刪除x里面的值,但x的本身地址不會影響temp,反之亦然。BinNodePtr temp = x;//替代被刪除節點的接替者,一般為被刪除節點的左孩子或者右孩子,而不是x的左孩子或者右孩子BinNodePtr replacer = nullptr;if (!HasLChild(x)) {//如果x沒有左孩子,或者x左右孩子均無,則將x的右孩子作為x,并將接替者設為x的右孩子x = x->_rchild;replacer = x;}else if (!HasRChild(x)) {//如果x沒有右孩子,則將x的左孩子作為x,并將接替者設為x的左孩子x = x->_lchild;replacer = x;}else {temp = temp->succ();//取得中序遍歷的后繼//這個后繼必將沒有左孩子std::swap(x->_data, temp->_data);//交換對應的值if (temp->_parent == x) {//如果后繼的父親是原來的x,后繼必然為x的右孩子replacer = temp->_rchild; //就將后繼的右孩子作為父親的右孩子temp->_parent->_rchild = replacer;}else {//如果后繼的父親不是原來的x,后繼必然為某一節點的左孩子replacer = temp->_rchild;temp->_parent->_lchild=replacer;//就將后繼的右孩子作為這個節點左孩子}}//hot即被刪除節點的父親。而temp正是要刪除的節點。hot = temp->_parent;if (replacer)//若replacer存在,則必須將其父指針指向hot。不然如同x->_rchild的父親指向的還是原來的replacer->_parent = hot;//釋放原來x所指的堆區的數據,或者x的后繼的堆區的數據release(temp->_data);release(temp);return replacer;}template<typename T>bool BST<T>::remove(const T& data) {BinNodePtr& x = search(data);//接收返回的值,這里用引用if (x == nullptr)//若沒找到return false;//返回falseremoveAt(x, _hot);//刪除找到的節點this->_size--;//更新規模this->updateHeightAbove(_hot);//更新高度return true;} }//namespace mytree

    四、BST測試代碼~

    在此處,就會利用到再本系列文章第一部分中的遍歷函數,以及利用仿函數來實現遍歷。

    #include<iostream> #include "BinNode.h" #include "BST.h" using namespace std; using namespace mytree;template<typename BinNodePtr> void visitprint(BinNodePtr x) {cout << x->_data; }int main() {BST<int>* BT = new BST<int>;//cout << BT.size() << endl;//cout << BT.empty() << endl;BT->insert(3);BT->insert(6);BT->insert(2);BT->insert(4);BT->insert(5);BT->insert(1);BT->insert(7);BT->insert(8);BT->remove(7);BT->remove(6);BT->remove(3);cout << endl;BT->travLevel(visitprint<BinNode<int>*>);cout << endl;BT->travPre(visitprint<BinNode<int>*>);cout << endl;BT->travIn(visitprint<BinNode<int>*>);cout << endl;BT->travPost(visitprint<BinNode<int>*>);cout << endl;delete BT;return 0; } 結果為 42815 42185 12458 12584


    動圖演示為



    五、BST的缺點~

    ??平均BST樹的高度為log2n,即平均復雜度為log2n。而BST在高度上,并沒有限制,因此可能出現這種情況。

    ??這樣,要找到6這個節點,就需要把整棵樹都遍歷一遍,因此最壞復雜度為O(n)。這樣BST相對有序的vector而言,就沒有任何的優勢。
    ??而這,也恰恰是我們要引入AVL和RedBlack的原因!



    五、后序文章鏈接~

  • 基本二叉樹節點,通用函數 二叉樹節點
  • 基本二叉樹類的定義和實現 二叉樹基類
  • BST(二叉搜索樹的實現) BST
  • AVL(二叉平衡搜索樹的實現)AVL
  • B樹的實現(如果你只想了解B樹,可以跳過所有章節,直接看B樹)B樹
  • 紅黑樹的實現 RedBlack
  • 學一個東西,不知道其道理,不高明!

    總結

    以上是生活随笔為你收集整理的真c++ 从二叉树到红黑树(3)之二叉搜索树BST的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。