链表

jdk8 ConcurrentHashMap分析

孤人 提交于 2020-03-20 08:02:04
ConcurrentHashMap分析 tryPresize() transfer() putVal() addCount() sumCount() class ConcurrentHashMap { /** * Tries to presize table to accommodate the given number of elements. * * @param size number of elements (doesn't need to be perfectly accurate) */ private final void tryPresize(int size) { // 当size未达到MAXIMUM_CAPACITY时,扩容size。调用tableSizeFor(), // 此处size + (size >>> 1) + 1 == size*1.5+1,注意, size = table.length << 1 // 传进来的size已经提前扩容了2倍 // c == 2**n int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : tableSizeFor(size + (size >>> 1) + 1); int sc; // 判断条件,sizeCtl >=0 说明

ConcurrentHashMap源码解析(1.8)

末鹿安然 提交于 2020-03-20 07:58:47
一、简介 上篇文章 详细介绍了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也没有引入红黑树

C++双向链表

生来就可爱ヽ(ⅴ<●) 提交于 2020-03-20 05:11:57
   本文C++实现的关于双向链表的增删查改操作,收获颇多,第一篇博客请多指教。 定义节点类型 1 struct Number{ 2 int data; 3 Number* next; 4 Number* previous; 5 }; 定义一个链表类 class LinkList{ private: Number *head; Number *tail; int length; public: LinkList(); void headInsert(int data); void tailInsert(int data); void display_HeadToTail(); void display_TailToHead(); Number * findNumber(int data); void change(Number*); void quit(); }; 构造函数 LinkList::LinkList(){ head = NULL; tail = head; length = 0; } 头插函数 void LinkList::headInsert(int data){ Number * node = new Number(); node->data=data; if(head!=NULL){ head->previous=node; node->next=head;

小学数学题,你会吗?

自闭症网瘾萝莉.ら 提交于 2020-03-20 04:29:07
  一日,某小学生问作业:“将16分解为若干素数的和,求这些素数积的最大值”。不禁被吓了一跳。怎么小学生的数学题变得这么难了?   细细询问,小学生没学不等式,没学数学归纳法……。那么只能用最笨的办法——穷举,一个个地试的办法来解决。   穷举之道,在于一一举来,不多不少;而不多不少,则在于有条有理,从容不乱。   小于16的素数依次为:2,3,5,7,11,13。显然,最大积是16和{2,3,5,7,11,13}的函数,将这个最大积记为     F(16,{2,3,5,7,11,13})   该最大积中可能有素因子2也可能没有,因此     F(16,{2,3,5,7,11,13}) =      MAX (          2 * F(14 ,{2,3,5,7,11,13}) ,         F(16 ,{3,5,7,11,13} ) ,       )   同理,      F(14,{2,3,5,7,11,13}) =       MAX (           2 * F(12 ,{2,3,5,7,11,13}) ,           F(14 ,{3,5,7,11,13} ) ,       )      F(16,{3,5,7,11,13}) =       MAX (           3 * F(3 ,{2,3,5,7,11,13}) ,       

leetcode61(旋转链表)--C语言实现

ぐ巨炮叔叔 提交于 2020-03-20 00:04:53
3 月,跳不动了?>>> 求: 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。 示例 1: 输入: 1->2->3->4->5->NULL, k = 2 输出: 4->5->1->2->3->NULL 解释: 向右旋转 1 步: 5->1->2->3->4->NULL 向右旋转 2 步: 4->5->1->2->3->NULL 示例 2: 输入: 0->1->2->NULL, k = 4 输出: 2->0->1->NULL 解释: 向右旋转 1 步: 2->0->1->NULL 向右旋转 2 步: 1->2->0->NULL 向右旋转 3 步: 0->1->2->NULL 向右旋转 4 步: 2->0->1->NULL 解: /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* rotateRight( struct ListNode* head, int k){ int size= 0 ; int i; struct ListNode* p1; struct ListNode* p2; for (p1=head;p1!=NULL;p1=p1->next)

两个有序链表合成一个有序链表

元气小坏坏 提交于 2020-03-19 12:03:06
1 #include<iostream> 2 #include<cstdlib> 3 using namespace std; 4 #define MAXa 5//La链表中的元素数量 5 #define MAXb 7//Lb链表中的元素数量 6 typedef struct node{//定义链表中的节点 7 int data;//存储数据 8 struct node *next;//存储指向下一个节点的指针 9 }Lnode; 10 void creatlist(Lnode *head, int *arr, int n);//创建链表 11 void printlist(Lnode *head);//打印链表 12 void mergelist(Lnode *headA, Lnode *headB, Lnode *headC);//合并链表 13 int main(){ 14 int a[MAXa] = { 1, 3, 5, 7, 9 };//先将元素存储到数组中,再存到链表中 15 int b[MAXb] = { 2, 4, 6, 8, 10 ,11,45}; 16 Lnode *La, *Lb, *Lc;//分别定义La链表、Lb链表、Lc链表的头节点 17 La = (Lnode*)malloc(sizeof(Lnode));//动态分配空间 18 La->next =

leetCode #2 简单题(链表)

徘徊边缘 提交于 2020-03-19 04:59:02
题目:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 题解:就指向两个链表的头的指针依次向后遍历、算和的余数,记录一下进位。如果L1先遍历到末尾的话,就把L1最后一个指针指向L2当前的next,即把L2剩余的部分接在L1的结尾。这样可以节省不少开辟新Node的空间,然后继续用进位和L1当前Node的值求和,记录进位。如果此时到了L1的末尾还有进位,就new一个新的Node加个结尾就行了。为了快点写完,代码有点丑,将就看吧,以后如果不懒的话再优化一下。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { int toNextNum = 0; ListNode* beginNode = l1;

面试题 23:链表中环的入口节点

最后都变了- 提交于 2020-03-18 23:58:28
3 月,跳不动了?>>> 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。 思路 书中解法 查询是否有环,设定两个指针,第一个慢指针每次走一步,第二个快指针每次走两步。当快指针超过慢指针时,即链表中有环。 查询环中的节点数,可从 1 中获得在环中的某个节点,通过这个节点循环遍历,可以回到此节点,由此计算节点数 nodesInLoop。 从链表头开始,设定两个指针,第一个指针先走环中节点数 nodesInLoop 次数,然后第二个指针与第一个指针开始同时遍历,每次走一步,到两指针相会时,所指向的节点即为入口节点。 其他解法 双指针法 https://leetcode-cn.com/problems/linked-list-cycle-ii/ 代码 书中解法 public class Solution { public ListNode detectCycle(ListNode head) { ListNode meetingNode = meetingNode(head); // 链表中无环,直接返回 null if (meetingNode == null) { return null; } // 得到环中节点的数目 int nodesInLoop = 1; ListNode pNode1 = meetingNode; while (pNode1

小学期编码体会

那年仲夏 提交于 2020-03-18 21:24:48
这一周都在忙着敲小学期的作业代码,原本幻想着一天一道题的进度完成,结果被前两道系统题搞得焦头烂额的,光是定义一个student的类,就写了好多行,功能的实现也只是一部分,简单的录入与查询,然后剩下的文件导入什么的都不太清楚,上网搜索,查询。看别人写的程序,函数的使用,还有链表。看了好多资料,还是没有搞明白。链表的数据域,插入元素,感觉好高深。 好在后面的题目还不是很麻烦,像是三角形类别判断,只需要把数据,按坐标输入,计算出三边长度,就能判断是否可以构成三角形,再进行对等边三角形,等腰三角形,直角三角形等类别,进行分类。还是挺轻松的。人机下棋那道题,写出来自己跟电脑下,虽然游戏体验不是特别好,但是这是我自己做出来的程序,自然是乐在其中。 链表问题有点迷惑,我还问了不少同学,也找了不少资料,稍微摸到了一些皮毛。运用的还不是很熟练。 那些题目真的需要好好思考,我好几次代码,写着写着,就忘记这里是干嘛的,还要返回去重新再过一遍,才知道自己写了个什么东西。 每天下午,走过那条太阳路,坐在机房的板凳上,掏出自己以后吃饭的家伙,开始一顿敲,挺考验意志的,我一道题磨了两天,还是写不下去,就去写下表面的题目,换换脑子,只要真心投入到敲代码的世界里去,时间就过的飞快,这都已经第六天了,好多小伙伴都完成了他们的任务,我也用过他们的小程序,有的很出色,有的觉得还不够人性化,我希望我上交的那份作业

集合框架系列 Map(十一):LinkeHashMap

a 夏天 提交于 2020-03-18 18:31:25
目录 1 概述 2 原理 3 源码分析  3.0 Entry 的继承体系  3.1 链表的建立过程  3.2 链表节点的删除过程  3.3 访问顺序的维护过程  3.4 基于 LinkedHashMap 实现缓存 4 总结 1. 概述 LinkedHashMap 继承自 HashMap,在 HashMap 基础上,通过维护一条双向链表,解决了 HashMap 不能随时保持遍历顺序和插入顺序一致的问题。除此之外,LinkedHashMap 对访问顺序也提供了相关支持。在一些场景下,该特性很有用,比如缓存。在实现上,LinkedHashMap 很多方法直接继承自 HashMap,仅为维护双向链表覆写了部分方法。所以,要看懂 LinkedHashMap 的源码,需要先看懂 HashMap 的源码。关于 HashMap 的源码分析,本文并不打算展开讲了。大家可以参考我之前的一篇文章“ HashMap 源码详细分析(JDK1.8) ”。在那篇文章中,我配了十多张图帮助大家学习 HashMap 源码。 本篇文章的结构与我之前两篇关于 Java 集合类( 集合框架 )的源码分析文章不同,本文将不再分析集合类的基本操作(查找、遍历、插入、删除),而是把重点放在双向链表的维护上。包括链表的建立过程,删除节点的过程,以及访问顺序维护的过程等。好了,接下里开始分析吧。 2. 原理 上一章说了