数据结构——二叉查找树、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的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...
随机推荐
- Kafka入门经典教程
本帖最后由 desehawk 于 2015-5-3 00:45 编辑问题导读 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程 ...
- mapreduce 自定义数据类型的简单的应用
本文以手机流量统计为例: 日志中包含下面字段 现在需要统计手机的上行数据包,下行数据包,上行总流量,下行总流量. 分析:可以以手机号为key 以上4个字段为value传传递数据. 这样则需要自己定义一 ...
- Python 爬虫笔记、多线程、xml解析、基础笔记(不定时更新)
1 Python学习网址:http://www.runoob.com/python/python-multithreading.html
- codeforces #270 ABCD
Codeforces Round #270 A - Design Tutorial: Learn from Math 题意:给出n,求出两个合数x和y使x+y=n. 题解:暴力筛合数,然后暴力找 // ...
- hdu4923 Room and Moor
4923Room and Moor Room and Moor Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/2621 ...
- Unity调试相关
1.LOG处理 将所有LOG信息写入到文件,并设置部分LOG显示到屏幕上,总结成以下脚本,将其挂载在摄像机上即可. using UnityEngine; using System.Collection ...
- RTX二次开发(一)(基于ASP.NET)
腾讯通RTX是(Real Time eXpert)是腾讯公司推出的企业级实时通信平台,致力于帮助企业提高运作效率.降低沟通成本.拓展商业机会,是一种高度可管理.低成本.易部署的IT平台.RTX集成了丰 ...
- js中的换算小技巧
之前自己一直使用~~运算符来把‘112222’字符型的数值换算成整型的数值 但今天调试程序发现了一些问题 ~~'999'=>999 ~~'111111999'=>111111999 这些都 ...
- 个人建了一个APPCAN移动前端开发交流QQ群258213194
QQ群号:258213194,欢迎有兴趣的同志加一下. 二维码如下:
- php的字符串转2进制函数
<?php $file1 = '16.jpg'; $file2 = 'test.txt'; $file3 = '47.jpg'; $size = filesize($file1); echo ' ...