博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TreeMap底层源分析
阅读量:5040 次
发布时间:2019-06-12

本文共 3348 字,大约阅读时间需要 11 分钟。

import java.util.Comparator;

import java.util.TreeMap;

/**

(1)无参构造方法
public TreeMap() {
comparator = null;
}
private final Comparator<? super K> comparator;//外部比较器用于比较大小
(2)put方法
public V put(K key, V value) { //传入(K,V)
Entry<K,V> t = root; //t节点指向根
if (t == null) { //
//比较大小
compare(key, key); // type (and possibly null) check
//创建一个根节点
root = new Entry<>(key, value, null);
size = 1; //个数++
modCount++;
return null;
}
int cmp; //创建一个标记
Entry<K,V> parent; //父节点
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
//如果外部比较器不等于null,说明外部比较器存在
if (cpr != null) {
do {
parent = t; //把root赋给父节点
cmp = cpr.compare(key, t.key); //调用外部比较起
if (cmp < 0)
t = t.left; //t指向左子树,向左子树比较
else if (cmp > 0)
t = t.right; //t指向右子树,向右子树比较
else
return t.setValue(value); //若key相同,值覆盖
} while (t != null);
}
else { //外部比较器不存在,使用内部比较器进行比较
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);//调用内部比较器比较
if (cmp < 0)
t = t.left; //t指向左子树,向左子树比较
else if (cmp > 0)
t = t.right; //t指向右子树,向右子树比较
else
return t.setValue(value); //若key相同,值覆盖
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e; //添加到左子树
else
parent.right = e; //添加到右子树
fixAfterInsertion(e); //调整树的结构
size++; //数量++
modCount++;
return null;
}
//调整树的结构
private void fixAfterInsertion(Entry<K,V> x) {
x.color = RED;
//直到x节点的父节点不是根,且x的父节点不是红色

while (x != null && x != root && x.parent.color == RED) {

//x的父节点是其祖父节点的左子节点
if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
//获取x的父节点的兄弟节点
Entry<K,V> y = rightOf(parentOf(parentOf(x)));
//如果父节点的兄弟节点是红色(需要颜色翻转)
if (colorOf(y) == RED) {
//将x的父节点设为黑色
setColor(parentOf(x), BLACK);
//将x的父节点的兄弟节点设为黑色
setColor(y, BLACK);
//将其x的祖父节点设为红色
setColor(parentOf(parentOf(x)), RED);
//x指向祖父节点
x = parentOf(parentOf(x));
} else {
//如果x是其父节点的右子节点
if (x == rightOf(parentOf(x))) {
//将x的父节点设为x
x = parentOf(x);
rotateLeft(x);
}
// 把 x 的父节点设为黑色
setColor(parentOf(x), BLACK);
// 把 x 的祖父点设为红色
setColor(parentOf(parentOf(x)), RED);
rotateRight(parentOf(parentOf(x)));
}
} else {
//x的父节点是其祖父节点的右子节点
//获取x的父节点的兄弟节点
Entry<K,V> y = leftOf(parentOf(parentOf(x)));
//如果父节点的兄弟节点是红色(需要颜色翻转)
if (colorOf(y) == RED) {
//将x的父节点设为黑色
setColor(parentOf(x), BLACK);
//将x的父节点的兄弟节点设为黑色
setColor(y, BLACK);
//将其x的祖父节点设为红色
setColor(parentOf(parentOf(x)), RED) ;
//x指向祖父节点
x = parentOf(parentOf(x));
} else {
//如果x是其父节点的左子节点
if (x == leftOf(parentOf(x))) {
//将x的父节点设为x
x = parentOf(x);
rotateRight(x);
}
// 把 x 的父节点设为黑色
setColor(parentOf(x), BLACK);
// 把 x 的祖父点设为红色
setColor(parentOf(parentOf(x)), RED);
rotateLeft(parentOf(parentOf(x)));
}
}
}
root.color = BLACK;
}
*
*/

public class TreeMapTest {

public static void main(String[] args){
//创建集合对象
//TreeMap treeMap = new TreeMap();
CompareLength cc = new CompareLength();
TreeMap treeMap = new TreeMap(cc);
treeMap.put("hello",123);
treeMap.put("world1",456);
treeMap.put("hello11",789);
treeMap.put("java", 1000);
System.out.println(treeMap);
System.out.println("集合元素的个数:"+treeMap.size());
System.out.println(treeMap.containsKey("hello")+"\t"+treeMap.containsKey("sql"));
System.out.println(treeMap.containsValue(789)+"\t"+treeMap.containsValue(1000));
System.out.println(treeMap.get("java"));
}

}

转载于:https://www.cnblogs.com/hoetears/p/10243685.html

你可能感兴趣的文章
Balanced Lineup
查看>>
C语言:数据类型
查看>>
C# string和byte[]数组之间相互转换
查看>>
无论多累,都要坚持下去!
查看>>
[转载]Linux 线程实现机制分析
查看>>
各 Android 平台版本支持的 API 级别
查看>>
PHP学习 Object Oriented 面向对象 OO
查看>>
转载 .net中的dll.refresh文件和pdb文件
查看>>
python 缩进问题
查看>>
黑马程序员 一个准程序的内心告白,原来上帝是那么的遥远
查看>>
铺地毯
查看>>
Vue.js---组件
查看>>
C++ 中超类化和子类化
查看>>
CEF3开发者系列之进程间消息传递
查看>>
Android 网络加载通用Loading
查看>>
hdu 1756:Cupid's Arrow(计算几何,判断点在多边形内)
查看>>
Eclipse+php插件+Xdebug搭建PHP完美开发/调试环境指南
查看>>
时序分析 基本术语 摘记 (ALTERA 官方教程)
查看>>
分治算法经典案例 - 棋盘问题
查看>>
A Mysterious 'RuntimeLibrary' Link Error
查看>>