标签:inno return 处理 规模 隔离 while 初始 cte 等于
#ifndef BST_hpp #define BST_hpp #include "BinTree.hpp" #include "Entry.hpp" //二叉搜索树 //任何一个二叉树是二叉搜索树,当且仅当其中序遍历序列单调非降 template <typename T> class BST : public BinTree<T> { protected: BinNodePosi(T) _hot; //"命中"节点的父亲 BinNodePosi(T) connect34( //按照"3+4"的结构,连接3个节点及3颗子树 BinNodePosi(T),BinNodePosi(T),BinNodePosi(T), BinNodePosi(T),BinNodePosi(T),BinNodePosi(T),BinNodePosi(T)); BinNodePosi(T) rotateAt(BinNodePosi(T) x); //对x及其父亲、祖父做统一旋转调整 public: virtual BinNodePosi(T)& search(const T& e); //查找 virtual BinNodePosi(T) insert(const T& e); //插入 virtual bool remove(const T& e); //删除 }; #pragma mark - 查找 //在以v为根的(AVL、SPLAY、rbTree等)BST子树中查找关键码e template <typename T> static BinNodePosi(T)& searchIn(BinNodePosi(T) & v, const T& e,BinNodePosi(T) & hot) { if (!v || (e == v->data)) { return v; } //一般情况:先记下当前节点,然后再深入一层,递归查找 hot = v; return searchIn((e < v->data)? v->lc:v->rc, e, hot); } //searchIn的迭代版 #define EQUAL(e, v) (!(v) || (e) == (v)->data) //节点v(或假想的通配哨兵)的关键码等于e template <typename T> static BinNodePosi(T)& searchIn_I2(BinNodePosi(T) & v, const T& e,BinNodePosi(T) & hot) { if (EQUAL(e, v)) { return v; //退化情况:在子树根节点v处命中 } hot = v; while (1) { //确定深入方向 BinNodePosi(T) & c = ( e < hot->data) ? hot->lc : hot->rc; if (EQUAL(e, c)) { return c; } hot = c; }//hot始终指向最后一个失败节点 }//返回时,返回值指向命中节点(或假想的通配哨兵),hot指向其父亲(退化时为初始值NULL) template <typename T> BinNodePosi(T) & BST<T>::search(const T &e) { return searchIn(this->_root, e, _hot = NULL); } #pragma mark - 插入 //将关键码e插入BST树中 template <typename T> BinNodePosi(T) BST<T>::insert(const T &e) { BinNodePosi(T) &x = search(e); if (x) { return x; //确认目标不存在(留意对_hot的设置) } x = new BinNode<T> (e, _hot); //创建新节点x:以e为关键码,以_hot为父 this -> _size++; //更新全树规模 this -> updateHeightAbove(x); //更新x及其历代祖先的高度 return x; //新插入的节点,必为叶子 }//无论e是否存在于原树中,返回时总有x->data == e #pragma mark - 删除 template <typename T> static BinNodePosi(T) removeAt(BinNodePosi(T) &x,BinNodePosi(T) &hot) { BinNodePosi(T) w = x; //实际被摘除的节点,初值同x BinNodePosi(T) succ = NULL; //实际被删除节点的接替者 if ( ! HasLChild(*x) ){ //若*x的左子树为空,则可直接将*x替换为其右子树 succ = x = x -> rc; }else if ( !HasRChild(*x) ) { //若右子树为空,则可对称的处理---注意,此时succ != NULL succ = x = x -> lc; }else{ //若左右子树均存在,则选择x的直接后继作为实际被摘除节点,为此需要(在右子树中)找到*x的直接后继*w //交换*x和*w的数据元素 w = w -> succ(); std::swap(x->data, w->data); BinNodePosi(T) u = w -> parent; ( (u == x) ? u->rc : u->lc ) = succ = w -> rc; //隔离节点*w } hot = w -> parent; //记录实际被删除节点的父亲 if (succ) { succ -> parent = hot; //并将被删除节点的接替者与hot相连 } delete w -> data; delete w; return succ;//释放被摘除节点,返回接替者 } //从BST树中删除关键码e template <typename T> bool BST<T>::remove(const T &e) { BinNodePosi(T) &x = search(e); if (!x) { //确认目标存在(留意_hot的设置) return false; } removeAt(x, _hot); //实施删除 this -> _size--; this -> updateHeightAbove(_hot); //更新_hot及其历代祖先的高度 return true; }//删除成功与否,由返回值指示 template <typename T> BinNodePosi(T) BST<T>::connect34(BinNodePosi(T) a, BinNodePosi(T) b, BinNodePosi(T)c, BinNodePosi(T) T0, BinNodePosi(T) T1, BinNodePosi(T) T2, BinNodePosi(T) T3) { a -> lc = T0; if (T0) { T0 -> parent = a; } a -> rc = T1; if (T1) { T1 -> parent = a; } this -> updateHeight(a); c -> lc = T2; if (T2) { T2 -> parent = c; } c -> rc = T3; if (T3) { T3 -> parent = c; } this -> updateHeight(c); b -> lc = a; a -> parent = b; b -> rc = c; c -> parent = b; this -> updateHeight(b); return b; //该子树新的根节点 } //v为非空孙辈节点 template <typename T> BinNodePosi(T) BST<T>::rotateAt(BinNodePosi(T) v){ BinNodePosi(T) p = v -> parent; BinNodePosi(T) g = p -> parent; if (IsLChild(*p)) { //zig if (IsLChild(*v)) { //zig--zig p -> parent = g -> parent;//向上联接 return connect34(v, p, g, v->lc, v->rc, p->rc, g->rc); }else{ //zig--zag v -> parent = g -> parent; //向上联接 return connect34(p, v, g, p->lc, v->lc, v->rc, g->rc); } }else{ //zag if (IsRChild(*v)) { //zag--zag p -> parent = g -> parent;//向上联接 return connect34(g, p, v, g->lc, p->lc, v->lc, v->rc); }else{ //zag---zig v -> parent = g -> parent; //向上联接 return connect34(g, v, p, g->lc, v->lc, v->rc, p->rc); } } } #endif /* BST_hpp */
标签:inno return 处理 规模 隔离 while 初始 cte 等于
原文地址:https://www.cnblogs.com/gkp307/p/9621076.html