AVLTree - 二叉平衡树的实现之一(C++)

 

 

template<class E, class K> class AVLtree { public: AVLtree() {root = 0;} ~AVLtree() {Erase(root);} bool Search(const K& k, E& e) const; AVLtree<E,K>& Insert(const E& e); AVLtree<E,K>& Delete(const K& k, E& e); void Ascend() {InOutput(root); cout << endl;} void PostOut() {PostOutput(root); cout << endl;} private: AVLNode<E,K> *root; void Erase(AVLNode<E,K> *t); void InOutput(AVLNode<E,K> *t); void PostOutput(AVLNode<E,K> *t); void FixBF(AVLNode<E,K> *, AVLNode<E,K>*, const E&); void RRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *); void LLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *); void RLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *); void LRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *); }; template<class E, class K> void AVLtree<E,K>::Erase(AVLNode<E,K> *t) { //用前序遍历的方式删除所有节点 if (t) { Erase(t->LeftChild); Erase(t->RightChild); delete t; } } template<class E, class K> bool AVLtree<E,K>::Search(const K& k, E &e) const { AVLNode<E,K> *p = root; while (p) { if (k < p->data) p = p->LeftChild; else if (k > p->data) p = p->RightChild; else { e = p->data; return true; } } return false; } template<class E, class K> void AVLtree<E,K>::FixBF(AVLNode<E,K> *q, AVLNode<E,K> *r, const E &e) { //从q到r的平衡因子通常为0 //根据实际情况改变成 +1 或 -1 while (q != r) { if (e < q->data) { q->bf = 1; q = q->LeftChild; } else { q->bf = -1; q = q->RightChild; } } } template<class E, class K> void AVLtree<E,K>::LLrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B) { //LL型的旋转 A->LeftChild = B->RightChild; B->RightChild = A; if (PA) // A 是否有父节点 { if (A == PA->LeftChild) PA->LeftChild = B; else PA->RightChild = B; } else { root = B; } //设置平衡因子 A->bf = B->bf = 0; } template<class E, class K> void AVLtree<E,K>::RRrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B) { //RR型的旋转 A->RightChild = B->LeftChild; B->LeftChild = A; if (PA) // A 是否有父节点 { if (A == PA->LeftChild) PA->LeftChild = B; else PA->RightChild = B; } else { root = B; } //设置平衡因子 A->bf = B->bf = 0; } template<class E, class K> void AVLtree<E,K>::LRrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B) { //LR型的旋转 AVLNode<E,K> *C = B->RightChild; A->LeftChild = C->RightChild; B->RightChild = C->LeftChild; C->LeftChild = B; C->RightChild = A; if (PA) // A 是否有父节点 { if (A == PA->LeftChild) PA->LeftChild = C; else PA->RightChild = C; } else { root = C; } //设置平衡因子 int b = C->bf; if (b == 1) { B->bf = 0; A->bf = -1; } else if (b == -1) { B->bf = 1; A->bf = 0; } else // b = 0 { B->bf = A->bf = 0; } C->bf = 0; } template<class E, class K> void AVLtree<E,K>::RLrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B) { //RL型的旋转 AVLNode<E,K> *C = B->LeftChild; A->RightChild = C->LeftChild; B->LeftChild = C->RightChild; C->LeftChild = A; C->RightChild = B; if (PA) // A 是否有父节点 { if (A == PA->LeftChild) PA->LeftChild = C; else PA->RightChild = C; } else { root = C; } //设置平衡因子 int b = C->bf; if (b == 1) { B->bf = -1; A->bf = 0; } else if (b == -1) { B->bf = 0; A->bf = 1; } else // b = 0 { B->bf = A->bf = 0; } C->bf = 0; } template<class E, class K> AVLtree<E,K>& AVLtree<E,K>::Insert(const E& e) { AVLNode<E,K> *p = root, *pp = 0, // p的父节点 *A = 0, // 平衡因子不为0 的最后一个节点 *PA; // A的父节点 //找到可以插入的地方 //同时记录最后一个平衡因子不为0的节点及其父节点 while (p) { if (p->bf) { A = p; PA = pp; } pp = p; // 将p移向子节点 if (e < p->data) p = p->LeftChild; else if (e > p->data) p = p->RightChild; else throw BadInput(); /*if(e <= p->data) p = p->LeftChild; else p = p->RightChild;*/ } AVLNode<E,K> *r = new AVLNode<E,K> (e); if (root) { if (e < pp->data) pp->LeftChild = r; else pp->RightChild = r; } else { root = r; return *this; } //查看是否需要再平衡,还是只是简单的刷新下平衡因子 if(A) { if (A->bf < 0) // bf = -1 在插入前 { if (e < A->data) { //插入到A的左子树,左子树高度加1 //A新的平衡因子等于0, 不需要再平衡 A->bf = 0; //刷新下从A到r的平衡因子 FixBF(A->LeftChild,r,e); } else { //插入到A的右子树 //A的平衡因子为-2, 需要再平衡 AVLNode<E,K> *B = A->RightChild; if (e > B->data) { // RR型 FixBF(B->RightChild,r,e); RRrotate(PA,A,B); } else { // RL型 FixBF(B->LeftChild,r,e); RLrotate(PA,A,B); } } } else // bf = +1 在插入前 { if (e > A->data) { //插入到A的右子树,右子树高度加1 //A新的平衡因子等于0, 不需要再平衡 A->bf = 0; //刷新下从A到r的平衡因子 FixBF(A->RightChild,r,e); } else { //插入到A的左子树 //A的平衡因子为+2, 需要再平衡 AVLNode<E,K> *B = A->LeftChild; if (e < B->data) { // LL型 FixBF(B->LeftChild,r,e); LLrotate(PA,A,B); } else { // LR型 FixBF(B->RightChild,r,e); LRrotate(PA,A,B); } } } } else // A一直为0, 不需要再平衡 { //刷新下从root到r的平衡因子 FixBF(root,r,e); } return *this; } template<class E, class K> AVLtree<E,K>& AVLtree<E,K>::Delete(const K& k, E& e) { // 如果元素数量超过2^60, S栈将会溢出 Stack<AVLNode<E,K>*> S(100); AVLNode<E,K> *p = root; while (p && p->data != k) { S.Add(p); if (k < p->data) p = p->LeftChild; else p = p->RightChild; } if (!p) throw BadInput(); e = p->data; //p有两个子树的情况 if (p->LeftChild && p->RightChild) { //查找p左子树里元素值最大的节点 S.Add(p); AVLNode<E,K> *s = p->LeftChild; while (s->RightChild) { S.Add(s); s = s->RightChild; } //将p左子树里元素值最大的节点等于p p->data = s->data; p = s; } //只有一个子树的情况 AVLNode<E,K> *c; if (p->LeftChild) c = p->LeftChild; else c = p->RightChild; if (p == root) { root = c; } else { if (p == S.Top()->LeftChild) S.Top()->LeftChild = c; else S.Top()->RightChild = c; } E f = p->data; //f也许不等于e delete p; AVLNode<E,K> *q; try { S.Delete(q); } catch (OutOfBounds) { //根节点被删除了 return *this; } while (q) { if (f <= q->data) { //从q的左子树删除的 q->bf--; //高度并未发生改变, 不需要再做什么 if (q->bf == -1) return *this; if (q->bf == -2) { //树变得不平衡了, 需要旋转 AVLNode<E,K> *B = q->RightChild, *PA; // q就是A节点 // PA是A的父节点 try { S.Delete(PA); } catch (OutOfBounds) { //说明A是根节点 PA = 0; } switch (B->bf) { case 0: // L0型 RRrotate(PA,q,B); B->bf = 1; q->bf = -1; return *this; case 1: // L1型 RLrotate(PA,q,B); break; case -1:// L-1型 RRrotate(PA,q,B); break; } q = PA; } else // q->bf == 0 { try { S.Delete(q); } catch (OutOfBounds) { return *this; } } } else { //从q的右子树删除的 q->bf++; //高度并未发生改变, 不需要再做什么 if (q->bf == 1) return *this; if (q->bf == 2) { //树变得不平衡了, 需要旋转 AVLNode<E,K> *B = q->LeftChild, *PA; // q就是A节点 // PA是A的父节点 try { S.Delete(PA); } catch (OutOfBounds) { //说明A是根节点 PA = 0; } switch (B->bf) { case 0: // R0型 LLrotate(PA,q,B); B->bf = -1; q->bf = 1; return *this; case 1: // R1型 LLrotate(PA,q,B); break; case -1: // R-1 型 LRrotate(PA,q,B); break; } q = PA; } else // q->bf == 0 { try { S.Delete(q); } catch (OutOfBounds) { return *this; } } } } return *this; } template<class E, class K> void AVLtree<E,K>::InOutput(AVLNode<E,K> *t) { if(t) { InOutput(t->LeftChild); cout << t->data << " "; InOutput(t->RightChild); } } template<class E, class K> void AVLtree<E,K>::PostOutput(AVLNode<E,K> *t) { if(t) { PostOutput(t->LeftChild); PostOutput(t->RightChild); cout << t->data << " "; } }

 

#ifndef AVLNode_ #define AVLNode_ template <class E, class K> class AVLtree; template <class E, class K> class AVLtree2; template <class E, class K> class DAVLtree; template <class E, class K> class AVLNode { friend AVLtree<E,K>; friend AVLtree2<E,K>; friend DAVLtree<E,K>; public: AVLNode() {LeftChild = RightChild = 0;} AVLNode(const E& e){data = e; bf = 0; LeftChild = RightChild = 0; height = 0; } private: E data; int bf; int height; AVLNode<E,K> *LeftChild, *RightChild; }; #endif

 

stack:

template<class T> class Stack { public: Stack(int MaxStackSize = 10); ~Stack() {delete [] stack;} bool IsEmpty() const {return top == -1;} bool IsFull() const {return top == MaxTop;} T Top() const; Stack<T>& Add(const T& x); Stack<T>& Delete(T& x); private: int top; int MaxTop; T *stack; }; template<class T> Stack<T>::Stack(int MaxStackSize) { MaxTop = MaxStackSize - 1; stack = new T[MaxStackSize]; top = -1; } template<class T> T Stack<T>::Top() const { if (IsEmpty()) throw OutOfBounds(); return stack[top]; } template<class T> Stack<T>& Stack<T>::Add(const T& x) { if (IsFull()) throw NoMem(); stack[++top] = x; return *this; } template<class T> Stack<T>& Stack<T>::Delete(T& x) { if (IsEmpty()) throw OutOfBounds(); x = stack[top--]; return *this; }

你可能感兴趣的:(C++,c,delete,search,Class,insert)