二叉树
二叉搜索树(Binary Search Tree,简称BST),BST是一种常用的二叉树。
它的定义是:一个二叉树中任意节点的值要大于等于左子树所有节点的值,且要小于等于右子树的所有节点的值。
引入的原因:主要针对链表的插入和删除很快,但是是查找数据却很慢的特点。树状结构最大的优势在于查找,但是插入和删除的效率都不太高
public class Node{
private Object data;//节点数据
private Node leftChild;//左子节点的引用
private Node rightChild;//右子节点的引用
}
二叉树的特点
- 左子树上所有结点的值均小于或等于它的根结点的值
- 右子树上所有结点的值均大于或等于它的根结点的值
- 左、右子树也分别为二叉排序树
- 中序遍历:左子树——》根节点——》右子树
- 前序遍历:根节点——》左子树——》右子树
- 后序遍历:左子树——》右子树——》根节点
public void orderTraverse(TreeNode root){
System.out.println(node.val+" ");
orderTraverse(root.left);
orderTraverse(root.right);
}
平衡二叉树
二叉树在极端情况下会退化为链表结构,为了避免出现这个问题,引入平衡树
AVL树是一种平衡二叉树,平衡二叉树递归定义如下:
-左右子树的高度差小于等于1
-其每个子树均为平衡二叉树
AVL树引入了所谓监督机制,就是在树的某一部分的不平衡度超过一个阈值后触发相应的平衡操作。保证树的平衡度在可以接受的范围内。
public class TreeNode{
int val;具体数据
int height; //多加了一个高度,用来记录每个节点的高度
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
二叉树的类型
满二叉树
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,深度为k(k>=1)且有(2^k)-1个结点的二叉树就是满二叉树
完全二叉树
深度为K的二叉树中,K-1层结点数是满的2^(k-2),K层结点是左连续的(即结点编号是连续的);高度为h(h>=2)的完全二叉树至少有2^(h-2)个叶子结点。
满二叉树是完全二叉树的特殊形态, 即如果一棵二叉树是满二叉树, 则它必定是完全二叉树
红黑树
- 红黑树是一种近似平衡的二叉查找树,查找、删除、插入都快,树经常需要进行旋转达到平衡但是平衡算法很复杂。
红黑树特征:
- 1、每个节点不是红色就是黑色的;
- 2、根节点总是黑色的;
- 3、如果节点是红色的,则它的子节点必须是黑色的(反之不一定),(也就是从每个叶子到根的所有路径上不能有两个连续的红色节点);
- 4、从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)
TreeMap
TreeMap是一个有序的key-value集合,它是通过红黑树实现的。该映射根据其键的自然顺序进行排序[Comparable或者Comparator]或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法
底层实现和hash表无关
类定义
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
TreeMap 实现了Cloneable接口,意味着它能被克隆。
TreeMap 实现了java.io.Serializable接口,意味着它支持序列化。
属性
private final Comparator<? super K> comparator; 自定义针对key的比较器
private transient Entry<K,V> root;红黑树的根节点
节点定义类
static final class Entry<K,V> implements Map.Entry<K,V> {
K key; 对应的key
V value; 对应存储的value
Entry<K,V> left; 左子树
Entry<K,V> right; 右子树
Entry<K,V> parent; 为了方便编程引入的当前节点的父节点
boolean color = BLACK; 颜色值
}
颜色值的定义
private static final boolean RED = false;
private static final boolean BLACK = true;
private transient int size = 0;节点个数
private transient int modCount = 0;修改次数
构造器
public TreeMap() {
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator; 可以在创建TreeMap对象时指定所使用的key比较器
}
方法
常用方法
-put(K key,V value) 用于添加一个Entry(结点,包括key和value)到TreeMap对象,key为与指定值将要关联的键,value为使用指定键关联的值。如果key对应的值已经存在,则将key对应的值修改为value
-V get(Object key) 方法用于获取指定key的value,key为与value相关联的键
特殊方法
-firstEntry() 返回Map中最小的key
-higherEntry(Object key) 返回该Map中位于key后一位的key-value
-lowerEntry(Object key) 返回该Map中唯一key前一位的key-value
-tailMap(Object key,boolean inclusive) 返回该Map的子Map
简单用法
import java.util.TreeMap;
public class TestTreeMap {
public static void main(String[] args) {
//用法1
TreeMap<Integer, String> map=new TreeMap<>((obj1,obj2)->{
return -1*obj1.compareTo(obj2);
});
for(int i=0;i<10;i++) {
map.put(10-i, "name-"+(10-i));
}
map.forEach((key,val)->{
System.out.println(key+"-->"+val);
});
}
}
import java.util.Map;
import java.util.TreeMap;
public class TestTreeMap2 {
public static void main(String[] args) {
//用法2
TreeMap<Integer, String> map=new TreeMap<>((obj1,obj2)->{
return obj1.compareTo(obj2);
});
for(int i=0;i<10;i++) {
map.put(10-i, "name-"+(10-i));
}
Map.Entry<Integer, String> en=map.firstEntry();
System.out.println("最小值:"+en);
Map.Entry<Integer, String> en2=map.higherEntry(en.getKey());
System.out.println("比指定的key大一些的值:"+en2);
en2=map.lowerEntry(en.getKey());
System.out.println("比指定的key小一些的值:"+en2);
}
}