找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2793|回复: 0

【C++】C++模板实现的AVL树

[复制链接]

33

主题

1

回帖

561

积分

用户组: 大·技术宅

UID
580
精华
26
威望
28 点
宅币
341 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2014-12-8
发表于 2014-12-8 17:49:03 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 0x55AA 于 2014-12-8 17:54 编辑

1 AVL树的定义
AVL树是一种自平衡二叉排序树,它的特点是任何一个节点的左子树高度和右子树的高度差在-1,0,1三者之间。AVL树的任何一个子树都是AVL树。
2 AVL树的实现
AVL树本质是一种二叉排序树,所以二叉排序树的任何性质AVL树都具有,但是AVL树稍微复杂的地方就是AVL树必须满足平衡条件,具体跟BST不同的地方主要体现在插入,删除操作。
插入操作:当插入之后可能会出现不平衡,所以这时候要通过旋转树来实现平衡。旋转有四种类型,左左,左右,右左,右右。其中左左旋转和右右旋转是镜像的,左右旋转和右左旋转是镜像的,所以实质上就是两种类型的旋转。针对左左旋转,只需要旋转一次即可,针对左右旋转,需要执行两次旋转。见下图:
1.png
这里采用递归法实现插入和删除操作。使用递归方便的一点是如果函数的参数是引用类型的,当传入一个p->left的时候,我们在当前函数的下层递归的时候,对p进行的赋值操作其实就是对上层递归中的p->left进行的操作,所以这样就不需要传递父指针了。
3 实现代码
AVLTree.h
  1. //AVLTree.h
  2. #ifndef DDXX_AVLTREE_H
  3. #define DDXX_AVLTREE_H
  4. #include <iostream>
  5. #include <queue>
  6. using namespace std;
  7. template<typename Type>
  8. class AVLTree
  9. {
  10.         struct Node
  11.         {
  12.                 Type e;
  13.                 Node* left;
  14.                 Node* right;
  15.                 int h;
  16.                 Node(Type _e):e(_e),left(NULL),right(NULL),h(0){}
  17.                 Node(Type _e,Node* _left,Node* _right,int _h):e(e),left(_left),right(_right),h(_h){}
  18.         };
  19. public:
  20.         AVLTree();
  21.         AVLTree(Type arr[],int nLength);
  22.         /*AVLTree(const AVLTree& right);
  23.         AVLTree& operator=(const AVLTree& right);*/
  24.         ~AVLTree();
  25. public:
  26.         bool        insert(Type e,Node* &p);
  27.         void        erase(Type e,Node* &p);
  28.         Node*&        find(Type e)const;
  29.         void        traverse(Node* p)const;
  30.         void        traverseByLevel(Node* p)const;
  31.         int                getLength(){return mLength;}
  32.         Node*&        getParent(Node* p);
  33.         Node*&        getRoot(){return mRoot;} //notice the return type
  34.         bool        empty(){return mRoot==NULL;};
  35.         void        clear();
  36.         void        clears(Node* &p);
  37. private:
  38.         void        rotateLeft(Node* &k2);
  39.         void        rotateRight(Node* &k2);
  40.         void        rotateLeftDouble(Node* &p);
  41.         void        rotateRightDouble(Node* &p);
  42.         int                height(Node* p)const{ return p == NULL ? -1 : p->h ;}
  43.         int                max(int x,int y){return x>y?x:y;}
  44. private:
  45.         Node* mRoot;
  46.         int mLength;

  47. };
  48. template<typename Type> AVLTree<Type>::AVLTree():mRoot(NULL),mLength(0)
  49. {
  50. }

  51. template<typename Type> AVLTree<Type>::AVLTree(Type arr[],int nLength):mRoot(NULL),mLength(0)
  52. {
  53.         for(int i=0;i<nLength;i++)
  54.         {
  55.                 insert(arr[i],mRoot);
  56.         }
  57. }

  58. template<typename Type> AVLTree<Type>::~AVLTree()
  59. {
  60.         clears(mRoot);
  61. }
  62. template<typename Type> bool AVLTree<Type>::insert(Type e,Node* &p)
  63. {
  64.         if( p== NULL)
  65.         {
  66.                 p = new Node(e);
  67.                 mLength++;
  68.         }
  69.         else if(e < p->e)
  70.         {
  71.                 insert(e,p->left);
  72.                 if( height(p->left) - height(p->right) == 2)
  73.                 {
  74.                         if (e < p->left->e)
  75.                                 rotateLeft(p);
  76.                         else
  77.                                 rotateLeftDouble(p);
  78.                 }
  79.         }
  80.         else if(e > p->e)
  81.         {
  82.                 insert(e,p->right);
  83.                 if( height(p->left) - height(p->right) == -2)
  84.                 {
  85.                         if (e > p->right->e)
  86.                                 rotateRight(p);
  87.                         else
  88.                                 rotateRightDouble(p);
  89.                 }
  90.         }
  91.         else // e ia already exist
  92.         {       
  93.                 //return false;
  94.         }
  95.         p->h = max( height(p->left),height(p->right) )+1;
  96.         return true;
  97. }

  98. template<typename Type> void AVLTree<Type>::rotateLeft(Node*& k2)
  99. {
  100.         Node* k1 = k2->left;
  101.         k2->left = k1->right;
  102.         k1->right = k2;

  103.         k1->h = max( height(k1->left),height(k1->right) ) + 1;
  104.         k2->h = max( height(k2->left),height(k2->right) ) + 1;
  105.         k2 = k1;// join the original node
  106. }

  107. template<typename Type> void AVLTree<Type>::rotateRight(Node* &k2)
  108. {
  109.         Node* k1 = k2->right;
  110.         k2->right = k1->left;
  111.         k1->left = k2;

  112.         k1->h = max( height(k1->left),height(k1->right) ) + 1;
  113.         k2->h = max( height(k2->left),height(k2->right) ) + 1;
  114.         //k1=k2,因为在insert函数中传入的是p->left或者p->right的引用,所以这里能把根结点赋给其父结点的子节点
  115.         k2 = k1;
  116. }

  117. template<typename Type> void AVLTree<Type>::rotateLeftDouble(Node*& k3)
  118. {
  119.         rotateRight(k3->left);
  120.         rotateLeft(k3);
  121. }
  122. template<typename Type> void AVLTree<Type>::rotateRightDouble(Node*& k3)
  123. {
  124.         rotateLeft(k3->right);
  125.         rotateRight(k3);
  126. }

  127. template<typename Type> void AVLTree<Type>::traverse(Node* p)const
  128. {
  129.         if( p == NULL)
  130.                 return;
  131.         else
  132.         {
  133.                 traverse(p->left);
  134.                 cout<<"element:"<<p->e<<endl; //traverse by mid
  135.                 traverse(p->right);       
  136.         }
  137. }

  138. template<typename Type> void AVLTree<Type>::traverseByLevel(Node* root)const
  139. {
  140.         if(root == NULL)
  141.         {
  142.                 cout<<"The tree is empty"<<endl;
  143.                 return;
  144.         }
  145.         queue<Node*> que;
  146.         que.push(root);
  147.         while( !que.empty() )
  148.         {
  149.                 Node* ptr = que.front();
  150.                 que.pop();
  151.                 cout<<"element:"<<ptr->e<<"        th:"<<height(ptr->left) - height(ptr->right)<<endl;
  152.                 if(ptr->left != NULL)
  153.                         que.push(ptr->left);
  154.                 if(ptr->right != NULL)
  155.                         que.push(ptr->right);
  156.         }
  157. }

  158. template<typename Type> typename AVLTree<Type>::Node* & AVLTree<Type>::getParent(Node* p)
  159. {  
  160.     if( p == m_root)  
  161.         return NULL;  
  162.     Node* ptr = m_root;  
  163.     Node* ptf = ptr;  
  164.     while( ptr != NULL )  
  165.     {  
  166.         if ( ptr->e == p->e )  
  167.             return ptf;  
  168.         if ( ptr->e > p->e )  
  169.         {  
  170.             ptf = ptr;  
  171.             ptr = ptr->leftChild;  
  172.         }  
  173.         else  
  174.         {  
  175.             ptf = ptr;  
  176.             ptr = ptr->rightChild;
  177.         }  
  178.     }   
  179. }

  180. template<typename Type> typename AVLTree<Type>::Node*& AVLTree<Type>::find(Type e)const
  181. {  
  182.     Node* ptr = m_root;  
  183.   
  184.     while(ptr != NULL)  
  185.     {  
  186.         if ( ptr->e == e )  
  187.             return ptr;  
  188.         if ( ptr->e > e )  
  189.             ptr = ptr->leftChild;  
  190.         else  
  191.             ptr = ptr->rightChild;  
  192.     }  
  193.     //if ( ptr == NULL )  
  194.     return NULL;  
  195. }

  196. template<typename Type> void AVLTree<Type>::clears(Node*& p)
  197. {
  198.         if( p == NULL )
  199.                 return;
  200.         else
  201.         {
  202.                 clears(p->left);
  203.                 clears(p->right);
  204.                 delete p;
  205.                 p = NULL;
  206.                 mLength--;
  207.         }
  208. }

  209. template<typename Type> void AVLTree<Type>::clear()
  210. {
  211.         clears(mRoot);
  212. }

  213. template<typename Type> void AVLTree<Type>::erase(Type e,Node* &p)
  214. {
  215.         if( p == NULL)
  216.                 return;
  217.         if( e > p->e)
  218.         {
  219.                 erase(e,p->right);
  220.                 if( height(p->left) - height(p->right) == 2)
  221.                 {
  222.                         if( height(p->left->left) > height(p->left->right) )
  223.                                 rotateLeft(p);
  224.                         else
  225.                                 rotateLeftDouble(p);
  226.                 }
  227.         }
  228.         else if( e < p->e)
  229.         {
  230.                 erase(e,p->left);
  231.                 if( height(p->left) - height(p->right) == -2)
  232.                 {
  233.                         if( height(p->right->right) > height(p->right->left) )
  234.                                 rotateRight(p);
  235.                         else
  236.                                 rotateRightDouble(p);
  237.                 }
  238.         }
  239.         else if ( e == p->e && p->left!= NULL && p->right!= NULL)
  240.         {
  241.                 Node* pmax = p->left;
  242.                 while( pmax->right != NULL)
  243.                 {
  244.                         pmax = pmax->right;
  245.                 }
  246.                 p->e = pmax->e;
  247.                 erase(p->e,p->left);
  248.         }
  249.         else //最终的删除会在这里执行
  250.         {
  251.                 Node* pNew = p->left==NULL ? p->right : p->left;
  252.                 delete p;
  253.                 p = pNew;
  254.                 mLength--;
  255.         }
  256.         if ( p!=NULL)
  257.                 p->h = max( height(p->left),height(p->right)) + 1;
  258. }
  259. #endif
复制代码
main.cpp
  1. //main.cpp
  2. #include <iostream>
  3. #include "AVLTree.h"
  4. using namespace std;

  5. void main()
  6. {
  7.         int Arr[9] = {6,2,8,4,10,0,12,16,14};
  8.         AVLTree<int> Tr(Arr,9);
  9.         Tr.traverse(Tr.getRoot());
  10.         Tr.traverseByLevel(Tr.getRoot());

  11.         Tr.erase(14,Tr.getRoot());
  12.         Tr.traverse(Tr.getRoot());
  13.         Tr.traverseByLevel(Tr.getRoot());
  14.         cout<<"Tree's length is:"<<Tr.getLength()<<endl;
  15.         Tr.clear();
  16.         cout<<"Tree's length is:"<<Tr.getLength()<<endl;
  17. }
复制代码
回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-5-1 08:26 , Processed in 0.043054 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表