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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

真c++ 从二叉树到红黑树(2)之二叉树基类

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

??此文章為從二叉樹到紅黑樹系列文章的第二節,主要介紹介紹二叉樹抽象基類的基本組成。為后續BST,AVL和RedBlack做好鋪墊


文章目錄

  • 一、前面文章鏈接~(點擊右邊波浪線可以返回目錄)
  • 二、二叉樹抽象基類~
    • (一)定義變量和接口~
      • 1.需要的變量~
      • 2.需要的接口~
      • 3.重要輔助函數~
      • 4.其他輔助函數~
      • 5.BinTree.h~
    • (二)獲取當前節點的父親的孩子的引用~
    • (三)更新當前節點的高度~
    • (四)更新當前節點及其祖先節點的高度~
    • (五)刪除函數~
    • (六)release.h頭文件~
    • (七)完整BinTree.h~
  • 三、后序文章鏈接~

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

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

  • 基本二叉樹節點,通用函數 二叉樹節點
  • 二、二叉樹抽象基類~

    (一)定義變量和接口~

    1.需要的變量~

    int _size;//二叉樹的規模 BinNodePtr _root;//二叉樹的樹根

    2.需要的接口~

    構造,析構 判空 獲取二叉樹的規模、根節點 獲取二叉樹當前高度 四種遍歷(結合根節點使用)

    3.重要輔助函數~

    獲取當前節點的父親的孩子的引用。(這句話有點拗口,但這個函數是整個流程的關鍵) FromParentTo

    4.其他輔助函數~

    更新節點的高度 updateHeight 更新節點以及其祖先的高度 updateHeightAbove 刪除所有節點 remove 插入節點insert(為了方便起見,設為純虛函數,使這個二叉樹基類不能實例化)

    5.BinTree.h~

    template<typename T=int> class BinTree { protected:using BinNodePtr = BinNode<T>*;using BinTreePtr = BinTree<T>*;protected:int _size;//二叉樹的規模BinNodePtr _root;//二叉樹的樹根public:BinTree() :_size(0), _root(nullptr) {}virtual ~BinTree() {//std::cout << "調用析構函數" << std::endl;if (0 < _size)remove(_root); }public:constexpr int size()const { return _size; }//規模constexpr bool empty()const { return !_root; }//判空inline BinNodePtr root()const {//返回樹根return (_root) ? _root : nullptr;}constexpr int getHeight()const {//獲取樹高度return (this->_root) ? this->_root->_height : -1;}public:template<typename VST>//層次遍歷void travLevel(VST visit) {if (_root)_root->travLevel(visit);}template<typename VST>//先序遍歷void travPre(VST visit,const int&method=1) {if (_root)_root->travPre(visit, method);}template<typename VST>//中序遍歷void travIn(VST visit, const int& method = 1) {if (_root)_root->travIn(visit, method);}template<typename VST>//后序遍歷void travPost(VST visit, const int& method = 1) {if (_root)_root->travPost(visit, method);}protected:virtual int updateHeight(BinNodePtr x)const;//更新節點x的高度/*vs開最新版本的c++就可以用virtual constexpr*/void updateHeightAbove(BinNodePtr x)const;//更新節點x及其祖先的高度protected://注意返回值為引用,不然無法作為左值BinNodePtr& FromParentTo(BinNodePtr x) {/*用這個更改x的父親的左右孩子*//*接受者一般要加個引用接收*/return (IsRoot(x) ? this->_root : (IsLChild(x) ? x->_parent->_lchild : x->_parent->_rchild));}protected:virtual BinNode<T>* insert(const T& data) = 0;//插入節點,為了方便起見,設為純虛函數,即這個基類為抽象類,沒有實例private:void remove(BinNodePtr x);//只用于析構函數,因此不管高度等其他因素,直接暴力全部刪除};//class BinTree

    (二)獲取當前節點的父親的孩子的引用~

    ??這個函數對于AVL樹和RedBlack樹的插入和刪除而言,至關重要。我會在AVL和RedBlack樹的相應部分再次說明這個函數的作用。

    //注意返回值為引用,不然無法作為左值 BinNodePtr& FromParentTo(BinNodePtr x) {/*用這個更改x的父親的左右孩子*//*接受者一般要加個引用接收*/return (IsRoot(x) ? this->_root : (IsLChild(x) ? x->_parent->_lchild : x->_parent->_rchild)); }

    (三)更新當前節點的高度~

    此處stature是本系列文章第一節的在全局區定義的函數,頭文件為BInNode_Macro.h。

    //更新節點x的高度 template<typename T> int BinTree<T>::updateHeight(BinNodePtr x)const {//高度為左右子樹的高度的最大值return x->_height = 1 + std::max(stature(x->_lchild), stature(x->_rchild)); }

    (四)更新當前節點及其祖先節點的高度~

    ??通常,還需要從當前節點出發沿parent指針逆行向上,依次更新各代祖先的高度記錄,直到這個祖先的高度不變時停止。

    //更新節點x及其祖先的高度 template<typename T> void BinTree<T>::updateHeightAbove(BinNodePtr x)const{if (x == nullptr)return;updateHeight(x);do {x = x->_parent;if (x == nullptr)//如果父節點為空節點,則返回return;int currentHeight = x->_height;//記錄節點當前的高度int afterHeight = updateHeight(x);if (currentHeight == afterHeight)//只要其高度沒有更新,那么就可以跳出循環break;} while (x);//當此節點不為空 }

    (五)刪除函數~

    這個函數用于析構函數中,用于所有樹的析構,無論是BST,AVL還是RedBlack。

    //=========刪除============// template<typename T> void BinTree<T>::remove(BinNodePtr x) {if (nullptr==x)return;remove(x->_lchild);remove(x->_rchild);/*處于方便,用遞歸刪除*/release(x->_data);release(x); }

    (六)release.h頭文件~

    ??在(五)中的刪除代碼中,可以看到用到了release函數來進行節點的刪除,其位于頭文件release.h中。

    該刪除函數用到了模板偏特化技術。 #pragma oncetemplate<typename T> struct Cleaner {static void clean(T& x) { #ifdef DEBUGprintf("刪除了\n"); #endif // DEBUG} };template<typename T> struct Cleaner<T*> {static void clean(T*& x) {//注意這里是引用,方便刪除后,直接變成空指針if (x) {delete x;x = nullptr;}} };template<typename T> static void release(T &x) {//利用模板偏特化,刪除節點,若為指針,則delete,若不為指針,則不做任何操作。Cleaner<T>::clean(x); }

    (七)完整BinTree.h~

    #pragma once #include"BinNode.h" #include "release.h"namespace mytree {using namespace mytree_marcro;template<typename T=int>class BinTree {protected:using BinNodePtr = BinNode<T>*;using BinTreePtr = BinTree<T>*;protected:int _size;//二叉樹的規模BinNodePtr _root;//二叉樹的樹根public:BinTree() :_size(0), _root(nullptr) {}virtual ~BinTree() {//std::cout << "調用析構函數" << std::endl;if (0 < _size)remove(_root); }public:constexpr int size()const { return _size; }//規模constexpr bool empty()const { return !_root; }//判空inline BinNodePtr root()const {//返回樹根return (_root) ? _root : nullptr;}constexpr int getHeight()const {//獲取樹高度return (this->_root) ? this->_root->_height : -1;}public:template<typename VST>//層次遍歷void travLevel(VST visit) {if (_root)_root->travLevel(visit);}template<typename VST>//先序遍歷void travPre(VST visit,const int&method=1) {if (_root)_root->travPre(visit, method);}template<typename VST>//中序遍歷void travIn(VST visit, const int& method = 1) {if (_root)_root->travIn(visit, method);}template<typename VST>//后序遍歷void travPost(VST visit, const int& method = 1) {if (_root)_root->travPost(visit, method);}protected:virtual int updateHeight(BinNodePtr x)const;//更新節點x的高度/*vs開最新版本的c++就可以用virtual constexpr*/void updateHeightAbove(BinNodePtr x)const;//更新節點x及其祖先的高度protected://注意返回值為引用,不然無法作為左值BinNodePtr& FromParentTo(BinNodePtr x) {/*用這個更改x的父親的左右孩子*//*接受者一般要加個引用接收*/return (IsRoot(x) ? this->_root : (IsLChild(x) ? x->_parent->_lchild : x->_parent->_rchild));}protected:virtual BinNode<T>* insert(const T& data) = 0;//插入節點,為了方便起見,設為純虛函數,即這個基類為抽象類,沒有實例private:void remove(BinNodePtr x);//只用于析構函數,因此不管高度等其他因素,直接暴力全部刪除};//class BinTree//================更新高度==================////更新節點x的高度template<typename T>int BinTree<T>::updateHeight(BinNodePtr x)const {return x->_height = 1 + std::max(stature(x->_lchild), stature(x->_rchild));//高度為左右子樹的高度的最大值}//更新節點x及其祖先的高度template<typename T>void BinTree<T>::updateHeightAbove(BinNodePtr x)const{if (x == nullptr)return;updateHeight(x);do {x = x->_parent;if (x == nullptr)//如果父節點為空節點,則返回return;int currentHeight = x->_height;//記錄節點當前的高度int afterHeight = updateHeight(x);if (currentHeight == afterHeight)//只要其高度沒有更新,那么就可以跳出循環break;} while (x);//當此節點不為空}//=========刪除============//template<typename T>void BinTree<T>::remove(BinNodePtr x) {if (nullptr==x)return;remove(x->_lchild);remove(x->_rchild);/*處于方便,用遞歸刪除*/release(x->_data);release(x);} }//namespace mytree

    三、后序文章鏈接~

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

    總結

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

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