标签:asc false 递归 接口 eve ted red stack 入栈
BinNode.hpp
#ifndef BinNode_hpp #define BinNode_hpp #include <iostream> #include "Queue.hpp" #define BinNodePosi(T) BinNode<T>* #define stature(p) ( (p) ? (p)->height : -1) //节点高度 typedef enum { RB_RED, RB_BLACK }RBColor; //节点颜色 //二叉树节点模版类 template <typename T> struct BinNode { T data; //数值 BinNodePosi(T) parent; BinNodePosi(T) lc; BinNodePosi(T) rc; //父节点及左右孩子 int height; //高度(通用) int npl; //Null Path Length(左式堆,也可直接用height代替) RBColor color; //颜色(红黑树) //构造函数 BinNode(): parent(NULL), lc(NULL), rc(NULL),height(0),npl(1),color(RB_RED) {} BinNode(T e,BinNodePosi(T) p = NULL,BinNodePosi(T) lc = NULL, BinNodePosi(T) rc = NULL, int h = 0,int l = 1, RBColor c = RB_RED) : data(e), parent(p), lc(lc),rc(rc),height(h),npl(l),color(c) {} //操作接口 int size(); BinNodePosi(T) insertAsLC(T const&); BinNodePosi(T) insertAsRC(T const&); BinNodePosi(T) succ(); template <typename VST> void travLevel(VST&); //子树层次遍历 template <typename VST> void travPre(VST&); //子树先序遍历 template <typename VST> void travIn(VST&); //子树中序遍历 template <typename VST> void travPost(VST&); //子树后续遍历 bool operator<(BinNode const& bn) { return data < bn.data; } bool operator==(BinNode const& bn) { return data == bn.data; } }; //BinNode状态与性质的判断 #define IsRoot(x) (! ((x).parent)) #define IsLChild(x) ( !IsRoot(x) && ( & (x) == (x).parent->lc ) ) #define IsRChild(x) ( !IsRoot(x) && ( & (x) == (x).parent->rc ) ) #define HasParent(x) (!IsRoot(x)) #define HasLChild(x) ( (x).lc ) #define HasRChild(x) ( (x).rc ) #define HasChild(x) ( HasLChild(x) || HasRChild(x) ) #define HasBothChild(x) ( HasLChild(x) && HasRChild(x) ) #define IsLeaf(x) ( !HasChild(x) ) //与BinNode具有特定关系的节点及指针 #define sibling(p) ( IsLChild( *(p) ) ? (p)->parent->rc : (p)->parent->lc ) #define uncle(x) ( IsLChild( *( (x)->parent) ) ? (x)->parent->parent->rc : (x)->parent->parent->lc ) //来自父亲的引用 #define FromParentTo(x,_root) ( IsRoot(x) ? _root : ( IsLChild(x) ? (x).parent->lc : (x).parent->rc ) ) template <typename T> BinNodePosi(T) BinNode<T>::insertAsLC(T const& e) { return lc = new BinNode(e, this); } template <typename T> BinNodePosi(T) BinNode<T>::insertAsRC(T const& e) { return rc = new BinNode(e, this); } //定位节点V的直接后继(中序遍历序列) template <typename T> BinNodePosi(T) BinNode<T>::succ(){ //定位节点v的直接后继 BinNodePosi(T) s = this; //记录后继的临时变量 if (rc) { //若有右孩子,则直接后继必在右子树中,具体的就是 s = rc; //右子树中 while (HasLChild(*s)) { s = s -> lc; //最靠左最小的节点 } }else{ //否则,直接后继应该是"将当前节点包含于其左子树中的最低祖先",具体地就是 while (IsRChild(*s)) { s = s -> parent; //逆向地沿右向分支,不断朝左上方移动 } s = s -> parent; //最后再朝右上方移动一步,即抵达直接后继(如果存在) } return s; } template <typename T> template <typename VST> void BinNode<T>::travLevel(VST&visit){ //子树层次遍历 Queue<BinNodePosi(T)> Q; Q.enqueue(this); //根节点入队 while (!Q.empty()) { //在队列再次变空之前,反复迭代 BinNodePosi(T) x = Q.dequeue(); visit(x -> data); if (HasLChild(*x)) { Q.enqueue(x -> lc); } if (HasRChild(*x)) { Q.enqueue(x -> rc); } } } template <typename T> template <typename VST> void BinNode<T>::travPre(VST&visit){ //子树先序遍历 travPre_I1(this, visit); } template <typename T> template <typename VST> void BinNode<T>::travIn(VST&visit){ //子树中序遍历 switch ( rand() % 5) { case 1: travIn_I1(this, visit); break; case 2: travIn_I2(this, visit); break; case 3: travIn_I3(this, visit); break; case 4: travIn_I4(this, visit); break; default: travIn_R(this, visit); break; } } template <typename T> template <typename VST> void BinNode<T>::travPost(VST&visit){ //子树后续遍历 travPost_I(this, visit); } #endif /* BinNode_hpp */
BinTree.hpp
#ifndef BinTree_hpp #define BinTree_hpp #include "BinNode.hpp" #include "Stack.hpp" template <typename T> class BinTree { protected: int _size; BinNodePosi(T) _root; virtual int updateHeight(BinNodePosi(T) x); //更新节点x的高度 void updateHeightAbove(BinNodePosi(T) x); //更新节点x及其祖先的高度 public: BinTree() : _size(0),_root(NULL){} ~BinTree() { if (0 < _size) { remove(_root); } } int size() const { return _size; } bool empty() const { return !_root; } BinNodePosi(T) root() const { return _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作为右子树插入 int remove(BinNodePosi(T) x); //删除以位置x除节点为根的子树,返回该子树原先的规模 BinTree<T>* secede(BinNodePosi(T) x); //将子树x从当前树中摘除,并将其转换为一棵独立子树 template <typename VST> void travLevel(VST& visit) { if (_root) { _root->travLevel(visit); //层次遍历 } } template <typename VST> void travPre(VST& visit){ if (_root) { _root->travPre(visit); //先序遍历 } } template <typename VST> void travIn(VST& visit){ if (_root) { _root->travIn(visit); //中序遍历 } } template <typename VST> void travPost(VST& visit){ if (_root) { _root->travPost(visit); //后序遍历 } } bool operator< (BinTree<T> const& t) { return _root && t._root && lt(_root, t._root); } bool operator==(BinTree<T> const& t){ return _root && t._root && (_root == t._root); } }; //高度更新 template <typename T> int BinTree<T>::updateHeight(BinNodePosi(T) x){ return x->height = 1 + std::max( stature(x->lc), stature(x->rc) ); } template <typename T> void BinTree<T>::updateHeightAbove(BinNodePosi(T) x){ while (x) { updateHeight(x); x = x->parent; } } //节点插入 template <typename T> BinNodePosi(T) BinTree<T>::insertAsRoot(T const&e){ _size = 1; return _root = new BinNode<T>(e); } template <typename T> BinNodePosi(T) BinTree<T>::insertAsLC(BinNodePosi(T) x, T const &e){ _size++; x->insertAsLC(e); updateHeightAbove(x); return x -> lc; } template <typename T> BinNodePosi(T) BinTree<T>::insertAsRC(BinNodePosi(T) x, T const &e){ _size++; x->insertAsRC(e); updateHeightAbove(x); return x -> rc; } //子树接入 template <typename T> BinNodePosi(T) BinTree<T>::attachAsLC(BinNodePosi(T) x, BinTree<T> *&S) { //二叉树子树接入算法:将S当作节点x的左子树接入,S本身置空 if ((x -> lc = S -> _root)) { x -> lc -> parent = x; } _size += S -> _size; updateHeightAbove(x); S->_root = NULL; S->_size = 0; // release(S); delete S; S = NULL; return x; } template <typename T> BinNodePosi(T) BinTree<T>::attachAsRC(BinNodePosi(T) x, BinTree<T> *&S) { if ((x -> rc = S -> _root)) { x -> rc -> parent = x; } _size += S -> _size; updateHeightAbove(x); S -> _root = NULL; S -> _size = 0; // release(S); delete S; S = NULL; return x; } //子树删除 template <typename T> int BinTree<T>::remove(BinNodePosi(T) x){ //assert: x为二叉树中的合法位置 FromParentTo(*x, this->_root) = NULL; //切断来自父节点的指针 updateHeightAbove(x->parent); //更新祖先高度 int n = removeAt(x); _size -= n; return n; } //删除二叉树中位置x处的节点及其后代,返回被删除节点的数值 template <typename T> static int removeAt(BinNodePosi(T) x){ if (!x) { return 0; } int n = 1 + removeAt(x -> lc) + removeAt(x -> rc); // release(x -> data); // release(x); x -> data = NULL; delete x; return n; } //子树分离 //将子树x从当前树中摘除,将其封装为一棵独立子树返回 template <typename T> BinTree<T>* BinTree<T>::secede(BinNodePosi(T) x){ //assert: x为二叉树中的合法位置 FromParentTo(*x, this->_root) = NULL; updateHeightAbove(x -> parent); BinTree<T>* S = new BinTree<T>; S -> _root = x; x -> parent = NULL; S -> _size = x -> size(); _size -= S -> _size; return S; } //遍历 //1.递归式遍历 //1.1 先序遍历 template <typename T,typename VST> void travPre_R(BinNodePosi(T) x, VST& visit) { if (!x) { return; } visit(x -> data); travPre_R(x -> lc, visit); travPre_R(x -> rc, visit); } //1.2 后序遍历 template <typename T,typename VST> void travPost_R(BinNodePosi(T) x,VST& visit) { if (!x) { return; } travPost_R(x -> lc, visit); travPost_R(x -> rc, visit); visit(x -> data); } //1.3 中序遍历 template <typename T,typename VST> void travIn_R(BinNodePosi(T) x, VST& visit){ if (!x) { return; } travIn_R(x -> lc, visit); visit(x -> data); travIn_R(x -> rc, visit); } //2.迭代式遍历 //2.1 先序遍历 template <typename T,typename VST> void travPre_I1(BinNodePosi(T) x,VST& visit){ Stack<BinNodePosi(T)> S; if (x) { S.push(x); } while (!S.empty()) { x = S.pop(); visit(x -> data); if (HasRChild(*x)) { S.push(x -> rc); } if (HasLChild(*x)) { S.push(x -> lc); } } } //从当前节点出发,沿左分支不断深入,直至没有左分支的节点;沿途节点遇到后立即访问 template <typename T,typename VST> static void visitAlongLeftBranch(BinNodePosi(T) x,VST& visit,Stack<BinNodePosi(T)>& S) { while (x) { visit(x->data); S.push(x -> rc); x = x->lc; } } template <typename T,typename VST> void trav_Pre_I2(BinNodePosi(T) x,VST& visit) { Stack<BinNodePosi(T)> S; //辅助栈 while (true) { visitAlongLeftBranch(x, visit, S); if (S.empty()) { break; } x = S.pop(); } } //2.2 中序遍历 template <typename T> static void goAlongLeftBranch(BinNodePosi(T) x,Stack<BinNodePosi(T)>& S) { while (x) { S.push(x); x = x -> lc; } } template <typename T,typename VST> void travIn_I1(BinNodePosi(T) x,VST& visit) { Stack<BinNodePosi(T)> S; while (true) { goAlongLeftBranch(x, S); if (S.empty()) { break; } x = S.pop(); visit(x -> data); x = x -> rc; //转向右子树 } } template <typename T,typename VST> void travIn_I2(BinNodePosi(T) x,VST& visit){ Stack<BinNodePosi(T)> S; while (true) { if (x) { S.push(x); x = x -> lc; }else if(!S.empty()) { x = S.pop(); visit(x -> data); x = x -> rc; }else{ break; } } } template <typename T,typename VST> void travIn_I3(BinNodePosi(T) x,VST& visit){ bool backtrack = false; //前一步是否刚从右子树回溯----省去栈,仅σ(1)辅助空间 while (true) { if (!backtrack && HasLChild(*x)) { //若有左子树且不是刚刚回溯,则深入遍历左子树 x = x -> lc; }else{ //否则----无左子树或刚刚回溯(相当于无左子树) visit(x -> data); if (HasRChild(*x)) { //若其右子树非空,则深入右子树继续遍历,并关闭回溯标志 x = x -> rc; backtrack = false; }else{ //若右子树为空,则回溯 if (! (x = x -> succ())) { break; } backtrack = true; } } } } //继续改进 template <typename T,typename VST> void travIn_I4(BinNodePosi(T) x,VST& visit) { while (true) { if (HasLChild(*x)) { //若有左子树,则深入遍历左子树 x = x -> lc; }else{ visit(x -> data); //访问当前节点,并 while (!HasRChild(*x)) { //不断的在无右分支处,回溯至直接后继(在没有后继的末节点处,直接退出) if (! (x = x->succ())) { return; }else{ visit(x -> data); } } //(直至有右分支处)转向非空的右子树 x = x -> rc; } } } //2.3 后序遍历 //在以S栈顶节点为根的子树中,找到最高左侧可见叶节点 template <typename T> static void gotoHLVFL(Stack<BinNodePosi(T)>& S) { //沿途所遇节点依次入栈 while (BinNodePosi(T) x = S.top()) { //自顶向下,反复检查当前节点(即栈顶) if (HasLChild(*x)) { //尽可能向左 if (HasRChild(*x)) { S.push(x -> rc);//若有右孩子,优先入栈 } S.push(x -> lc);//然后才转至左孩子 }else{ //实不得已 S.push(x -> rc); //才向右 } } S.pop(); //返回之前,弹出栈顶的空节点 } template <typename T,typename VST> void travPost_I(BinNodePosi(T) x,VST& visit){ //二叉树的后序遍历(迭代版) Stack<BinNodePosi(T)> S; //辅助栈 if (x) { S.push(x); //根节点入栈 } while (!S.empty()) { if (S.top() != x -> parent) { //若栈顶非当前节点之父(则必为其右兄),此时需 gotoHLVFL(S); //在以其右兄为根之子树中,找到HLVFL } x = S.pop(); visit(x -> data); //弹出栈顶(即前一节点之后继),并访问之 } } #endif /* BinTree_hpp */
标签:asc false 递归 接口 eve ted red stack 入栈
原文地址:https://www.cnblogs.com/gkp307/p/9621050.html