AVL平衡二叉树(二)

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

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/jkay_wong/article/details/6905396
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞