红黑树

简单理解红黑树

旧街凉风 提交于 2019-12-29 18:40:58
在升级到JDK8之后,HashMap在列表个数大于8个时候,采用了红黑树来实现。面试的时候经常会问到我们一些红黑树的问题。那么我们首先要知道什么是红黑树。 红黑树性质定义 红黑树也是二叉查找树,我们知道二叉查找树的结构并不难,而红黑树就是难在它是自平衡的二叉树。它必须满足以下性质: 1.每个节点要么黑色要么红色。 2.根节点必需是黑色。 3.每个叶子节点(NIL)是黑色。 4.每个红色节点的两个子节点一定都是黑色。 5.任意一节点到每个叶子节点的路径都包含了数量相同的黑色节点。 我们知道在由随机数节点组成的二叉树的平均高度为logn,所以正常情况下二叉树查找的时间复杂度为O(logn)。但是,根据二叉树的特性,在最坏的情况下,比如存储的是一个有序的数据的话,那么所以的数据都会形成一条链,此时二叉树的深度为n,时间复杂度为O(n)。红黑树就是为了解决这个问题的,它能够保证在任何情况下树的深度都保持在logn左右。为什么这么说呢,我们由他的性质总结出一个隐含性质:从根节点到叶子节点的最长路径不大于最短路径的 2 倍。 红黑树的增加和删除 我们在将红黑树的增加和删除的时候首先要了解3种操作 1.变色:节点的颜色由红色变为黑色或者黑色变为红色。 2.左旋:以某个节点为旋转点,其右子节点变为旋转点的父节点。右子节点的左子节点变为旋转点的右子节点,旋转点的左子节点保持不变。如下图 3.右旋

Java中HashMap底层实现原理(JDK1.8)源码分析

*爱你&永不变心* 提交于 2019-12-28 17:46:16
Java中HashMap底层实现原理(JDK1.8)源码分析 ​ 在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树**,这样大大减少了查找时间。 简单说下HashMap的实现原理: 首先有一个每个元素都是链表(可能表述不准确)的数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一个hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,它们在数组的同一位置,但是形成了链表,同一个链表上的Hash值是相同的,所以说数组存放的是链表。而当链表长度太长时,链表就转换为红黑树,这样大大提高了查找的效率。 当链表数组的容量超过初始容量的0.75时,再散列表将链表数组扩大2倍,把原链表数组搬移到新的数组中,即HashMap的原理图是: 一.JDK1.8中涉及到的数据结构 1.位桶数组 transient Node < k , v > [ ] table ; //存储(位桶)的数组</k,v> 2,数组元素Node<K,V

集合Collection接口

早过忘川 提交于 2019-12-28 14:31:08
集合Collection接口: 是所有单列集合的最顶层接口 add()方法返回的意思是是否添加成功,添加动作是一定成功的。但是对于其他集合,添加不一定成功 分为list接口和set接口 List接口有序的(存储123,取出也是123),可以重复,有索引 有索引,可以使用普通for循环遍历 **set接口无序不可重复** 没有索引,不能使用带索引的方法,不能使用普通for循环遍历 哈希值:他是一个10进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来的地址,不是数据实际存储的物理地址) 在Object类有一个方法,可以获取对象的哈希值 HashSet的查询速度非常快,先把元素按照相同的哈希值分组,相同的哈希值把它挂到下面, 超过8位把他转换为红黑树 HashSet集合存储数据的结构(哈希表) jdk1.8之前:哈希表=数组+链表 jdk1.8版本之后:哈希表也等于数组加链表,链表变成了红黑树,数组+红黑树(提高查询的速度)如果链表长度超过了8位,那么就会把链表转换为红黑树 哈希表的特点:速度快 HashSet集合不允许重复的原理 只要是new的,就会把他们存储到堆内存当中,Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法,通过hashCode方法计算元素的哈希值,判断元素是否重复 来源: CSDN 作者: 黄大仙Ol

数据结构:Skip List--跳表

孤人 提交于 2019-12-28 06:48:47
本文为转载,原文作者:fanrui 原文链接: 简书 https://www.jianshu.com/p/9d8296562806 跳表是一种神奇的数据结构,因为几乎所有版本的大学本科教材上都没有跳表这种数据结构,而且神书《算法导论》、《算法第四版》这两本书中也没有介绍跳表。但是跳表插入、删除、查找元素的时间复杂度跟红黑树都是一样量级的,时间复杂度都是O(logn),而且跳表有一个特性是红黑树无法匹敌的(具体什么特性后面会提到)。所以在工业中,跳表也会经常被用到。废话不多说了,开始今天的跳表学习。 通过本文,你能 get 到以下知识: 什么是跳表? 跳表的查找、插入、删除元素的流程 跳表查找、插入、删除元素的时间复杂度 跳表插入元素时,如何动态维护索引? 为什么Redis选择使用跳表而不是红黑树来实现有序集合? 工业上其他使用跳表的场景 友情提示:下文在跳表插入数据时,会讲述如何动态维护索引,实现比较简单,逻辑比较绕,不要放弃,加油!!!如果一遍看不懂没关系,可以选择暂时性的跳过,毕竟这块偏向于源码。但是读者必须知道跳表的查找、插入、删除的时间复杂度都是 O(logn),而且可以按照范围区间查找元素,当工作中遇到某些场景时,需要想到可以使用跳表解决问题即可。毕竟平时的工作都是直接使用封装好的跳表,例如:java.util.concurrent 下的

HashMap和HashTable

倾然丶 夕夏残阳落幕 提交于 2019-12-28 03:07:00
JAVA的基础知识:数据结构(Map,List,Set等),设计模式,算法,线程相关,IO/NIO,序列化等等 其次是高级特征:反射机制,并发与锁,JVM(GC策略,类加载机制,内存模型)等等 举个例子 就比如问你:HashMap 是不是有序的? 你回答不是有序的。那面试官就会可能继续问你,有没有有序的Map实现类呢? 你如果这个时候说不知道的话,那这块问题就到此结束了。如果你说有TreeMap和LinkedHashMap。 那么面试官接下来就可能会问你,TreeMap和LinkedHashMap是如何保证它的顺序的? 如果你回答不上来,那么到此为止。 如果你说TreeMap是通过实现SortMap接口,能够把它保存的键值对根据key排序,基于红黑树,从而保证TreeMap中所有键值对处于有序状态。 LinkedHashMap则是通过插入排序(就是你put的时候的顺序是什么,取出来的时候就是什么样子)和访问排序(改变排序把访问过的放到底部)让键值有序。 1、为什么用HashMap? HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射 HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改 HashMap是非synchronized,所以HashMap很快 HashMap可以接受null键和值

HashMap源码记录1|火影凡酷

☆樱花仙子☆ 提交于 2019-12-26 12:07:58
前言:由于笔者所在的公司用的是jdk1.8,故该源码是针对1.8分析的。 首先:我们看一张长的很丑的HashMap的结构图: 再看看几个核心的常量: 复制代码 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 默认初始化容器大小,当自己指定容器大小时,必须为2的幂次方 static final int MAXIMUM_CAPACITY = 1 << 30; //容器的最大容量值 static final float DEFAULT_LOAD_FACTOR = 0.75f; //加载因子 static final int TREEIFY_THRESHOLD = 8; //把桶中链表转换为红黑树的阈值 static final int UNTREEIFY_THRESHOLD = 6; //把红黑树转换成链表的阈值 static final int MIN_TREEIFY_CAPACITY = 64; //最小的表容量使桶被树化,当表的容量小于该值时,先扩容解决hash冲突而不是树化 复制代码 putVal()方法: 复制代码 1 /** 2 * 实现Map.put和相关方法 3 * 4 * @param hash 根据key计算出来的hash值 5 * @param key 键 6 * @param value 值 7 *

数据结构树之红黑树

纵饮孤独 提交于 2019-12-26 08:13:59
红黑树简介:   红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是RED 或 BLACK。通过对任何一条根到叶子的简单路径上各个结点的颜色进行约束,红黑树确保没有一条路径回避其他路径长处2倍,因而是近似平衡的。   树的每个结点包含 5 个属性:color,key,left,right和p。如果一个结点没有子结点或者父结点,则该结点相应的指针属性的值为NULL。我们可以把这些NULL视为指向二叉搜索树叶结点的指针,而把带关键字的结点视为树的内部结点。 红黑树的性质:   一棵红黑树是满足下面红黑性质的二叉搜索树:   1.每个结点或是红色的,或是黑色的   2.根节点是黑色的   3.每个叶结点(NULL)是黑色的   4.如果一个结点是红色的,那么他的两个子结点都是黑色的   5.对于每个结点,从该结点到其所有后代叶结点的简单路径上,包含相同数目的黑色结点   这 5 个性质中1,2,4都比较好理解。3与我们常说的(大部分数据结构书上说的)叶结点有一点点区别,如下图:    那性质5又是什么意思呢?我们再来看一个图:      由红黑树的 5 个性质可知,上幅图中左图是红黑树,而右图非红黑树。右图中满足红黑树的性质1.2.3.4,但是不满足性质5:从根节点6(不包括根节点)到各叶结点的简单路径上的黑色黑色结点个数并不相等。例如:6-1有2个,而6

我的腾讯技术面试经历(3)

梦想与她 提交于 2019-12-25 14:20:24
  9月19号下午,腾讯游戏的hr就打电话过来约定好下周一下午去深圳面试了。面试者的往返交通、住宿费用全部可以报销,不禁感叹大公司果然是有钱啊!   其实在投简历之前没想太多,但在过了两轮电面后,终于开始重视起来,进腾讯的机会很大了!   整整周六日两天时间,都在面试做准备。刚开始担心面试是否会考察计算机原理,汇编,计算机网络,数据库方面的东西,因为这些基本忘光了。最后只是简单回顾了一下,把准备重心放在简历上提到的点。还是看专业能力说话!   于是把LeetCode之前刷过的题过了一遍;数据结构过了一遍,专门看了July几篇经典文章:海量数据处理、各种b树和红黑树;把做过的几个项目的底层又研究了一遍,重看了下pureMVC,robotlegs框架;学习prtocol buffer;连搭和谐号回深圳都拿着macbook重温23个设计模式的思想和实现例子。奋斗了两天,一度有回到高考的感觉,不禁感叹考试永远是逼人学习的最有效方式啊! —————————————————————————————————————————   事实证明,这两天做的准备用处还是很大的。整个下午连续进行了4面:其中3轮技术面。   腾讯游戏不在腾讯大厦总部,而是在附近的科兴科学园。2点多提前到腾讯,来接了我的人是一面面试官,简单聊了下,他做了3,4年as3,3年前来腾讯,然后竟然也是从我现在的公司跳过去的(3

Java集合类--HashMap

烂漫一生 提交于 2019-12-25 14:07:36
一、HashMap基本源码实现 1、HashMap基本结构 HashMap继承AbstractMap抽象类,AbstractMap实现Map接口。 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { private static final long serialVersionUID = 362498820763181265L; .... } public abstract class AbstractMap<K,V> implements Map<K,V> { protected AbstractMap() { } ... } 二、HashMap的基本数据结构 jdk1.8之前,HashMap是由“数组+链表”的结构组成,jdk1.8之后,HashMap得到很大的改善;数据结构也发生了改变:“数组+链表+红黑树”;当链表节点大于8时,会转换为红黑树;否则仍然以链表结构。 头节点指的是table表上索引位置的节点,也就是链表的头节点 根节点(root节点)指的是红黑树最上面的那个节点,也就是没有父节点的节点 红黑树的根节点不一定是索引位置的头节点 转为红黑树节点后,链表的结构还存在,通过next属性维持

java实现数据结构13(红黑树详解代码之自定义红黑树)

落花浮王杯 提交于 2019-12-25 05:17:36
自定义红黑树 import com . sun . org . apache . regexp . internal . RE ; /** * @description: 自定义红黑树 * @author: liangrui * @create: 2019-12-24 13:50 **/ public class RedBlackTree < K extends Comparable < K > , V > { private static final boolean RED = true ; private static final boolean BLACK = false ; private class Node { public K key ; public V value ; public Node left , right ; public boolean color ; public Node ( K key , V value ) { this . key = key ; this . value = value ; left = null ; right = null ; color = RED ; } } private Node root ; private int size ; public RedBlackTree ( ) { root = null ;