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

插入:直接插入,插入后一定为根节点
查找:直接查找
删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父节点即可,有两个孩子的节点,将左儿子最右边节点(或右儿子最左边节点)替换到根节点即可。
AVL树(二叉平衡查找树)
定义:节点的平衡度(左子树的高度 - 右子树的高度)只能为-1、0、1的二叉查找树。

创建:需要一个变量记录每个节点的平衡度
查找:直接查找
插入:LL、LR、RL、RR过程
删除:分情况讨论
AVL树的Java实现:
package com.tonyluis; /**
* AVL树
*
* @author TonyLuis 2016.07.27
* @param <T>
*/
public class AVLTree<T extends Comparable<T>> {
private AVLNode<T> root; @SuppressWarnings("hiding")
class AVLNode<T> {
T val;
AVLNode<T> left;
AVLNode<T> right;
int height; AVLNode(T val, AVLNode<T> left, AVLNode<T> right) {
this.val = val;
this.left = left;
this.right = right;
this.height = 0;
}
} public void insert(T num) {
root = insert(num, root);
} public void remove(T num) {
remove(num, root);
} public boolean find(T num) {
AVLNode<T> t = this.root;
while (t != null && num.compareTo(t.val) != 0)
t = num.compareTo(t.val) > 0 ? t.right : t.left;
if (t == null)
return false;
else
return true;
} private int height(AVLNode<T> node) {
return node == null ? -1 : node.height;
} private AVLNode<T> insert(T num, AVLNode<T> root) {
// root==null 找到了插入的位置
if (root == null)
return new AVLNode<T>(num, null, null); int compareResult = num.compareTo(root.val);
if (compareResult < 0) {// 插入左子树
root.left = insert(num, root.left);
if (height(root.left) - height(root.right) == 2) {
if (num.compareTo(root.left.val) < 0)
root = LL(root);
else
root = LR(root);
}
} else if (compareResult > 0) {
root.right = insert(num, root.right);
if (height(root.right) - height(root.left) == 2) {
if (num.compareTo(root.right.val) < 0)
root = RL(root);
else
root = RR(root);
}
}
root.height = Math.max(height(root.left), height(root.right)) + 1;
return root;
} public boolean remove(T num, AVLNode<T> root) {
boolean isStop = false;
boolean isLeftSubTree;
if (root == null)
return true;
int compareResult = num.compareTo(root.val);
if (compareResult < 0) {
isStop = remove(num, root.left);
isLeftSubTree = true;
} else if (compareResult > 0) {
isStop = remove(num, root.right);
isLeftSubTree = false;
} else if (root.left == null || root.right == null) {
root = root.left == null ? root.right : root.left;
return false;
} else {// 找到且有两个子树,将其和右子树最左边节点交换,然后在右子树执行删除操作
AVLNode<T> tmp = root.right;
while (tmp.left != null)
tmp = tmp.left;
root.val = tmp.val;
isStop = remove(root.val, root.right);
isLeftSubTree = false;
}
if (isStop)
return true;
int bf;// 删除前的root的平衡因子
if (isLeftSubTree) {
bf = height(root.left) - height(root.right) + 1;
if (bf == 0)
return true;
else if (bf == 1)
return false;
else if (bf == -1) {
int bfr = height(root.right.left) - height(root.right.left);
switch (bfr) {
case 0:
RR(root);
return true;
case -1:
RR(root);
return false;
default:
RL(root);
return false;
}
}
} else {
bf = height(root.left) - height(root.right) - 1;
if (bf == 0)
return true;
else if (bf == -1)
return false;
else if (bf == 1) {
int bfr = height(root.right.left) - height(root.right.left);
switch (bfr) {
case 0:
LL(root);
return true;
case 1:
LL(root);
return false;
default:
LR(root);
return false;
}
}
}
return false;
} private AVLNode<T> LL(AVLNode<T> node) {
AVLNode<T> nodeLeft = node.left;
node.left = nodeLeft.right;
nodeLeft.right = node;
node.height = Math.max(height(node.left), height(node.right)) + 1;
nodeLeft.height = Math.max(height(nodeLeft.left), node.height) + 1;
return nodeLeft;
} private AVLNode<T> RR(AVLNode<T> node) {
AVLNode<T> nodeRight = node.right;
node.right = nodeRight.left;
nodeRight.left = node;
node.height = Math.max(height(node.left), height(node.right)) + 1;
nodeRight.height = Math.max(height(nodeRight.right), node.height) + 1;
return nodeRight;
} private AVLNode<T> LR(AVLNode<T> node) {
node.left = RR(node.left);
return LL(node);
} private AVLNode<T> RL(AVLNode<T> node) {
node.right = LL(node.right);
return RR(node);
} }
数据结构——二叉查找树、AVL树的更多相关文章
- 006-数据结构-树形结构-二叉树、二叉查找树、平衡二叉查找树-AVL树
一.概述 树其实就是不包含回路的连通无向图.树其实是范畴更广的图的特例. 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合. 1.1.树的特性: 每个结点有零个或多个子 ...
- linux 内核数据结构之 avl树.
转载: http://blog.csdn.net/programmingring/article/details/37969745 https://zh.wikipedia.org/wiki/AVL% ...
- 数据结构之AVL树
AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 旋转 如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡.这种失去平衡的可以概括为4种姿态:LL ...
- 二叉树-二叉查找树-AVL树-遍历
一.二叉树 定义:每个节点都不能有多于两个的儿子的树. 二叉树节点声明: struct treeNode { elementType element; treeNode * left; treeNod ...
- D&F学数据结构系列——AVL树(平衡二叉树)
AVL树(带有平衡条件的二叉查找树) 定义:一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树. 为什么要使用AVL树(即为什么要给二叉查找树增加平衡条件),已经在我之前的博文中说到过 ...
- [算法] 数据结构之AVL树
1 .基本概念 AVL树的复杂程度真是比二叉搜索树高了整整一个数量级——它的原理并不难弄懂,但要把它用代码实现出来还真的有点费脑筋.下面我们来看看: 1.1 AVL树是什么? AVL树本质上还是一棵 ...
- [javaSE] 数据结构(AVL树基本概念)
AVL树是高度平衡的二叉树,任何节点的两个子树的高度差别<=1 实现AVL树 定义一个AVL树,AVLTree,定义AVLTree的节点内部类AVLNode,节点包含以下特性: 1.key——关 ...
- 面试题:什么叫平衡二叉查找树--AVL树
查找.插入和删除在平均和最坏情况下都是O(log n) 增加和删除可能需要通过一次或多次树旋转来重新平衡这个树 节点的平衡因子是它的左子树的高度减去它的右子树的高度.带有平衡因子 1.0 或 -1 的 ...
- 大话数据结构—平衡二叉树(AVL树)
平衡二叉树(Self-Balancing Binary Search Tree/Height-Balanced Binary Search Tree),是一种二叉排序树,当中每个节点的左子树和右子树的 ...
- 二叉树学习笔记之经典平衡二叉树(AVL树)
二叉查找树(BSTree)中进行查找.插入和删除操作的时间复杂度都是O(h),其中h为树的高度.BST的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...
随机推荐
- AndroidStudio-使用Translations Editor
前言 如果你的App支持多语言,你需要正确的管理你的翻译字符串资源.Android Studio提供了翻译编辑器使更容易的查看和管理翻译资源. 关于翻译编辑器 翻译资源存储工程的多个目录下的多个XML ...
- 在虚机中安装CentOS
摘要 最近看到.net core 1发布的内容,也想尝试着在lunix上跑一圈.linux这方面的知识一直都没怎么接触过,只在工作中见同事操作过,看到满屏幕的命令行,感觉非常的高大上,趁着现在赶紧学习 ...
- asp.net—缓存
1.页面缓存 要实现页面输出缓存,只要将一条 OutputCache 指令添加到页面即可. <%@ OutputCache CacheProfile=" " NoStore= ...
- 使用type="redirect"重定向,传递List等变量到jsp页面的问题
Struts2在提交表单的时候,使用「type="redirect"」重定向到相应的jsp页面. Action中的List表单是无法传到相应的jsp页面. 我猜测是因为List作为 ...
- poj3070 (斐波那契,矩阵快速幂)
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9630 Accepted: 6839 Descrip ...
- poj.1703.Find them, Catch them(并查集)
Find them, Catch them Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I6 ...
- 第一节 HTML网页和CSS样式
1. 第一行 <!DOCTYPE html> 表明网页使用的是HTML5版本 2. 网页的head内容,包含了 title,meta. 3. 网页的标题 title,注意这个显示在浏览器的 ...
- (:: operator)作用域限定符的几种使用
一.(:: operator)解决局部变量与全局变量重名问题 ; int main() { ; cout<<var<<endl;//local variable cout< ...
- Linux 下复制(cp)目录时排除一个或者多个目录的方法
cp 貌似没有排除目录的功能,可以使用 rsync 命令来实现了,如: [案例] /home/52php目录里面有data目录,data目录里面有 a.b.c.d.e 五个目录,现在要把data目录里 ...
- bootstrap实现弹出窗口
bootstrap使用modal-dialog实现弹对话框. 一个对话框包含3部分: 对话框头部 modal-header 对话框内容体 modal-body 对话框底部 modal-footer 如 ...