红黑树

面试3——java集合类总结(Map)

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-16 22:30:53
1.概述: Java 中的map集合使用键值对(key-value)来保持数据,其中值(value)可以重复,键(key)必须唯一,但最多只能有一个key为空,它的主要实现类有HashMap、HashTable、TreeMap、LinkedHashMap. Map集合方法摘要 map和collection的区别: map存储的是键值对形式的元素,键唯一,值可以重复 collection存储的是单列元素,子接口set元素唯一,子接口list元素可以重复 map集合的数据结构值针对键有效,跟值无关,collection集合的数据结构针对的是元素有效 map的遍历方式(4种) package Three; import java.util.*; public class Map_sort { public static void main(String[] args) { Map<String,String> map = new HashMap<String, String>(); map.put("a","@"); map.put("f","@"); map.put("n","@"); map.put("e","@"); map.put("q","@"); map.put("d","@"); map.put("l","@"); // 第一种遍历map的方法,通过加强for循环map

【集合系列】- 深入浅出分析HashMap

风格不统一 提交于 2019-12-16 22:30:37
一、摘要 在集合系列的第一章,咱们了解到,Map的实现类有HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties等等。 关于HashMap,一直都是一个非常热门的话题,只要你出去面试,我保证一定少不了它! 本文主要结合JDK1.7和JDK1.8的区别,就HashMap的数据结构和实现功能,进行深入探讨,废话也不多说了,直奔主题! 二、简介 在程序编程的时候,HashMap是一个使用非常频繁的容器类,它允许键值都放入null元素。除该类方法未实现同步外,其余跟Hashtable大致相同,但跟TreeMap不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,因此不同时间迭代同一个HashMap的顺序可能会不同。 HashMap容器,实质还是一个哈希数组结构,但是在元素插入的时候,存在发生hash冲突的可能性; 对于发生Hash冲突的情况,冲突有两种实现方式, 一种开放地址方式(当发生hash冲突时,就继续以此继续寻找,直到找到没有冲突的hash值),另一种是拉链方式(将冲突的元素放入链表) 。 Java HashMap采用的就是第二种方式,拉链法。 在jdk1.7中,HashMap主要是由数组+链表组成,当发生hash冲突的时候

【JDK1.8】HashMap源码详解:

早过忘川 提交于 2019-12-16 16:46:00
一、HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。 下图中代表jdk1.8之前的hashmap结构,左边部分即代表哈希表,也称为哈希数组,数组的每个元素都是一个单链表的头节点,链表是用来解决冲突的,如果不同的key映射到了数组的同一位置处,就将其放入单链表中。 jdk1.8之前hashmap结构图 jdk1.8之前的hashmap都采用上图的结构,都是基于一个数组和多个单链表,hash值冲突的时候,就将对应节点以链表的形式存储。如果在一个链表中查找其中一个节点时,将会花费O(n)的查找时间,会有很大的性能损失。到了jdk1.8,当同一个hash值的节点数不小于8时,不再采用单链表形式存储,而是采用红黑树,如下图所示。 jdk1.8 hashmap结构图 说明:上图很形象的展示了HashMap的数据结构(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树的引入是为了提高效率。 二、涉及到的数据结构:处理hash冲突的链表和红黑树以及位桶 1、链表的实现

红黑树详解(转载)

本小妞迷上赌 提交于 2019-12-16 16:01:50
在讲红黑树之前,我们首先来了解下下面几个概念:二叉树,排序二叉树以及平衡二叉树。 二叉树 二叉树指的是每个节点最多只能有两个字数的有序树。通常左边的子树称为 左子树 ,右边的子树称为 右子树 。这里说的有序树强调的是二叉树的左子树和右子树的次序不能随意颠倒。 二叉树简单的示意图如下: 代码定义: class Node { T data; Node left; Node right; } 排序二叉树 所谓排序二叉树,顾名思义,排序二叉树是有顺序的,它是一种特殊结构的二叉树,我们可以对树中所有节点进行排序和检索。 性质 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若她的右子树不空,则右子树上所有节点的值均大于它的根节点的值; 具有递归性,排序二叉树的左子树、右子树也是排序二叉树。 排序二叉树简单示意图: 排序二叉树退化成链表 排序二叉树的左子树上所有节点的值小于根节点的值,右子树上所有节点的值大于根节点的值,当我们插入一组元素正好是有序的时候,这时会让排序二叉树退化成链表。 正常情况下,排序二叉树是如下图这样的: 但是,当插入的一组元素正好是有序的时候,排序二叉树就变成了下边这样了,就变成了普通的链表结构,如下图所示: 正常情况下的排序二叉树检索效率类似于二分查找,二分查找的时间复杂度为 O(log n),但是如果排序二叉树退化成链表结构,那么检索效率就变成了线性的

Java集合框架常见面试题

给你一囗甜甜゛ 提交于 2019-12-16 14:56:15
点击关注 公众号 及时获取笔主最新更新文章,并可免费领取本文档配套的《Java面试突击》以及Java工程师必备学习资源。 剖析面试最常见问题之Java基础知识 说说List,Set,Map三者的区别? Arraylist 与 LinkedList 区别? 补充内容:RandomAccess接口 补充内容:双向链表和双向循环链表 ArrayList 与 Vector 区别呢?为什么要用Arraylist取代Vector呢? 说一说 ArrayList 的扩容机制吧 HashMap 和 Hashtable 的区别 HashMap 和 HashSet区别 HashSet如何检查重复 HashMap的底层实现 JDK1.8之前 JDK1.8之后 HashMap 的长度为什么是2的幂次方 HashMap 多线程操作导致死循环问题 ConcurrentHashMap 和 Hashtable 的区别 ConcurrentHashMap线程安全的具体实现方式/底层具体实现 JDK1.7(上面有示意图) JDK1.8 (上面有示意图) comparable 和 Comparator的区别 Comparator定制排序 重写compareTo方法实现按年龄来排序 集合框架底层数据结构总结 Collection 1. List 2. Set Map 如何选用集合? 剖析面试最常见问题之Java基础知识

【算法笔记】跳表

橙三吉。 提交于 2019-12-16 05:01:21
跳表 1.如何理解“跳表”? 2.用跳表查询到底有多快?-时间复杂度 3.跳表是不是很浪费内存?-空间复杂度 4 高效的动态插入和删除 5 跳表索引动态更新 6 为什么 Redis 要用跳表来实现有序集合,而不是红黑树? 7 总结 1.如何理解“跳表”? 这种链表加多级索引的结构,就是跳表; 2.用跳表查询到底有多快?-时间复杂度 每两个结点会抽出一个结点作为上一级索引的结点,那第一级索引的结点个数大约就是 n/2,第二级索引的结点个数大约就是 n/4,第三级索引的结点个数大约就是 n/8,依次类推,也就是说,第 k 级索引的结点个数是第 k-1 级索引的结点个数的 1/2,那第 k级索引结点的个数就是 n/(2^k)。 假设索引有 h 级,最高级的索引有 2 个结点。通过上面的公式,我们可以得到 n/(2^h)=2,从而求得 h=log2n-1。如果包含原始链表这一层,整个跳表的高度就是 log2n。我们在跳表中查询某个数据的时候,如果每一层都要遍历 m 个结点,那在跳表中查询一个数据的时间复杂度就是 O(m*logn)。 每一级索引都最多只需要遍历 3 个结点,也就是说 m=3; m=3的详细解释: 假设我们要查找的数据是 x,在第 k 级索引中,我们遍历到 y 结点之后,发现 x 大于 y,小于后面的结点 z,所以我们通过 y 的 down 指针,从第 k 级索引下降到第 k

日常总结

六眼飞鱼酱① 提交于 2019-12-16 03:00:51
集合:List(列表)存储元素有序,就可以重复(ArrayList,LinkedList,Vector) ArrayList:10 2n 不安全 LinkedList: 不安全 Vector:10 2n 安全 Set(集合)存储元素无序,不可以重复(HashSet,LinkedHashSet,TreeSet,) HashSet:16 0.75 2n 不安全 底层是HahsMap TreeSet:会对存入的元素进行排序(升序) 不安全 Queue(队列)先进先出的原则 映射Map: HashMap 安全 底层数组+链表+红黑二叉树,桶:数组里的每个元素空间叫做桶 当我们需要放入元素,通过put方法传入键值对,首先回去计算键的哈希码值,算出hash码值后,对桶数(默认初始容量)进行取余,这样会保证键值对会放到每个桶中,得到桶值,会把键值对放入桶中,完成元素的添加,当需要删除元素时,调用get方法回去键的eauals方法找到正确的值,进行返回。 如果计算出key的hash值一样时,会产生hash冲突,俩个元素要放入同一个桶中,此时有四种解决办法: 链地址法:会把hash值相同的元素链接起来, 新对象会和桶里面的所有元素用equals比较, 相同,会不存储, 不同,会链接起来,形成链表,当链接的数量多于8个,会转换成红黑树进行存储。 建立公共溢出区:将hash表分为俩部分,基本表和溢出表

TreeMap

耗尽温柔 提交于 2019-12-16 00:48:07
TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。 TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。 TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。 TreeMap 实现了Cloneable接口,意味着它能被克隆。 TreeMap 实现了java.io.Serializable接口,意味着它支持序列化。 TreeMap基于红黑树(Red-Black tree)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。 另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fastl的。 TreeMap构造函数 1234567891011 // 默认构造函数。使用该构造函数,TreeMap中的元素按照自然排序进行排列。TreeMap()// 创建的TreeMap包含MapTreeMap(Map<? extends K, ? extends V> copyFrom)// 指定Tree的比较器TreeMap(Comparator<? super

HashMap你了解多少

橙三吉。 提交于 2019-12-16 00:03:18
HashMap几乎是面试必问的知识,对于HashMap面试是你真的能从容面对吗?相信如果你去面试知名互联网公司的时候,决对不会只是问问你HashMap的数据结构这么简单的问题。我收集了最近老大在面试过程中关于HashMap常问的几个问题: 1. 为什么HashMap是2的幂次方? new HashMap(14); HashMap是由数组+链表(1.8还有红黑树)来实现的,那么上面这行代码它执行后,创建的数组大小是多少呢? 追踪源码可以看到它会执行这样一个函数来返回数组大小的: static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; } 图解: 第一次右移并且或运算,可以保证从左到右第一位1后面再多出来一个1 第二次右移并且或运算,可以保证从左到右再多出两个1 以此类推,因为java中int值是4个字节,32位的,所以最后移16位的时候,足以保证2^32这种情况的出现; 通过这个函数的运算,可以将我们传入的14运算得到16

Mysql索引原理

一曲冷凌霜 提交于 2019-12-15 23:56:40
说起Mysql就离不开SQL优化,说起优化就离不开索引,那么什么是索引?为什么加了索引就可以快?那接下来我们就一起来探讨一下索引相关的知识! 一、数据结构中常见的索引 【对这块数据结构了解的同学建议跳过本节】 1.二叉树 说起二叉树,我们都知道每个结点最多只能有两个子结点,例如: 可以发现二叉树很有规律,左子结点小于当前结点,右子结点大于当前结点。那这样不是查询起来很方便呢?二叉树的性质决定了它的时间复杂度为 Olog(n),当然,二叉树的时间复杂度与它的插入顺序有着,如果按升序或降序的方式插入数据,那么它的二叉树的高度h就与结点个数相等了,此时复杂度就提高到了O(n)。 假如,数据库使用二叉树来做索引,此时需要插入1000条数据,我们来计算一下这树的高度。(深度为k的二叉树最少有k个结点,最多有2^k-1个结点) 2^10-1 ≈ 1000 此时树的高度约为10 最差的情况,树的高度为1000 树的高度决定了查询的效率,而二叉树又会存在高度10~1000这么大的差距,很明显它已经不适合做我们的索引了! 2.平衡树 前面把问题摆出来了,二叉树的高度很不稳定,那我们能不能把高度稳定一下呢?这就是平衡树,它会根据插入的情况,动态的调整二叉树的高度( 左右子树的高度最多差1 ),比如:我们插入从10,9,8,,,1 看,我没有骗你吧,它会根据插入的情况调整树的高度,具体怎么调整的