BinTree::構造、析構、插入、刪除

構造析構:

   BinTree() : _size(0), _root(NULL) { } //構造函數
   ~BinTree() { if (0 < _size) remove(_root); } //析構函數

插入:

   BinNodePosi(T) insertAsRoot(T const & e); //插入根節點
   BinNodePosi(T) insertAsLC(BinNodePosi(T) x, T const & e); //e作爲x的左孩子(原無)插入
   BinNodePosi(T) insertAsRC(BinNodePosi(T) x, T const & e); //e作爲x的右孩子(原無)插入
   BinNodePosi(T) attachAsLC(BinNodePosi(T) x, BinTree<T>* &T); //T作爲x左子樹接入
   BinNodePosi(T) attachAsRC(BinNodePosi(T) x, BinTree<T>* &T); //T作爲x右子樹接入

插入根節點:

template <typename T> BinNodePosi(T) BinTree<T>::insertAsRoot(T const& e)
{ _size = 1; return _root = new BinNode<T>(e); } //將e當作根節點插入空的二叉樹

插入左右孩子:

template <typename T> //將e作爲當前節點的左孩子插入二叉樹
BinNodePosi(T) BinNode<T>::insertAsLC(T const & e) {  return lChild = new BinNode(e, this);  }

template <typename T> //將e作爲當前節點的右孩子插入二叉樹
BinNodePosi(T) BinNode<T>::insertAsRC(T const & e) {  return rChild = new BinNode(e, this);  }

#define stature(p) ((p) ? (p)->height : -1) //節點高度(與“空樹高度爲-1”的約定相統一)
template <typename T> int BinTree<T>::updateHeight(BinNodePosi(T) x) //更新節點x高度
{ return x->height = 1 + max(stature(x->lChild), stature(x->rChild)); } //具體規則因樹不同而異

template <typename T> void BinTree<T>::updateHeightAbove(BinNodePosi(T) x) //更新v及祖先的高度
{ while (x) { updateHeight(x); x = x->parent; } } //可優化:一旦高度未變,即可終止

template <typename T> BinNodePosi(T) BinTree<T>::insertAsLC(BinNodePosi(T) x, T const& e)
{ _size++; x->insertAsLC(e); updateHeightAbove(x); return x->lChild; } //e插入爲x的左孩子

template <typename T> BinNodePosi(T) BinTree<T>::insertAsRC(BinNodePosi(T) x, T const& e)
{ _size++; x->insertAsRC(e); updateHeightAbove(x); return x->rChild; } //e插入爲x的右孩子

插入左右子樹:

template <typename T> //二叉樹子樹接入算法:將S當作節點x的左子樹接入,S本身置空
BinNodePosi(T) BinTree<T>::attachAsLC(BinNodePosi(T) x, BinTree<T>* &S) { //x->lChild == NULL
   if (x->lChild = S->_root) x->lChild->parent = x; //接入
   _size += S->_size; updateHeightAbove(x); //更新全樹規模與x所有祖先的高度
   S->_root = NULL; S->_size = 0; release(S); S = NULL; return x; //釋放原樹,返回接入位置
}

template <typename T> //二叉樹子樹接入算法:將S當作節點x的右子樹接入,S本身置空
BinNodePosi(T) BinTree<T>::attachAsRC(BinNodePosi(T) x, BinTree<T>* &S) { //x->rChild == NULL
   if (x->rChild = S->_root) x->rChild->parent = x; //接入
   _size += S->_size; updateHeightAbove(x); //更新全樹規模與x所有祖先的高度
   S->_root = NULL; S->_size = 0; release(S); S = NULL; return x; //釋放原樹,返回接入位置
}

刪除以結點爲根的子樹:

#define FromParentTo(x) ( \
   IsRoot(x) ? _root : ( \
   IsLChild(x) ? (x).parent->lChild : (x).parent->rChild \
   ) \
) //來自父親的指針

template <typename T> //刪除二叉樹中位置x處的節點及其後代,返回被刪除節點的數值
int BinTree<T>::remove(BinNodePosi(T) x) { //assert: x爲二叉樹中的合法位置
   FromParentTo(*x) = NULL; //切斷來自父節點的指針
   updateHeightAbove(x->parent); //更新祖先高度
   int n = removeAt(x); _size -= n; return n; //刪除子樹x,更新規模,返回刪除節點總數
}

template <typename T> //刪除二叉樹中位置x處的節點及其後代,返回被刪除節點的數值
static int removeAt(BinNodePosi(T) x) { //assert: x爲二叉樹中的合法位置
   if (!x) return 0; //遞歸基:空樹
   int n = 1 + removeAt(x->lChild) + removeAt(x->rChild); //遞歸釋放左、右子樹
   release(x->data); release(x); return n; //釋放被摘除節點,並返回刪除節點總數
}

子樹提出:

template <typename T> //二叉樹子樹分離算法:將子樹x從當前樹中摘除,將其封裝爲一棵獨立子樹返回
BinTree<T>* BinTree<T>::secede(BinNodePosi(T) x) { //assert: x爲二叉樹中的合法位置
   FromParentTo(*x) = NULL; //切斷來自父節點的指針
   updateHeightAbove(x->parent); //更新原樹中所有祖先的高度
   BinTree<T>* S = new BinTree<T>; S->_root = x; x->parent = NULL; //新樹以x爲根
   S->_size = x->size(); _size -= S->_size; return S; //更新規模,返回分離出來的子樹
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章