1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. //AVL树的节点
  6. template<typename T>
  7. class TreeNode
  8. {
  9. public:
  10. TreeNode() :lson(NULL), rson(NULL), freq(), hgt(){}
  11. T data;//值
  12. int hgt;//以这个结点为根的树的高度
  13. int freq;//相同点的频率,我是不知道
  14. TreeNode* lson, *rson;//左右儿子的地址
  15. };
  16.  
  17. template<typename T>
  18. class AVLTree
  19. {//AVLTree的类属性和方法声明
  20. private:
  21. TreeNode<T>*root;//根节点
  22. void insertpri(TreeNode<T>*&node, T x);//插入
  23. TreeNode<T>* findpri(TreeNode<T>* node, T x);//查找
  24. void traversalpri(TreeNode<T>* node);//遍历
  25. void delpri(TreeNode<T>* &node, T x);//删除
  26. int height(TreeNode<T>* node);//辅助操作:高度
  27. void singLeft(TreeNode<T>* &k2);//左左操作
  28. void singRight(TreeNode<T>* &k2);//右右操作
  29. void doubleLeft(TreeNode<T>* &k3);//左右操作
  30. void doubleRight(TreeNode<T>* &k3);//右左操作
  31. int max(int cmpa, int cmpb);
  32. public:
  33. AVLTree() :root(NULL){};
  34. void insert(T x);//插入接口
  35. void del(T x);//删除接口
  36. TreeNode<T>* find(T x);//查找接口
  37. void traversal();//遍历接口
  38. };
  39.  
  40. //辅助操作:高度
  41. template<typename T>
  42. int AVLTree<T>::height(TreeNode<T>* node)
  43. {
  44. if (node!=NULL)
  45. return node->hgt;
  46. return -;
  47. }
  48.  
  49. //辅助操作:比较高度
  50. template<typename T>
  51. int AVLTree<T>::max(int cmpa, int cmpb)
  52. {
  53. return cmpa > cmpb ? cmpa : cmpb;
  54. }
  55.  
  56. template<typename T>
  57. void AVLTree<T>::singLeft(TreeNode<T>* &k2)
  58. {//左左情况下旋转
  59. TreeNode<T>* k1;
  60. k1 = k2->lson;
  61. k2->lson = k1->rson;
  62. k1->rson = k2;
  63. k2 = k1;
  64. k2->hgt = max(height(k2->lson), height(k2->rson))+;
  65. k1->hgt = max(height(k1->lson), height(k1->rson))+;
  66. }
  67.  
  68. template<typename T>
  69. void AVLTree<T>::singRight(TreeNode<T>* &k2)
  70. {//左左情况下旋转
  71. TreeNode<T>* k1;
  72. k1 = k2->rson;
  73. k2->rson = k1->lson;
  74. k1->lson = k2;
  75. k2 = k1;
  76. k2->hgt = max(height(k2->lson), height(k2->rson))+;
  77. k1->hgt = max(height(k1->lson), height(k1->rson))+;
  78. }
  79.  
  80. template<typename T>
  81. void AVLTree<T>::doubleLeft(TreeNode<T>* &k3)
  82. {//左右的情况
  83. singRight(k3->lson);
  84. singLeft(k3);
  85. }
  86.  
  87. //右左的情况
  88. template<typename T>
  89. void AVLTree<T>::doubleRight(TreeNode<T>* &k3)
  90. {
  91. singLeft(k3->rson);
  92. singRight(k3);
  93. }
  94.  
  95. //插入
  96. template<typename T>
  97. void AVLTree<T>::insertpri(TreeNode<T>* &node, T x)
  98. {
  99. if (node == NULL)
  100. {
  101. node = new TreeNode<T>();
  102. node->data = x;
  103. return;
  104. }
  105. if (node->data>x)
  106. {
  107. insertpri(node->lson, x);//递归插入
  108. //插入后自我调整
  109. if ( == height(node->lson) - height(node->rson))
  110. if (node->lson->data < x)
  111. doubleRight(node);
  112. else
  113. singLeft(node);
  114. }
  115. else if (node->data < x)
  116. {
  117. insertpri(node->rson, x);
  118. if ( == height(node->rson) - height(node->lson))
  119. if (node->rson->data < x)
  120. singRight(node);
  121. else
  122. doubleRight(node);
  123. }
  124. else ++(node->freq);
  125. //取新的高度值,后面的+1很重要,作者都忘记了加
  126. node->hgt = max(height(node->lson), height(node->rson)) + ;
  127. }
  128.  
  129. //插入接口
  130. template<typename T>
  131. void AVLTree<T>::insert(T x)
  132. {
  133. insertpri(root, x);
  134. }
  135.  
  136. //查找
  137. template<typename T>
  138. TreeNode<T>* AVLTree<T>::findpri(TreeNode<T>* node, T x)
  139. {
  140. if (node == NULL)
  141. return NULL;
  142. if (node->data > x)
  143. return findpri(node->lson, x);
  144. else if (node->data < x)
  145. return findpri(node->rson, x);
  146. else return node;
  147. }
  148.  
  149. //查找
  150. template<typename T>
  151. TreeNode<T>* AVLTree<T>::find(T x)
  152. {
  153. findpri(root, x);
  154. }
  155.  
  156. //删除
  157. template<typename T>
  158. void AVLTree<T>::delpri(TreeNode<T>* &node,T x)
  159. {
  160. if (node == NULL)
  161. return;
  162. if (x < node->data)
  163. {
  164. delpri(node->lson, x);
  165. //删除后的调整
  166. if ( == height(node->rson) - height(node->lson))
  167. if (node->rson->lson&&height(node->rson->lson) > height(node->rson->rson))
  168. doubleRight(node);
  169. else
  170. singRight(node);
  171. }
  172. else if (x > node->data)
  173. {
  174. delpri(node->rson, x);
  175. if ( == height(node->lson) - height(node->rson))
  176. if (node->lson->rson&&height(node->lson->rson) > height(node->lson->lson))
  177. doubleLeft(node);
  178. else
  179. singLeft(node);
  180. }
  181. else//找到后的操作
  182. {//先是有两个儿子的情况
  183. if (node->lson&&node->rson)
  184. {
  185. TreeNode<T>* t = node->lson;
  186. for (; t->rson; t = t->rson);
  187. node->data = t->data;
  188. node->freq = t->freq;
  189. //递归到一个儿子或没有儿子的情况
  190. delpri(node->lson, t->data);
  191. if ( == height(node->rson) - height(node->lson))
  192. {//下面的if自己不会写
  193. if (node->rson->lson&&height(node->rson->lson) > height(node->rson->rson))
  194. doubleRight(node);
  195. else
  196. singRight(node);
  197. }
  198. }
  199. else
  200. {
  201. TreeNode<T>* t = node;
  202. if (node->lson == NULL)
  203. node = node->rson;
  204. else if (node->rson == NULL)
  205. node = node->lson;
  206. delete(t);
  207. t = NULL;
  208. }
  209. }
  210. if (node == NULL)return;//表示只有根节点,删了之后就没有了
  211. node->hgt = max(height(node->lson), height(node->rson));
  212. return;
  213. }
  214.  
  215. template<typename T>
  216. void AVLTree<T>::del(T x)
  217. {
  218. delpri(root, x);
  219. }
  220.  
  221. //中序遍历函数
  222. template<class T>
  223. void AVLTree<T>::traversalpri(TreeNode<T>* node)
  224. {
  225. if (node == NULL) return;
  226. traversalpri(node->lson);//先遍历左子树
  227. cout << node->data << " ";//输出根节点
  228. traversalpri(node->rson);//再遍历右子树
  229. }
  230. //中序遍历接口
  231. template<class T>
  232. void AVLTree<T>::traversal()
  233. {
  234. traversalpri(root);
  235. }
  236.  
  237. int main()
  238. {
  239. AVLTree<int> t;
  240. t.insert();
  241. t.insert();
  242. t.insert();
  243. t.insert();
  244. t.insert();
  245. t.insert();
  246. t.del();
  247. t.insert();
  248. t.traversal();
  249. }

AVL树相关操作的更多相关文章

  1. AVL树插入操作实现

    为了提高二插排序树的性能,规定树中的每个节点的左子树和右子树高度差的绝对值不能大于1.为了满足上面的要求需要在插入完成后对树进行调整.下面介绍各个调整方式. 右单旋转 如下图所示,节点A的平衡因子(左 ...

  2. avl树的操作证明

    以下用大O表示节点,ABC表示三个集合. 仅分析左子树的情况,因为对称,右子树的情况一样. 插入节点前 O /     \ O        A   /    \ B       C 插入节点后: O ...

  3. 数据结构树之AVL树(平衡二叉树)

    一 什么是AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节 ...

  4. 图解数据结构树之AVL树

    AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节点的两个子 ...

  5. AVL树Python实现

    # coding=utf-8 # AVL树Python实现 def get_height(node): return node.height if node else -1 def tree_mini ...

  6. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

  7. AVL树(平衡二叉树)

    定义及性质 AVL树:AVL树是一颗自平衡的二叉搜索树. AVL树具有以下性质: 根的左右子树的高度只差的绝对值不能超过1 根的左右子树都是 平衡二叉树(AVL树) 百度百科: 平衡二叉搜索树(Sel ...

  8. AVL树(查找、插入、删除)——C语言

    AVL树 平衡二叉查找树(Self-balancing binary search tree)又被称为AVL树(AVL树是根据它的发明者G. M. Adelson-Velskii和E. M. Land ...

  9. 深入理解索引和AVL树、B-树、B+树的关系

    目录 什么是索引 索引的分类 索引和AVL树.B-树.B+树的关系 AVL树.红黑树 B-树 B+树 SQL和NoSQL索引 什么是索引 索引时数据库的一种数据结构,数据库与索引的关系可以看作书籍和目 ...

随机推荐

  1. JS函数定义与匿名函数的调用

    一.函数声明.函数表达式.匿名函数 函数声明:function fnName () {…};使用function关键字 声明一个函数,再指定一个函数名,叫函数声明. 函数表达式 var fnName ...

  2. mysql中的JOIN用法总结

    join是mysql中一个基础的关键词,一般在多表连接查询中使用,这里做一下总结 1.JOIN的语法格式 table_references: table_reference [, table_refe ...

  3. testng,soket write error错误

    网上解决手段:  testng 工程报错java.net.SocketException SocketException: Software caused connection abort · Iss ...

  4. 『安全工具』Nmap 强悍的端口扫描工具

    作为时下流行的端口扫描工具,Nmap有因其扫描的隐密性有“端口扫描之王”之称 上图是黑客帝国(The Matrix)中崔妮蒂用Nmap入侵核发电站的能源管理系统 0x 01 Nmap介绍 Nmap是一 ...

  5. 转:BZERO()等的区别

    BZERO()等的区别 bzero  原型: extern void bzero(void *s, int n); 用法: #include <string.h> 功能:置字节字符串s的前 ...

  6. 转:QT 的点点滴滴 错误总结

    转自:http://blog.csdn.net/lbsljn/archive/2009/12/29/5099590.aspx MinGw + CodeBlock + QT4.5 类定义后面要加&quo ...

  7. Matlab 矩阵运算

    1.Syms 和sym的区别: syms是定义多个符号是符号变量的意思 sym只能定义一个符号变量,但可以具体到这个符号变量的内容 例:syms f z; %定义下x和y f=sym('a+b+c') ...

  8. Android 之 Spinner

    1:activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/androi ...

  9. 51单片机I/O口使用经验

    按常规,在51端口(P1.P2.P3)某位用作输入时,必须先向对应的锁存器写入1,使FET截止.一般情况是这样,也有例外.所谓IO口内部与电源相连的上拉电阻而非一常规线性电阻,实质上,该电阻是由两个场 ...

  10. BZOJ3297: [USACO2011 Open]forgot

    3297: [USACO2011 Open]forgot Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 54  Solved: 38[Submit][ ...