比较器
所谓比较器指的就是进行大小关系的确定判断。
java.lang.Integer与java.lang.String两个类都是由系统提供的程序类,如果使用自定义的类实现排序处理,会发现即使语法没有错误,排序的顺序也会出现错误,这是因为任意一个类默认情况下是无法使用系统内部的类实现数组排序或比较需求的,没有明确的指出到该如何进行比较的定义(没有比较的规则)。为此,在Java中为了统一比较规则的定义,提供了比较器的接口:Comparable接口。
Comparable比较器
对于Comparable而言,需要清楚其基本的定义结构:
public interface Comparable<T>{
public int compareTo(T o);
}
排序里只需要有一个CompareTo的方法进行排序规则的定义,而后整个Java系统里面就可以为其实现排序处理。
Comparator比较器
Comparator属于一种挽救的比较器支持,其主要的目的是解决一些没有使用Comparable排序的类的对象数组。
在Arrays类里排序有另一种实现:
public static <T> void sort(T[] a,Comparator<? super T>c);
在java.util.Comparator里面最初只定义有一个排序的compare()方法:
public int compare(T o1,T o2));
但是后来持续发展又出现了许多的static方法。
Comparable与Comparator的区别?
- java.lang.Comparable是在类定义的时候实现的父接口,主要用于定义排序规则,里面只有一个compareTo()方法;
- java.util.Comparator是挽救的比较操作,需要设置单独的比较器规则类实现排序,里面有compare()方法。
二叉树结构
二叉树是每个节点最多只有两个子树的树结构。
class Node{
Person person;
Node leftChild;
Node rightChild;
}
class Person{
int iData;
double dData;
}
class Tree{
private Node root;
}
红黑树原理分析
二叉树的主要特点:数据查询的时候可以提供更好的查询性能,但是就原始的二叉树结构是有明显缺陷的,例如在二叉树结构发生改变的时候(增加或删除)就有可能出现不平衡的问题。
红黑树本质上是一种二叉查找树,但它在二叉树的基础上额外添加了一个标记(颜色),同时具有一定的规则。这些规则使得红黑树保证了一种平衡,插入、删除、查找的最坏时间复杂度都位O(logn)。红黑树于1972年有Rudolf Bayer发明的。
enum Color{
RED,BLACK;
}
class BinaryTree<T>{
private class Node{
private T data;
ptivate Node parent;
private Node left;
private Color colo;
} //本质就是在节点上追加了一个表示颜色的操作信息而已。
对于Node节点中的颜色标记也可以使用true或false来实现,不一定非要使用枚举类。
- 红黑树特点
- 每个节点或者是黑色,或者是红色;
- 根节点必须是黑色;
- 每个叶子节点是黑色;
- Java实现的红黑树将使用null来代表空节点,因此遍历红黑树时将看不到黑色的叶子节点,反而可以看到每个叶子节点都是红色的。
- 如果一个节点是红色的,则它的子节点必须是黑色的;
- 从每个根到节点的路径上不会有两个连续的红色节点,但黑色节点是可以连续的。若给定黑色节点的个数N,最短路径情况是连续的N个黑色,树的高度为N-1;最长路径情况为节点红黑相间,树的高度为2(N-1);
- 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点;
- 成为红黑树最主要的条件,后序的插入、删除操作都是为了遵循这个规定。
利用红黑树的结构实现左旋或右旋达到树的平衡性。
• 数据插入处理 - 第一次插入,由于原树为空,所以只会违反红黑树的规则2,所以只要把根节点涂黑即可;
- 如果插入节点的父节点是黑色的,那不会违反红黑树规则,不需修改;但如果遇到以下三种情况,需要变色和旋转处理:
- 插入节点的父节点和其叔叔节点(祖父节点的另一子节点)均为红色的;(将父节点与叔叔节点涂黑,祖父节点涂红)
- 插入节点的父节点是红色,叔叔节点是黑色,且插入节点是父节点的左子节点。(将父节点变色(变黑)与祖父节点(变红)进行互换,随后采用右旋处理)
- 插入节点的父节点是红色,叔叔节点是黑色,且插入节点是父节点的右子节点。
在进行红黑树处理的时候为了方便操作都会将新的节点使用红色来进行描述。
- 成为红黑树最主要的条件,后序的插入、删除操作都是为了遵循这个规定。
- 数据删除处理
- 删除操作后,如果当前节点是黑色的根节点,不需修改。
- 如果当前节点是红色的,说明刚刚移走的后继节点是黑色的,那么不管后继节点的父节点是什么颜色,只要将当前节点涂黑即可。
- 但如果遇到以下四种情况,需要通过变色或旋转处理:
- 当前节点是黑色的,且兄弟节点是红色的(那么父节点和兄弟节点的子节点肯定是黑色的);
- 当前节点是黑色的,且兄弟节点是黑色的,且兄弟节点的两个子节点均为黑色的;
- 当前节点是黑色的,且兄弟节点是黑色的,且兄弟节点的左子节点是红色的,右子节点是黑色的;
- 当前节点是黑色的,且兄弟节点是黑色的,且兄弟节点的右子节点是红色的,右子节点任意颜色。