这是之前的AVL平衡二叉树的一个实现代码
点击打开链接
下面是看另一本书的实现的 没有了一重重的switch{case...},理解上不太一样,我觉得两种都可以。
//"avltree.h" class AVL_Tree; class AVLNode { friend AVL_Tree; public: AVLNode() {LeftChild = RightChild = 0;} AVLNode(const int& e) {data = e; bf = 0; LeftChild = RightChild = 0;} private: int data; int bf; // balance factor AVLNode *LeftChild; // left subtree AVLNode *RightChild; // right subtree }; class AVL_Tree { public: AVL_Tree() { root = 0; } ~AVL_Tree() { Erase(root); } bool Search(const int& k,AVLNode *&f,AVLNode *&p) const; AVL_Tree& Insert(const int& e); AVL_Tree& Delete(const int& k, int& e); void InOut() { InOutput(root); } void PostOut() { PostOutput(root); } private: AVLNode *root; // root node void Erase(AVLNode *t); void InOutput(AVLNode *t); void PostOutput(AVLNode *t); void FixBF(AVLNode *,AVLNode*, const int&); void RRrotate(AVLNode *,AVLNode*, AVLNode *); void LLrotate(AVLNode *,AVLNode*, AVLNode *); void RLrotate(AVLNode *,AVLNode*, AVLNode *); void LRrotate(AVLNode *,AVLNode*, AVLNode *); };
//"avltree.cpp" #include "avltree.h" #include <iostream> #include <stack> using namespace std; void AVL_Tree::Erase(AVLNode *t) {// Delete all nodes in AVL tree with root t. // Use a postorder traversal. if (t) {Erase(t->LeftChild); Erase(t->RightChild); delete t; } } bool AVL_Tree::Search(const int& k,AVLNode *&f,AVLNode *&p) const {// Search for element that matches k. // pointer p starts at the root and moves through // the tree looking for an element with key k p = root; while (p) // examine p->data { if (k < p->data) { f=p; p = p->LeftChild; } else if (k > p->data) { f=p; p = p->RightChild; } else {// found element return true; } } return false; } void AVL_Tree::FixBF(AVLNode *q,AVLNode *r, const int &e) {// Balance factors from q to r were originally 0. // They need to be changed to +1 or -1. // Use e to find path from q to r. while (q != r) if (e < q->data) { // height of left subtree has increased q->bf = 1; q = q->LeftChild;} else { // height of right subtree has increased q->bf = -1; q = q->RightChild; } } void AVL_Tree::LLrotate(AVLNode *PA,AVLNode *A, AVLNode *B) {// LL rotation around A. PA is parent of A // and B left child of A. // restructure subtree at A A->LeftChild = B->RightChild; B->RightChild = A; if (PA) // A is not the root { if (A == PA->LeftChild) PA->LeftChild = B; else PA->RightChild = B; } else root = B; // set balance factors A->bf = B->bf = 0; } void AVL_Tree::RRrotate(AVLNode *PA,AVLNode *A, AVLNode *B) {// RR rotation around A. PA is parent of A // and B right child of A. // restructure subtree at A A->RightChild = B->LeftChild; B->LeftChild = A; if (PA) // A is not the root { if (A == PA->LeftChild) PA->LeftChild = B; else PA->RightChild = B; } else root = B; // set balance factors A->bf = B->bf = 0; } void AVL_Tree::LRrotate(AVLNode *PA,AVLNode *A, AVLNode *B) {// LR rotation around A. PA is parent of A // and B left child of A. AVLNode *C = B->RightChild; // restructure subtree at A A->LeftChild = C->RightChild; B->RightChild = C->LeftChild; C->LeftChild = B; C->RightChild = A; if (PA) // A is not the root { if (A == PA->LeftChild) PA->LeftChild = C; else PA->RightChild = C; } else root = C; // set balance factors 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; } void AVL_Tree::RLrotate(AVLNode *PA,AVLNode *A, AVLNode *B) {// RL rotation around A. PA is parent of A // and B left child of A. AVLNode *C = B->LeftChild; // restructure subtree at A A->RightChild = C->LeftChild; B->LeftChild = C->RightChild; C->LeftChild = A; C->RightChild = B; if (PA) // A is not the root { if (A == PA->LeftChild) PA->LeftChild = C; else PA->RightChild = C; } else root = C; // set balance factors 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; } AVL_Tree& AVL_Tree::Insert(const int& e) {// Insert e if not duplicate. AVLNode *p = root, // search pointer *pp = 0, // parent of p *A = 0, // node with bf != 0 *PA; // parent of A // find place to insert // also record most recent node with bf != 0 // in A and its parent in PA while (p) {// examine p->data if (p->bf) {// new candidate for A node A = p; PA = pp; } pp = p; // move p to a child if (e < p->data) p = p->LeftChild; else if (e > p->data) p = p->RightChild; else cout<<"与该值相等的元素已存在"<<endl; } // get a node for e and attach to pp AVLNode *r = new AVLNode(e); if (root) {// tree not empty if (e < pp->data) pp->LeftChild = r; else pp->RightChild = r; } else {// insertion into empty tree root = r; return *this; } // see if we must rebalance or simply change // balance factors if (A) // possible rebalancing needed { if (A->bf < 0) // bf = -1 before insertion { if (e < A->data) {// insertion in left subtree // height of left subtree has increased by 1 // new bf of A is 0, no rebalancing A->bf = 0; // fix bf on path from A to r FixBF(A->LeftChild,r,e); } else {// insertion in right subtree // bf of A is -2, rebalance AVLNode *B = A->RightChild; if (e > B->data) {// RR case FixBF(B->RightChild,r,e); RRrotate(PA,A,B);} else {// RL case FixBF(B->LeftChild,r,e); RLrotate(PA,A,B); } } } else // bf = 1 before insertion { if (e > A->data) {// insertion in right subtree // height of right subtree has increased by 1 // new bf of A is 0, no rebalancing A->bf = 0; // fix bf on path from A to r FixBF(A->RightChild,r,e); } else {// insertion in left subtree // bf of A is +2, rebalance AVLNode *B = A->LeftChild; if (e < B->data) {// LL case FixBF(B->LeftChild,r,e); LLrotate(PA,A,B); } else {// LR case FixBF(B->RightChild,r,e); LRrotate(PA,A,B); } } } } else // A is NULL, no rebalancing FixBF(root,r,e); return *this; } AVL_Tree& AVL_Tree::Delete(const int& k, int& e) {// Delete element with key k and put it in e. // Throw BadInput exception if there is no element // with key k. // define a stack to hold path taken from root // to physically deleted node // we will not run out of stack space unless // the number of elements is much more than 2^60 stack<AVLNode *> st; // set p to point to node with key k AVLNode *p = root; // search pointer while (p && p->data != k) {// move to a child of p st.push(p); if (k < p->data) p = p->LeftChild; else p = p->RightChild; } if (!p) { cout<<"要删除的值不存在"<<endl; // no element with key k return *this; } e = p->data; // save element to delete // restructure tree // handle case when p has two children if (p->LeftChild && p->RightChild) {// two children // convert to zero or one child case // find largest element in left subtree of p st.push(p); AVLNode *s = p->LeftChild; while (s->RightChild) {// move to larger element st.push(s); s = s->RightChild; } // move largest from s to p p->data = s->data; p = s; } // p has at most one child // save child pointer in c AVLNode *c; if (p->LeftChild) c = p->LeftChild; else c = p->RightChild; // delete p if (p == root) root = c; else {// is p a left or right child? if(p == st.top()->LeftChild) st.top()->LeftChild = c; else st.top()->RightChild = c; } int f = p->data; // f may not equal e delete p; // rebalance tree and correct balance factors // use stack to retrace path to root // set q to parent of deleted node AVLNode *q; if(!st.empty()) { q=st.top(); st.pop(); } else return *this; //根节点被删 while (q) { if (f <= q->data) { // deleted from left subtree of q // height of left subtree reduced by 1 q->bf--; if (q->bf == -1) // height of q is unchanged return *this; // nothing more to do if (q->bf == -2) {// q is unbalanced // classify imbalance and rotate AVLNode *B = q->RightChild, *PA; // q is A node // PA is parent of A if(!st.empty()) { PA=st.top(); st.pop(); } else PA=0; // A is root switch (B->bf) { case 0: // L0 imbalance RRrotate(PA,q,B); B->bf = 1; q->bf = -1; // q is A node return *this; case 1: // L1 imbalance RLrotate(PA,q,B); break; // must continue on path to root case -1: // L-1 imbalance RRrotate(PA,q,B); } q = PA; } else {// q->bf is 0 if(!st.empty()) { q=st.top(); st.pop(); } else return *this; } } else {// f > q->data // deleted from right subtree of q // height of right subtree reduced by 1 q->bf++; if (q->bf == 1) // height of q is unchanged // nothing more to do return *this; if (q->bf == 2) {// q is unbalanced // classify imbalance and rotate AVLNode *B = q->LeftChild, *PA; // q is A node // PA is parent of A if(!st.empty()) { PA=st.top(); st.pop(); } else PA=0; // A is root switch (B->bf) { case 0: // R0 imbalance LLrotate(PA,q,B); B->bf = -1; q->bf = 1; // q is A node return *this; case 1: // R1 imbalance LLrotate(PA,q,B); break; // must continue on path to root case -1: // R-1 imbalance LRrotate(PA,q,B); } q = PA; } else {// q->bf is 0 if(!st.empty()) { q=st.top(); st.pop(); } else return *this; } } } return *this; } void AVL_Tree::InOutput(AVLNode *t) {// Output in ascending order. // Use an inorder traversal. if (t) { InOutput(t->LeftChild); cout << t->data << " "; InOutput(t->RightChild); } } void AVL_Tree::PostOutput(AVLNode *t) {// Output in postorder. if (t) { PostOutput(t->LeftChild); PostOutput(t->RightChild); cout << t->data << " "; } }
#include "avltree.h" #include <iostream> using namespace std; int main() { AVL_Tree tree; int a[6]={12,43,54,1,21,3}; for(int i=0;i<6;i++) tree.Insert(a[i]); tree.InOut(); cout<<endl; tree.PostOut(); cout<<endl; int e; tree.Delete(43,e); tree.InOut(); cout<<endl; return 0; }