数据结构——二叉查找树、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的高度直接影响到操作实现的性能,最坏情况下,二叉查找树会退化成一个单链表,比如插入的节点序列本身就 ...
随机推荐
- navicat linux 破解
破解方法一. navicat linux版本有一个月的试用期, 当过了试用期以后, 不能再进入. 但其实只要将~下.navicat目录下的system.reg文件删掉, 重新启动navicat ...
- Java通过JNI调用C
Java调用C有多种方式,本文介绍笔者最近的学习过程,避免今后再犯类似的错误. 首先,Java肯定是调用C的动态链接库,即通过编译器编译后的dll/so文件. 下面介绍gcc编译dll的方法. 一般情 ...
- php 选择排序法
private function demo(array $arr = array()){ $len = count($arr); if ($len == 1) return $arr; else fo ...
- acdream1233 Royal Federation (构造?)
http://acdream.info/problem?pid=1233 Andrew Stankevich's Contest (3) ASC 3 Royal Federation Special ...
- CF459E Pashmak and Graph (DP?
Codeforces Round #261 (Div. 2) E - Pashmak and Graph E. Pashmak and Graph time limit per test 1 seco ...
- c++模板
1.从 python 说起 def add(a, b): return a + b; print add(3.1, 5.1); #8.2 print add("abc", &quo ...
- 基础知识系列☞IList ←vs→ List
原文地址→http://www.cnblogs.com/zbphot/archive/2011/11/04/2235933.html IList接口→表示可按照索引单独访问的对象的非泛型集合. ILi ...
- hdu1757 A Simple Math Problem
Problem Description Lele now is thinking about a simple function f(x).If x < 10 f(x) = x.If x > ...
- Linux统计文件行数
语法:wc [选项] 文件… 说明:该命令统计给定文件中的字节数.字数.行数.如果没有给出文件名,则从标准输入读取.wc同时也给出所有指定文件的总统计数.字是由空格字符区分开的最大字符串. 该命令各选 ...
- Codeforces Round #270 1003
Codeforces Round #270 1003 C. Design Tutorial: Make It Nondeterministic time limit per test 2 second ...