一、定义:
或者是一棵空树
或者是具有下列性质的二叉树
(1)当左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)它的右子树上所有结点的值均大于它的根节点的值
(3)它的左、右子树也分别为二叉排序树
二、分类
1、平衡二叉树
是自平衡的二叉查找树,又被称为AVL树(有别于AVL算法)
它的左右两个子树的高度差(平衡因子)的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树
2、红黑树
红黑树每个节点上都有存储位表示节点的颜色,可以是红或黑
红黑树的特性:
- 根结点是黑色的
- 每个为空的(NIL或NULL)叶子节点是黑色的
- 如果一个节点是红色的,则它的子节点必须是黑色的(交替出现)
- 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点(确保没有一条路径会比其他路径长出两倍)
红黑树的应用比较广泛,主要是用它来存储有序的数据,它的时间复杂度是O(lgn),效率非常之高。
例如,Java集合中的TreeSet和TreeMap以及Linux虚拟内存的管理,都是通过红黑树去实现的。
3、B树(balanced tree)(各层结点都是有数据的)
与二叉平衡树相比,是多叉的,可以降低树的深度,提高查找效率。
B树应文件系统的要求而发展起来的,大量数据存放在外存中,通常放在硬盘中。
4、B+树(数据存储在最后一层结点上)
5、B*树
在B+树的非根和非叶子结点再增加指向兄弟的指针
三、红黑树
基本操:左旋和右旋
红黑树的基本操作是添加、删除。在对红黑树进行添加或删除之后,都会用到旋转方法。为什么呢?道理很简单,添加或删除红黑树中的节点之后,红黑树就发生了变化,可能不满足红黑树的性质。而通过旋转,可以使这颗树重新成为红黑树。简单点说,旋转的目的是让树保持红黑树的特性。
旋转包括两种:左旋 和 右旋。
红黑树的java代码实现:
public class RBTree<T extends Comparable<T>> {
private RBTNode<T> mRoot; // 根结点
private static final boolean RED = false;
private static final boolean BLACK = true;
public class RBTNode<T extends Comparable<T>> {
boolean color; // 颜色
T key; // 关键字(键值)
RBTNode<T> left; // 左孩子
RBTNode<T> right; // 右孩子
RBTNode<T> parent; // 父结点
public RBTNode(T key, boolean color, RBTNode<T> parent, RBTNode<T> left, RBTNode<T> right) {
this.key = key;
this.color = color;
this.parent = parent;
this.left = left;
this.right = right;
}
public T getKey() {
return key;
}
public String toString() {
return ""+key+(this.color==RED?"(R)":"B");
}
}
public RBTree() {
mRoot=null;
}
private RBTNode<T> parentOf(RBTNode<T> node) {
return node!=null ? node.parent : null;
}
private boolean colorOf(RBTNode<T> node) {
return node!=null ? node.color : BLACK;
}
private boolean isRed(RBTNode<T> node) {
return ((node!=null)&&(node.color==RED)) ? true : false;
}
private boolean isBlack(RBTNode<T> node) {
return !isRed(node);
}
private void setBlack(RBTNode<T> node) {
if (node!=null)
node.color = BLACK;
}
private void setRed(RBTNode<T> node) {
if (node!=null)
node.color = RED;
}
private void setParent(RBTNode<T> node, RBTNode<T> parent) {
if (node!=null)
node.parent = parent;
}
private void setColor(RBTNode<T> node, boolean color) {
if (node!=null)
node.color = color;
}
/*
* 前序遍历"红黑树"
*/
private void preOrder(RBTNode<T> tree) {
if(tree != null) {
System.out.print(tree.key+" ");
preOrder(tree.left);
preOrder(tree.right);
}
}
public void preOrder() {
preOrder(mRoot);
}
/*
* 中序遍历"红黑树"
*/
private void inOrder(RBTNode<T> tree) {
if(tree != null) {
inOrder(tree.left);
System.out.print(tree.key+" ");
inOrder(tree.right);
}
}
public void inOrder() {
inOrder(mRoot);
}
/*
* 后序遍历"红黑树"
*/
private void postOrder(RBTNode<T> tree) {
if(tree != null)
{
postOrder(tree.left);
postOrder(tree.right);
System.out.print(tree.key+" ");
}
}
public void postOrder() {
postOrder(mRoot);
}
/*
* (递归实现)查找"红黑树x"中键值为key的节点
*/
private RBTNode<T&g