加入收藏 | 设为首页 | 会员中心 | 我要投稿 大同站长网 (https://www.0352zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

C++模板达成的AVL树

发布时间:2021-11-19 17:46:30 所属栏目:教程 来源:互联网
导读:根据宁德站长网 Www.0593Zz.Com报道 1 AVL树的定义 AVL树是一种自平衡二叉排序树,它的特点是任何一个节点的左子树高度和右子树的高度差在-1,0,1三者之间。AVL树的任何一个子树都是AVL树。 2 AVL树的实现 AVL树本质是一种二叉排序树,所以二叉排序树的任何性
 
根据宁德站长网 Www.0593Zz.Com报道

1 AVL树的定义
 
AVL树是一种自平衡二叉排序树,它的特点是任何一个节点的左子树高度和右子树的高度差在-1,0,1三者之间。AVL树的任何一个子树都是AVL树。
 
2 AVL树的实现
 
AVL树本质是一种二叉排序树,所以二叉排序树的任何性质AVL树都具有,但是AVL树稍微复杂的地方就是AVL树必须满足平衡条件,具体跟BST不同的地方主要体现在插入,删除操作。
 
插入操作:当插入之后可能会出现不平衡,所以这时候要通过旋转树来实现平衡。旋转有四种类型,左左,左右,右左,右右。其中左左旋转和右右旋转是镜像的,左右旋转和右左旋转是镜像的,所以实质上就是两种类型的旋转。针对左左旋转,只需要旋转一次即可,针对左右旋转,需要执行两次旋转。见下图:
 
 
 
这里采用递归法实现插入和删除操作。使用递归方便的一点是如果函数的参数是引用类型的,当传入一个p->left的时候,我们在当前函数的下层递归的时候,对p进行的赋值操作其实就是对上层递归中的p->left进行的操作,所以这样就不需要传递父指针了。
 
3 实现代码
 
//AVLTree.h
 
#ifndef DDXX_AVLTREE_H
#define DDXX_AVLTREE_H
#include <iostream>
#include <queue>
using namespace std;
template<typename Type>
class AVLTree
{
 struct Node
 {
  Type e;
  Node* left;
  Node* right;
  int h;
  Node(Type _e):e(_e),left(NULL),right(NULL),h(0){}
  Node(Type _e,Node* _left,Node* _right,int _h):e(e),left(_left),right(_right),h(_h){}
 };
public:
 AVLTree();
 AVLTree(Type arr[],int nLength);
 /*AVLTree(const AVLTree& right);
 AVLTree& operator=(const AVLTree& right);*/
 ~AVLTree();
public:
 bool insert(Type e,Node* &p);
 void erase(Type e,Node* &p);
 Node*& find(Type e)const;
 void traverse(Node* p)const;
 void traverseByLevel(Node* p)const;
 int  getLength(){return mLength;}
 Node*& getParent(Node* p);
 Node*& getRoot(){return mRoot;} //notice the return type
 bool empty(){return mRoot==NULL;};
 void clear();
 void clears(Node* &p);
private:
 void rotateLeft(Node* &k2);
 void rotateRight(Node* &k2);
 void rotateLeftDouble(Node* &p);
 void rotateRightDouble(Node* &p);
 int  height(Node* p)const{ return p == NULL ? -1 : p->h ;}
 int  max(int x,int y){return x>y?x:y;}
private:
 Node* mRoot;
 int mLength;
 
};
template<typename Type> AVLTree<Type>::AVLTree():mRoot(NULL),mLength(0)
{
}
 
template<typename Type> AVLTree<Type>::AVLTree(Type arr[],int nLength):mRoot(NULL),mLength(0)
{
 for(int i=0;i<nLength;i++)
 {
  insert(arr[i],mRoot);
 }
}
 
template<typename Type> AVLTree<Type>::~AVLTree()
{
 clears(mRoot);
}
template<typename Type> bool AVLTree<Type>::insert(Type e,Node* &p)
{
 if( p== NULL)
 {
  p = new Node(e);
  mLength++;
 }
 else if(e < p->e)
 {
  insert(e,p->left);
  if( height(p->left) - height(p->right) == 2)
  {
   if (e < p->left->e)
    rotateLeft(p);
   else
    rotateLeftDouble(p);
  }
 }
 else if(e > p->e)
 {
  insert(e,p->right);
  if( height(p->left) - height(p->right) == -2)
  {
   if (e > p->right->e)
    rotateRight(p);
   else
    rotateRightDouble(p);
  }
 }
 else // e ia already exist
 {
  //return false;
 }
 p->h = max( height(p->left),height(p->right) )+1;
 return true;
}
 
template<typename Type> void AVLTree<Type>::rotateLeft(Node*& k2)
{
 Node* k1 = k2->left;
 k2->left = k1->right;
 k1->right = k2;
 
 k1->h = max( height(k1->left),height(k1->right) ) + 1;
 k2->h = max( height(k2->left),height(k2->right) ) + 1;
 k2 = k1;// join the original node
}
 
template<typename Type> void AVLTree<Type>::rotateRight(Node* &k2)
{
 Node* k1 = k2->right;
 k2->right = k1->left;
 k1->left = k2;
 
 k1->h = max( height(k1->left),height(k1->right) ) + 1;
 k2->h = max( height(k2->left),height(k2->right) ) + 1;
 //k1=k2,因为在insert函数中传入的是p->left或者p->right的引用,所以这里能把根结点赋给其父结点的子节点
 k2 = k1;
}
 
template<typename Type> void AVLTree<Type>::rotateLeftDouble(Node*& k3)
{
 rotateRight(k3->left);
 rotateLeft(k3);
}
template<typename Type> void AVLTree<Type>::rotateRightDouble(Node*& k3)
{
 rotateLeft(k3->right);
 rotateRight(k3);
}
 
template<typename Type> void AVLTree<Type>::traverse(Node* p)const
{
 if( p == NULL)
  return;
 else
 {
  traverse(p->left);
  cout<<"element:"<<p->e<<endl; //traverse by mid
  traverse(p->right);
 }
}
 
template<typename Type> void AVLTree<Type>::traverseByLevel(Node* root)const
{
 if(root == NULL)
 {
  cout<<"The tree is empty"<<endl;
  return;
 }
 queue<Node*> que;
 que.push(root);
 while( !que.empty() )
 {
  Node* ptr = que.front();
  que.pop();
  cout<<"element:"<<ptr->e<<" th:"<<height(ptr->left) - height(ptr->right)<<endl;
  if(ptr->left != NULL)
   que.push(ptr->left);
  if(ptr->right != NULL)
   que.push(ptr->right);
 }
}
 
template<typename Type> typename AVLTree<Type>::Node* & AVLTree<Type>::getParent(Node* p)
{
    if( p == m_root)
        return NULL;
    Node* ptr = m_root;
    Node* ptf = ptr;
    while( ptr != NULL )
    {
        if ( ptr->e == p->e )
            return ptf;
        if ( ptr->e > p->e )
        {
            ptf = ptr;
            ptr = ptr->leftChild;
        }
        else
        {
            ptf = ptr;
            ptr = ptr->rightChild;
        }
    }
}
 
template<typename Type> typename AVLTree<Type>::Node*& AVLTree<Type>::find(Type e)const
{
    Node* ptr = m_root;
 
    while(ptr != NULL)
    {
        if ( ptr->e == e )
            return ptr;
        if ( ptr->e > e )
            ptr = ptr->leftChild;
        else
            ptr = ptr->rightChild;
    }
    //if ( ptr == NULL )
    return NULL;
}
 
template<typename Type> void AVLTree<Type>::clears(Node*& p)
{
 if( p == NULL )
  return;
 else
 {
  clears(p->left);
  clears(p->right);
  delete p;
  p = NULL;
  mLength--;
 }
}
 
template<typename Type> void AVLTree<Type>::clear()
{
 clears(mRoot);
}
 
template<typename Type> void AVLTree<Type>::erase(Type e,Node* &p)
{
 if( p == NULL)
  return;
 if( e > p->e)
 {
  erase(e,p->right);
  if( height(p->left) - height(p->right) == 2)
  {
   if( height(p->left->left) > height(p->left->right) )
    rotateLeft(p);
   else
    rotateLeftDouble(p);
  }
 }
 else if( e < p->e)
 {
  erase(e,p->left);
  if( height(p->left) - height(p->right) == -2)
  {
   if( height(p->right->right) > height(p->right->left) )
    rotateRight(p);
   else
    rotateRightDouble(p);
  }
 }
 else if ( e == p->e && p->left!= NULL && p->right!= NULL)
 {
  Node* pmax = p->left;
  while( pmax->right != NULL)
  {
   pmax = pmax->right;
  }
  p->e = pmax->e;
  erase(p->e,p->left);
 }
 else //最终的删除会在这里执行
 {
  Node* pNew = p->left==NULL ? p->right : p->left;
  delete p;
  p = pNew;
  mLength--;
 }
 if ( p!=NULL)
  p->h = max( height(p->left),height(p->right)) + 1;
}
#endif
 
//main.cpp
 
#include <iostream>
#include "AVLTree.h"
using namespace std;
 
void main()
{
 int Arr[9] = {6,2,8,4,10,0,12,16,14};
 AVLTree<int> Tr(Arr,9);
 Tr.traverse(Tr.getRoot());
 Tr.traverseByLevel(Tr.getRoot());
 
 Tr.erase(14,Tr.getRoot());
 Tr.traverse(Tr.getRoot());
 Tr.traverseByLevel(Tr.getRoot());
 cout<<"Tree's length is:"<<Tr.getLength()<<endl;
 Tr.clear();
 cout<<"Tree's length is:"<<Tr.getLength()<<endl;
 
}

(编辑:大同站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!