二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列!

插入:直接插入,插入后一定为根节点

查找:直接查找

删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父节点即可,有两个孩子的节点,将左儿子最右边节点(或右儿子最左边节点)替换到根节点即可。

AVL树(二叉平衡查找树)

定义:节点的平衡度(左子树的高度 - 右子树的高度)只能为-1、0、1的二叉查找树。

创建:需要一个变量记录每个节点的平衡度

查找:直接查找

插入:LL、LR、RL、RR过程

删除:分情况讨论

AVL树的Java实现:

  1. package com.tonyluis;
  2.  
  3. /**
  4. * AVL树
  5. *
  6. * @author TonyLuis 2016.07.27
  7. * @param <T>
  8. */
  9. public class AVLTree<T extends Comparable<T>> {
  10. private AVLNode<T> root;
  11.  
  12. @SuppressWarnings("hiding")
  13. class AVLNode<T> {
  14. T val;
  15. AVLNode<T> left;
  16. AVLNode<T> right;
  17. int height;
  18.  
  19. AVLNode(T val, AVLNode<T> left, AVLNode<T> right) {
  20. this.val = val;
  21. this.left = left;
  22. this.right = right;
  23. this.height = 0;
  24. }
  25. }
  26.  
  27. public void insert(T num) {
  28. root = insert(num, root);
  29. }
  30.  
  31. public void remove(T num) {
  32. remove(num, root);
  33. }
  34.  
  35. public boolean find(T num) {
  36. AVLNode<T> t = this.root;
  37. while (t != null && num.compareTo(t.val) != 0)
  38. t = num.compareTo(t.val) > 0 ? t.right : t.left;
  39. if (t == null)
  40. return false;
  41. else
  42. return true;
  43. }
  44.  
  45. private int height(AVLNode<T> node) {
  46. return node == null ? -1 : node.height;
  47. }
  48.  
  49. private AVLNode<T> insert(T num, AVLNode<T> root) {
  50. // root==null 找到了插入的位置
  51. if (root == null)
  52. return new AVLNode<T>(num, null, null);
  53.  
  54. int compareResult = num.compareTo(root.val);
  55. if (compareResult < 0) {// 插入左子树
  56. root.left = insert(num, root.left);
  57. if (height(root.left) - height(root.right) == 2) {
  58. if (num.compareTo(root.left.val) < 0)
  59. root = LL(root);
  60. else
  61. root = LR(root);
  62. }
  63. } else if (compareResult > 0) {
  64. root.right = insert(num, root.right);
  65. if (height(root.right) - height(root.left) == 2) {
  66. if (num.compareTo(root.right.val) < 0)
  67. root = RL(root);
  68. else
  69. root = RR(root);
  70. }
  71. }
  72. root.height = Math.max(height(root.left), height(root.right)) + 1;
  73. return root;
  74. }
  75.  
  76. public boolean remove(T num, AVLNode<T> root) {
  77. boolean isStop = false;
  78. boolean isLeftSubTree;
  79. if (root == null)
  80. return true;
  81. int compareResult = num.compareTo(root.val);
  82. if (compareResult < 0) {
  83. isStop = remove(num, root.left);
  84. isLeftSubTree = true;
  85. } else if (compareResult > 0) {
  86. isStop = remove(num, root.right);
  87. isLeftSubTree = false;
  88. } else if (root.left == null || root.right == null) {
  89. root = root.left == null ? root.right : root.left;
  90. return false;
  91. } else {// 找到且有两个子树,将其和右子树最左边节点交换,然后在右子树执行删除操作
  92. AVLNode<T> tmp = root.right;
  93. while (tmp.left != null)
  94. tmp = tmp.left;
  95. root.val = tmp.val;
  96. isStop = remove(root.val, root.right);
  97. isLeftSubTree = false;
  98. }
  99. if (isStop)
  100. return true;
  101. int bf;// 删除前的root的平衡因子
  102. if (isLeftSubTree) {
  103. bf = height(root.left) - height(root.right) + 1;
  104. if (bf == 0)
  105. return true;
  106. else if (bf == 1)
  107. return false;
  108. else if (bf == -1) {
  109. int bfr = height(root.right.left) - height(root.right.left);
  110. switch (bfr) {
  111. case 0:
  112. RR(root);
  113. return true;
  114. case -1:
  115. RR(root);
  116. return false;
  117. default:
  118. RL(root);
  119. return false;
  120. }
  121. }
  122. } else {
  123. bf = height(root.left) - height(root.right) - 1;
  124. if (bf == 0)
  125. return true;
  126. else if (bf == -1)
  127. return false;
  128. else if (bf == 1) {
  129. int bfr = height(root.right.left) - height(root.right.left);
  130. switch (bfr) {
  131. case 0:
  132. LL(root);
  133. return true;
  134. case 1:
  135. LL(root);
  136. return false;
  137. default:
  138. LR(root);
  139. return false;
  140. }
  141. }
  142. }
  143. return false;
  144. }
  145.  
  146. private AVLNode<T> LL(AVLNode<T> node) {
  147. AVLNode<T> nodeLeft = node.left;
  148. node.left = nodeLeft.right;
  149. nodeLeft.right = node;
  150. node.height = Math.max(height(node.left), height(node.right)) + 1;
  151. nodeLeft.height = Math.max(height(nodeLeft.left), node.height) + 1;
  152. return nodeLeft;
  153. }
  154.  
  155. private AVLNode<T> RR(AVLNode<T> node) {
  156. AVLNode<T> nodeRight = node.right;
  157. node.right = nodeRight.left;
  158. nodeRight.left = node;
  159. node.height = Math.max(height(node.left), height(node.right)) + 1;
  160. nodeRight.height = Math.max(height(nodeRight.right), node.height) + 1;
  161. return nodeRight;
  162. }
  163.  
  164. private AVLNode<T> LR(AVLNode<T> node) {
  165. node.left = RR(node.left);
  166. return LL(node);
  167. }
  168.  
  169. private AVLNode<T> RL(AVLNode<T> node) {
  170. node.right = LL(node.right);
  171. return RR(node);
  172. }
  173.  
  174. }

数据结构——二叉查找树、AVL树的更多相关文章

  1. 006-数据结构-树形结构-二叉树、二叉查找树、平衡二叉查找树-AVL树

    一.概述 树其实就是不包含回路的连通无向图.树其实是范畴更广的图的特例. 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合. 1.1.树的特性: 每个结点有零个或多个子 ...

  2. linux 内核数据结构之 avl树.

    转载: http://blog.csdn.net/programmingring/article/details/37969745 https://zh.wikipedia.org/wiki/AVL% ...

  3. 数据结构之AVL树

    AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 旋转 如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡.这种失去平衡的可以概括为4种姿态:LL ...

  4. 二叉树-二叉查找树-AVL树-遍历

    一.二叉树 定义:每个节点都不能有多于两个的儿子的树. 二叉树节点声明: struct treeNode { elementType element; treeNode * left; treeNod ...

  5. D&F学数据结构系列——AVL树(平衡二叉树)

    AVL树(带有平衡条件的二叉查找树) 定义:一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树. 为什么要使用AVL树(即为什么要给二叉查找树增加平衡条件),已经在我之前的博文中说到过 ...

  6. [算法] 数据结构之AVL树

    1 .基本概念 AVL树的复杂程度真是比二叉搜索树高了整整一个数量级——它的原理并不难弄懂,但要把它用代码实现出来还真的有点费脑筋.下面我们来看看: 1.1  AVL树是什么? AVL树本质上还是一棵 ...

  7. [javaSE] 数据结构(AVL树基本概念)

    AVL树是高度平衡的二叉树,任何节点的两个子树的高度差别<=1 实现AVL树 定义一个AVL树,AVLTree,定义AVLTree的节点内部类AVLNode,节点包含以下特性: 1.key——关 ...

  8. 面试题:什么叫平衡二叉查找树--AVL树

    查找.插入和删除在平均和最坏情况下都是O(log n) 增加和删除可能需要通过一次或多次树旋转来重新平衡这个树 节点的平衡因子是它的左子树的高度减去它的右子树的高度.带有平衡因子 1.0 或 -1 的 ...

  9. 大话数据结构—平衡二叉树(AVL树)

    平衡二叉树(Self-Balancing Binary Search Tree/Height-Balanced Binary Search Tree),是一种二叉排序树,当中每个节点的左子树和右子树的 ...

  10. 二叉树学习笔记之经典平衡二叉树(AVL树)

    二叉查找树(BSTree)中进行查找.插入和删除操作的时间复杂度都是O(h),其中h为树的高度.BST的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...

随机推荐

  1. 关于php cgi的配置

    http://blog.csdn.net/xiaolei1982/article/details/7103850 1,查看php-cgi的进程数 netstat -anpo | grep " ...

  2. 再读<<基于MVC的JavaScript Web 富应用开发>>

    工作的时候粗读过这本书的几章内容,真真是囫囵吞枣~~目前手边就剩这一本,重新读才觉得先前是没看明白啊!这个作者博闻强识,对这些插件.库了解的非常多.记录下,查的资料 订阅/发布 jQuery Tiny ...

  3. OS X Framework Library not loaded: 'Image not found'的解决办法

    参考:OS X Framework Library not loaded: 'Image not found' 1.首先将相应的framework手动复制到/System/Library/Framew ...

  4. rpc优化

    1.刷文章列表的时候,发现调用总时间100ms ,其中调策略是花了60ms,一个开源的map方法dozer,组装bean要花40ms 2.redis的zounct方法,传 1和-1的时候有时候会返回0 ...

  5. hash-3.hashCode

    1.有一个类Person,有两个字段age和name,我重写Object类的equal方法来比较两个对象的age和name是否相等,但是不重写hashCode. package com.hash; p ...

  6. ajax访问 aspx.cs后台

    --前台$.ajax({ type: "POST", contentType: "application/json", url: "WebForm2. ...

  7. apt-get 按照php7后apache 输出php源文件

    需要添加php7的模块 sudo apt-get install libapache2-mod-php7.0

  8. android socket编程用Bufferreader读取的一个失败教训

    由于我的手机需要用笔记本开的wifi,躺在床上玩手机时需要关电脑或者是要让电脑放歌的时候总是不想下床,于是我想能不能用一个APP,然后通过局域网实现在手机上对电脑进行操控呢?说干就干. 我在电脑上用的 ...

  9. HDU 5007 Post Robot KMP (ICPC西安赛区网络预选赛 1001)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5007 解题报告:输入一篇文章,从头开始,当遇到 “Apple”, “iPhone”, “iPod”, ...

  10. iOS开发——多线程篇——快速生成沙盒目录的路径,多图片下载的原理、SDWebImage框架的简单介绍

    一.快速生成沙盒目录的路径 沙盒目录的各个文件夹功能 - Documents - 需要保存由"应用程序本身"产生的文件或者数据,例如:游戏进度.涂鸦软件的绘图 - 目录中的文件会被 ...