真c++二叉樹から赤黒樹(2)への二叉樹基類


この文章は二叉樹から赤黒樹シリーズの文章の第二節であり,主に二叉樹抽象基類の基本構成を紹介する.後続BST、AVL、RedBlackのために敷き詰めます
文書ディレクトリ
  • 一、前の文章のリンク~(右の波線をクリックしてディレクトリに戻る)
  • 二、二叉樹抽象基類~
  • (一)変数とインタフェースを定義~
  • 1.必要な変数~
  • 2.必要なインタフェース~
  • 3.重要補助関数~
  • 4.その他の補助関数~
  • 5.BinTree.h~
  • (二)現在のノードの親の子の参照を取得~
  • (3)現在のノードの高さを更新~
  • (四)現在のノードとその祖先ノードの高さを更新~
  • .
  • (五)削除関数~
  • (六)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は、このシリーズの第1節でグローバル領域で定義された関数で、ヘッダファイルは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ヘッダファイル~
    (5)の削除コードには、ヘッダファイルreleaseにあるrelease関数を用いたノードの削除が見られる.h中.
    この削除関数はテンプレート偏特化技術を用いた.
    #pragma once
    
    template<typename T>
    struct Cleaner {
    	static void clean(T& x) {
    #ifdef DEBUG
    		printf("   
    "
    ); #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
  • 一つのことを学んで、その道理を知らないで、上手ではありません!