红黑树

ConcurrentHashMap源码解析 JDK8

*爱你&永不变心* 提交于 2020-01-14 17:33:54
一、简介 上篇文章 详细介绍了HashMap的源码及原理,本文趁热打铁继续分析ConcurrentHashMap的原理。 首先在看本文之前,希望对HashMap有一个详细的了解。不然看直接看ConcurrentHashMap的源码还是有些费劲的。 相信对HashMap,HashTable有一定了解,应该知道HashMap是不具备线程安全性的,在resize时会丢数据(JDK8),而HashTable虽然保证了线程安全性,但是其是通过给每个方法加Synchronized关键字达到的同步目的。但是都知道Synchronized在竞争激烈的多线程并发环境中,在性能上的表现是非常不如人意的。那在高并发环境中HashMap如何保证线程安全而又不浪费太多性能呢?答案就是Java J.U.C并发包中的ConcurrentHashMap。 依然开局一张图。JDK8中的ConcurrentHashMap数据结构。 呃呵,和HashMap的结构是一样的,没错在数据结构层面,ConcurrentHashMap和HashMap是完全一样的。有了这个基础继续往下看。 二、历史版本 ConcurrentHashMap的历史版本大致分界线在JDK8。也就是可以分为JDK8和JDK8以前版本。 数据结构的区别 在JDK8之前HashMap没有引入红黑树,同样的ConcurrentHashMap也没有引入红黑树

从B树、B+树、B*树谈到R 树

。_饼干妹妹 提交于 2020-01-13 05:09:46
http://blog.csdn.net/v_july_v/article/details/6530142 第一节、B树、B+树、B*树(原文部分摘录) 1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree), 红黑树 (Red-Black Tree ),B-tree/B + -tree/ B * -tree (B~Tree)。前三者是典型的二叉查找树结构,其查找的时间复杂度 O (log 2 N )与树的深度相关,那么降低树的深度自然会提高查找效率。 但是咱们有面对这样一个实际问题:就是大规模数据存储中,实现索引查询这样一个实际背景下,树节点存储的元素数量是有限的(如果元素数量非常多的话,查找就退化成节点内部的线性查找了),这样导致二叉查找树结构由于 树的深度过大而造成磁盘I/O读写过于频繁,进而导致查询效率低下 (为什么会出现这种情况,待会在外部存储器-磁盘中有所解释),那么如何减少树的深度(当然是不能减少查询的数据量),一个基本的想法就是:采用 多叉树 结构(由于树节点元素数量是有限的,自然该节点的子树数量也就是有限的)。 也就是说,因为磁盘的操作费时费资源,如果过于频繁的多次查找势必效率低下。那么如何提高效率,即如何避免磁盘过于频繁的多次查找呢

深刻理解二叉树、红黑树、B-tree、B+tree

人走茶凉 提交于 2020-01-11 05:36:12
一 理解索引的特性 索引是帮助MySQL高效获取数据的排好序的数据结构 索引存储在文件里 二 索引的各种存储结构及其优缺点 在开始讲这一小节之前,我们先来看一下在数据库没有加索引的情况下,SQL中的where字句是如何查找目标记录的。 我们先看下左边表格第二列Col2列的数据时如何查找的,如果我们希望查找where Col2 = 22的记录,我们在没加索引的情况下是按顺序从第一条记录查找,由此可知需要查找5次才能找到; 如果对Col2字段加上索引后,我们假设使用最简单的二叉树作为索引存储方式,再次查找where Col2 = 22的记录这次只需要查找2次就能找到目标记录,效率提高十分明显。 (一) 二叉树 1. 优点: 二叉树是一种比顺序结构更加高效地查找目标元素的结构,它可以从第一个父节点开始跟目标元素值比较,如果相等则返回当前节点,如果目标元素值小于当前节点,则移动到左侧子节点进行比较,大于的情况则移动到右侧子节点进行比较,反复进行操作最终移动到目标元素节点位置。 2. 缺点: 在大部分情况下,我们设计索引时都会在表中提供一个自增整形字段作为建立索引的列,在这种场景下使用二叉树的结构会导致我们的索引总是添加到右侧,在查找记录时跟没加索引的情况是一样的,如下图所示: (二) 红黑树 1. 优点: 红黑树也叫平衡二叉树,它不仅继承了二叉树的优点

LeetCode 1 两数之和(哈希map)

你离开我真会死。 提交于 2020-01-10 13:13:14
1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 ****暴力解法:**** vector < int > twoSum ( vector < int > & nums , int target ) { int len = nums . size ( ) ; //vector的容器大小是size() vector < int > result ; //用来存放最后的结果 for ( int i = 0 ; i < len ; i ++ ) //遍历数组,固定一个位置找另一个位置 { int k = target - nums [ i ] ; for ( int j = i + 1 ; j < len ; j ++ ) { if ( nums [ j ] == k ) { result . push_back ( i ) ; result . push_back ( j ) ; } } } return result ; } 暴力法思路很简单,就是固定一个位置i,然后在数组中查找target-nums[i]的位置,找到返回即可 时间复杂度是O(n^2); **哈希解法:** 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说

红黑树(一)之 原理和算法详细介绍

隐身守侯 提交于 2020-01-10 08:16:08
概要 前面分别介绍红黑树的 理论知识 、红黑树的 C语言 和 C++的实现 。本章介绍红黑树的Java实现,若读者对红黑树的理论知识不熟悉,建立先学习 红黑树的理论知识 ,再来学习本章。还是那句老话,红黑树的C/C++/Java实现,原理一样,择其一了解即可。 目录 1. 红黑树的介绍 2. 红黑树的Java实现(代码说明) 3. 红黑树的Java实现(完整源码) 4. 红黑树的Java测试程序 转载请注明出处: 更多内容: 数据结构与算法系列 目录 (01) 红黑树(一)之 原理和算法详细介绍 (02) 红黑树(二)之 C语言的实现 (03) 红黑树(三)之 Linux内核中红黑树的经典实现 (04) 红黑树(四)之 C++的实现 (05) 红黑树(五)之 Java的实现 (06) 红黑树(六)之 参考资料 红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树。 红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键值,小于等于右孩子的键值。 除了具备该特性之外,红黑树还包括许多额外的信息。 红黑树的每个节点上都有存储位表示节点的颜色,颜色是红(Red)或黑(Black)。 红黑树的特性: (1) 每个节点或者是黑色,或者是红色。 (2) 根节点是黑色。 (3) 每个叶子节点是黑色。

面试的一些东西

☆樱花仙子☆ 提交于 2020-01-10 03:59:19
先是聊项目,从项目的架构设计到部署流程。 Java容器有哪些?哪些是同步容器,哪些是并发容器? ArrayList和LinkedList的插入和访问的时间复杂度? Java反射原理, 注解原理? 新生代分为几个区?使用什么算法进行垃圾回收?为什么使用这个算法? HashMap在什么情况下会扩容,或者有哪些操作会导致扩容? HashMap push方法的执行过程? HashMap检测到hash冲突后,将元素插入在链表的末尾还是开头? 1.8还采用了红黑树,讲讲红黑树的特性,为什么人家一定要用红黑树而不是AVL、B树之类的? https和http区别,有没有用过其他安全传输手段? 线程池的工作原理,几个重要参数,然后给了具体几个参数分析线程池会怎么做,最后问阻塞队列的作用是什么? Linux怎么查看系统负载情况? 请详细描述springmvc处理请求全流程? 讲一讲AtomicInteger,为什么要用CAS而不是synchronized? 查询中哪些情况不会使用索引? 数据库索引,底层是怎样实现的,为什么要用B树索引? Mysql主从同步的实现原理? MySQL是怎么用B+树? 谈谈数据库乐观锁与悲观锁? 有使用过哪些NoSQL数据库?MongoDB和Redis适用哪些场景? 描述分布式事务之TCC服务设计? Redis和memcache有什么区别

红黑树——自平衡过程

与世无争的帅哥 提交于 2020-01-10 01:32:23
红黑树的概念,这里不做阐述。网上一抓一大把。本文仅以个人的理解介绍一下红黑树自平衡的过程。 红黑树的性质: 性质1:每个节点要么是黑色,要么是红色。 性质2:根节点是黑色。 性质3:每个叶子节点(NIL)是黑色。 性质4:每个红色结点的两个子结点一定都是黑色。 性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑 自平衡所需要的操作,无非是变色,左旋,右旋。变色不用多说,黑变红红变黑。关于左旋,先附上网上找到的一个图 图片来源: http://www.360doc.com/content/18/0904/19/25944647_783893127.shtml 由于红黑树本身是一棵二叉搜索树,即左子树的所有节点值都小于自己,右子树的所有节点值都大于自己。于是,在旋转过程,把y提为本子树的根节点时,由于y原来是x的右孩子,y > x,x成为y的左孩子。y原本的左孩子b就得给x腾出位置,x的右节点恰好空了出来。b原为x的右子树成员,b > x,成为x的右孩子很合理。 关于右旋,原理相同。 图片来源: http://www.360doc.com/content/18/0904/19/25944647_783893127.shtml 现在开始说明红黑树的自平衡。 首先是插入节点的着色。所有关于红黑树自平衡的介绍都说,插入的节点为红色。至于为什么,笔者认为,由于性质3与性质5

红黑树学习笔记

限于喜欢 提交于 2020-01-09 02:47:40
红黑树学习笔记 红黑树是一种二叉查找树,接近平衡的,确保没有一条路径比其他路径长2倍。 性质: 1)每个结点要么是红的,要么是黑的。 2)根结点是黑的。 3)每个叶子结点,即空结点是黑的,叶子是NIL结点 4)如果一个结点是红的,那么他的两个孩子是黑的 5)对每个结点,从该结点到其子孙结点的所有路径包含相同数目的的黑结点 性质4暗示着任何一个简单路径上不能有两个毗连的红色节点,这样,最短的可能路径全是黑色节点,最长的可能路径有交替的红色和黑色节点。同时根据性质5知道:所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。 插入操作: 1)查找要插入的位置,O(n),其操作跟二叉查找树一样。 2)将新结点的color设置为red 3)自下而上调整树为红黑树 插入情况: 1)新的结点N位于树的根上,没有父节点: node n; n->color = red; void inster_case1(node n) { if(n->parent == NULL) n->color = black; else insert_case2(n); } 2)父亲结点为黑色P: void inster_case2(node n) { if(n->parent->color == black) return ; else inster_case3(n); } 3)父节点P

算法——几种查找算法的比较和应用

孤街醉人 提交于 2020-01-08 23:30:08
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 几种基础查找方法的 性能比较 : 算法(数据结构) 查找(最坏) 插入(最坏) 查找命中(平均) 插入(平均) 插入(平均)是否支持有序性相关操作 顺序查询(无序联播) N N N/2 N 否 二分查找(有序数组) lgN N lgN N/2 是 二叉树查找(二叉查找树) N N 1.39lgN 1.39lgN 是 2-3树查找(红黑树) 2lgN 2lgN 1.00lgN 1.00lgN 是 拉链法(链表数组) <lgN <lgN N/(2M) N/M 否 线性探测法(并行数组) clgN clgN <1.5 <2.5 否 顺序查找 :在表中查找一个不存在的键时,我们会将表中每个键和给定的键比较(N)。因为不允许出现重复的键,每次插入操作之前我们都需要这样查找一遍。 推论: 向一个空表中插入N个不同的键需要~N²/2次比较。 二分查找 :在N个键的有序数组中进行二分查找最多需要(lgN+1)次比较(无论是否成功)。插入一个新的元素在最坏情况下要访问~2N次数组。 推论: 向一个空表中插入N个不同的键需要~N²/2次比较。 二叉树查找 :使用二叉查找树的算法运行时间取决于树的形状。最好的情况下含有N个节点的树是完全平衡的,每条空链和根节点的距离都为~lgN;最坏情况下,搜索路径上可能有N个节点

HashMap实现原理JDK1.8

爱⌒轻易说出口 提交于 2020-01-08 10:55:24
在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>实现了Entry接口 1 //Node是单向链表,它实现了Map.Entry接口 2