这是之前的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;
}