TreeMap相关
Map接口
Map集合的特点
1.能够存储唯一的列的数据(唯一,不可重复) Set
2.能够存储可以重复的数据(可重复) List
3.值的顺序取决于键的顺序
4.键和值都是可以存储null元素的
TreeMap
本质上就是红黑树
的实现
1.每个节点要么是红色,要么是黑色。
2.根节点必须是黑色
3.每个叶子节点【NIL】是黑色
4.每个红色节点的两个子节点必须是黑色
5.任意节点到每个叶子节点的路径包含相同数量的黑节点
K key; // key
V value; // 值
Entry<K,V> left; // 左子节点
Entry<K,V> right; // 右子节点
Entry<K,V> parent; // 父节点
boolean color = BLACK; // 节点的颜色 默认是黑色
put为例
public V put(K key, V value) {
// 将root赋值给局部变量 null
Entry<K,V> t = root;
if (t == null) {
// 初始操作
// 检查key是否为空
compare(key, key); // type (and possibly null) check
// 将要添加的key、 value封装为一个Entry对象 并赋值给root
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; // 获取比较器
if (cpr != null) {
// 一直找到插入节点的父节点
do {
// 将root赋值给了parent
parent = t;
// 和root节点比较值得大小
cmp = cpr.compare(key, t.key);
if (cmp < 0)
// 将父节点的左子节点付给了t
t = t.left;
else if (cmp > 0)
t = t.right; // 将父节点的右节点付给了t
else
// 直接和父节点的key相等,直接修改值
return t.setValue(value);
} 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;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
// t 就是我们要插入节点的父节点 parent
// 将我们要插入的key value 封装成了一个Entry对象
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e; // 插入的节点在parent节点的左侧
else
parent.right = e; // 插入的节点在parent节点的右侧
fixAfterInsertion(e); // 实现红黑树的平衡
size++;
modCount++;
return null;
}
/** From CLR */
private void fixAfterInsertion(Entry<K,V> x) {
// 设置添加节点的颜色为 红色
x.color = RED;
// 循环的条件 添加的节点不为空 不是root节点 父节点的颜色为红色
while (x != null && x != root && x.parent.color == RED) {
// 父节点是否是 祖父节点的左侧节点
if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
// 获取父节点的 兄弟节点 叔叔节点
Entry<K,V> y = rightOf(parentOf(parentOf(x)));
if (colorOf(y) == RED) { // 叔叔节点是红色
// 变色
setColor(parentOf(x), BLACK); // 设置 父节点的颜色为黑色
setColor(y, BLACK); // 设置叔叔节点的颜色为 黑色
setColor(parentOf(parentOf(x)), RED); // 设置 祖父节点的颜色是 红色
// 将祖父节点设置为 插入节点
x = parentOf(parentOf(x));
} else { // 叔叔节点是黑色
if (x == rightOf(parentOf(x))) {
// 判断插入节点是否是 父节点的右侧节点
x = parentOf(x); // 将父节点作为插入节点
rotateLeft(x); // 左旋
}
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
rotateRight(parentOf(parentOf(x)));// 右旋
}
} else {// 父节点是祖父节点的右侧子节点
// 获取叔叔节点
Entry<K,V> y = leftOf(parentOf(parentOf(x)));
if (colorOf(y) == RED) { // 叔叔节点为红色
// recolor 变色
setColor(parentOf(x), BLACK);
setColor(y, BLACK);
setColor(parentOf(parentOf(x)), RED);
x = parentOf(parentOf(x));
} else {
// 插入节点在父节点的右侧
if (x == leftOf(parentOf(x))) {
x = parentOf(x);
rotateRight(x); // 右旋
}
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
rotateLeft(parentOf(parentOf(x))); // 左旋
}
}
}
// 根节点的颜色为黑色
root.color = BLACK;
}
TreeMap相关的更多相关文章
- JAVA实现的微信扫描二维码支付
吐槽一下 支付项目采用springMvc+Dubbo架构实现,只对外提供接口. 话说,为什么微信支付比支付宝来的晚了那么一点,一句话,那一阵挺忙的,然后就没有时间整理,最近做完支付宝支付,顺便也把微信 ...
- Map写入的顺序 输出地顺序ZT
偶然间 发现hashmap遍历的结果不是放入的顺序 为了项目某个功能更人性话 思考了半天还是不知道如何下手 因为有种种条件限制 后来 无意中发现 java.util.LinkedHashMap< ...
- 大数据系列修炼-Scala课程11
接着昨天的list,也是学习集合的相关知识 ListBuffer.ArrayBuffer.Queue.stack相关操作 1.ListBuffer.ArrayBuffer代码实现:ListBuffer ...
- 死磕 java集合之ConcurrentSkipListSet源码分析——Set大汇总
问题 (1)ConcurrentSkipListSet的底层是ConcurrentSkipListMap吗? (2)ConcurrentSkipListSet是线程安全的吗? (3)Concurren ...
- 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解
今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...
- Java 集合系列之五:Map基本操作
1. Java Map 1. Java Map 重要观点 Java Map接口是Java Collections Framework的成员.但是它不是Collection 将键映射到值的对象.一个映射 ...
- 嵌入式单片机STM32应用技术(课本)
目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...
- HashMap相关类:Hashtable、LinkHashMap、TreeMap
前言 很高兴遇见你~ 在 深入剖析HashMap 文章中我从散列表的角度解析了HashMap,在 深入解析ConcurrentHashMap:感受并发编程智慧 解析了ConcurrentHashMap ...
- 容器--TreeMap
一.概述 在Map的实现中,除了我们最常见的KEY值无序的HashMap之外,还有KEY有序的Map,比较常用的有两类,一类是按KEY值的大小有序的Map,这方面的代表是TreeMap,另外一种就保持 ...
随机推荐
- C printf 字符串格式化
%a 浮点数.十六进制数字和p-记数法(C99) %A 浮点数.十六进制数字和p-记法(C99) %c 一个字符 %d 有符号十进制整数 %e 浮点数.e-记数法 %E 浮点数.E-记数法 %f 浮点 ...
- 【LeetCode】720. Longest Word in Dictionary 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力查找 排序 日期 题目地址:https://le ...
- C. Success Rate
Success Rate 题目链接 题意 给你两个分数形式的数,然后有两种变化方式 上下都+1 仅下面部分+1 让你求第一个分数变化到第二个分数的最小步数. 思路 有几种特殊情况分类讨论一下. 首先我 ...
- 13 个 C# 10 特性
原文链接:https://blog.okyrylchuk.dev 原文作者:Oleg Kyrylchuk 译: 等天黑 常量的内插字符串 C# 10 允许使用在常量字符串初始化中使用插值, 如下 co ...
- vue使用自定义指令v-dialogDrag来控制element ui中el-dialog的拖动缩放,拉伸问题
1 在vue的utils中新建一个dialogDrag.js import Vue from 'vue' Vue.directive('dialogDrag', { bind(el, binding, ...
- CS5265完美替代CH7211|Type-C转HDMI2.0单转方案|CH7211替代方案
龙迅Chrontel的CH7211是一款Type-C转HDMI2.0半导体设备,可通过USB Type-C连接器将DisplayPort信号转换为HDMI/DVI.这款创新的基于USB Type-C的 ...
- JavaScript交互式网页设计 • 【第3章 JavaScript浏览器对象模型】
全部章节 >>>> 本章目录 3.1 浏览器对象模型 3.1.1 浏览器对象模型 3.2 window 对象 3.2.1 window 对象的常用属性及方法 3.2.2 使 ...
- C#自定义转换(implicit 或 explicit)
C#的类型转换分为显式转换和隐式转换,显式转换需要自己声明转换类型,而隐式转换由编译器自动完成,无需我们声明,如: //long需要显式转换成int long l = 1L; int i = (int ...
- .net core的配置介绍(二):自定义配置(Zookeeper,数据库,Redis)
上一篇介绍了.net core的配置原理已经系统提供的一些常用的配置,但有时我们的配置是存放在Zookeeper,DB,Redis中的,这就需要我们自己去实现集成了. 这里再介绍几个我们用的多的配置集 ...
- 初识python: 自定义函数
什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 函数的定义方法: def test(x): '函数定义方法' x+=1 r ...