链表

第一次理解通用链表

穿精又带淫゛_ 提交于 2020-03-13 11:06:08
1 #ifndef _LIST_H 2 #define _LIST_H 3 #include"stdio.h" 4 #define _INLINE_ static inline 5 6 struct list_head { 7 struct list_head *next, *prev; 8 }; 9 10 #define LIST_HEAD_INIT(name) {&(name), &(name)} 11 12 #define LIST_HEAD(name) \ 13 struct list_head name = LIST_HEAD_INIT(name) 14 15 #define INIT_LIST_HEAD(ptr) do {\ 16 (ptr)->next = (ptr); (ptr)->prev = (ptr); \ 17 } while (0) 18 19 _INLINE_ void __list_add(struct list_head *add, 20 struct list_head *prev, 21 struct list_head *next) 22 { 23 next->prev = add; 24 add->next = next; 25 add->prev = prev; 26 prev->next = add; 27 } 28 29 _INLINE

Redis——订阅

﹥>﹥吖頭↗ 提交于 2020-03-13 10:05:49
总结: 服务器状态在pubsub_channels字典保存了所有频道的订阅关系:SUBSCRIBE命令负责将客户端和被订阅的频道关联到这个字典里面,则UNSUBSCRIBE命令则负责解除客户端和退订频道之间 的关联。 服务器状态在pubsub_patterns链表保存了所有模式的订阅关系:PSUBSCRIBE命令负责将客户端 和被订阅的模式记录到这个链表中,而PUNSUBSCRIBE命令则负责移除客户端和被退订模式在链表中的记录。 PUBLISH 命令通过访问pubsub_channels字典来向频道的所有订阅者发送消息,通过访问 pubsub_patterns链表来向所有匹配频道的模式的订阅者发送消息。 PUBSUB命令的三个子命令都是通过读取pubsub_channels字典和pubsub_patterns链表中的信息来实现的。 订阅使用的场景是什么????? 补充: 消息系统该Push/Pull模式分析: http://blog.csdn.net/pi9nc/article/details/27714745 来源: oschina 链接: https://my.oschina.net/u/1475335/blog/682933

图解单链表反转

拜拜、爱过 提交于 2020-03-13 09:37:08
图解单链表反转 前言 反转链表是程序员必备的基本素养,经常在面试、笔试的过程中出现。一直觉得反转链表实现代码不是很好理解,决定搬leetcode那道经典反转链表题出来,用十多张图去解析它,希望加深大家对链表反转的理解,谢谢阅读。 leetcode的反转链表原题&答案 题目描述: 反转一个单链表。 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 分析: 假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3。 在遍历列表时,将当前节点的 next 指针改为指向前一个元素。由于节点没有引用其上一个节点,因此必须事先存储其前一个元素。在更改引用之前,还需要另一个指针来存储下一个节点。不要忘记在最后返回新的头引用! 代码实现: public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp; } return prev; } 图解链表反转代码的实现 接下来,我们图解以上代码实现

HashMap的实现原理

蓝咒 提交于 2020-03-13 09:24:54
一,前言 1.1,概述 ​ 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射(K-V)。Java提供了专门的集合类用来存放这种对象关系的对象,即 java.util.Map 接口。 Collection 中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。 Map 中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键(K)可以找对所对应的值(V)。 Collection 中的集合称为单列集合, Map 中的集合称为双列集合。 需要注意的是, Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。 ​ 通过查看Map接口描述,看到Map有多个子类,这里我们主要讲解常用的HashMap集合、LinkedHashMap集合。 HashMap<K,V> :存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。 LinkedHashMap<K,V> :HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法

HashMap的存储结构及原理

本小妞迷上赌 提交于 2020-03-13 09:22:55
1、HashMap的数据结构(HashMap通过hashcode对其内容进行高速查找,是无序的) 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。 数组 :数组的存储区是连续的,占用内存严重,故空间复杂度非常大。但数组的二分查找时间度小;数组的特点:寻址easy,插入和 删除困难。 链表 :链表的储存区离散。占用内存比較宽松。故空间复杂度非常小,但时间复杂度大;链表的特点:寻址困难,插入和删除easy。 哈希表 HashMap 是由数组+链表组成。寻址easy,插入和删除easy。( 存储单元数组Entry[],数组里面包括链表 ) HashMap 事实上也是由一个线性的数组实现的。 所以能够理解为其存储数据的容器就是一个线性容器; HashMap 里面有一个内部静态类Entry,其重要的属性有key,value,next,从属性key,value 就能够非常明显的看出来 Entry就是 HashMap键值对实现的一个基础bean;也就是说HashMap的基础就是一个线性数组,这个数组就是Entry[]。Map里面的内容都保存 在Entry[]中; /** * The table, resized as necessary. Length MUST Always be a power of two. */ transient Entry[] table; 2

Java HashMap实现原理分析

末鹿安然 提交于 2020-03-13 09:20:18
参考链接:https://www.cnblogs.com/xiarongjin/p/8310011.html 1. HashMap的数据结构 数据结构 中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难; 链表 链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。 链表 的特点是:寻址困难,插入和删除容易。 哈希表 那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表。哈希表((Hash table)既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。   哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法—— 拉链法,我们可以理解为“ 链表的数组 ” ,如图:   从上图我们可以发现哈希表是由 数组+链表 组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。那么这些元素是按照什么样的规则存储到数组中呢。一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28

hashmap实现原理

早过忘川 提交于 2020-03-13 08:54:20
hashmap就是一个链表散列,上边是table 下边是链表,可以理解为数组链表 键值对都可以为null 默认的hashmap大小为16,实际可以存储的只有16*0.72个, 一旦超过这个值就会进行hashmap扩容,扩容的方式是size*2,即按照2次方进行自动扩容,扩容时会进行resize,重新进行放置 高并发时不支持,会造成死循环,建议使用currenthashmap 来源: https://www.cnblogs.com/xww115/p/11158545.html

数据结构之常见的数据结构

爷,独闯天下 提交于 2020-03-13 07:23:01
最近做题,老是遇到一些概念性的问题(详见:牛客) 逐步总结在此博客: 1、 常用数据结构 · 数组(静态数组、动态数组)、线性表、链表( 单向链表 、双向链表、循环链表)、队列、栈、树(二叉树、查找树、平衡树、线索树、线索树、堆)、图等的定义、存储和操作 · Hash(存储地址计算,冲突处理) 2、数据存储类型就是数据的类型,如整形,字符型等,所以数组和链表是相同的,数据访问效率不同,数组可以随机访问,而链表不可以,插入删除效率也不相同. 来源: https://www.cnblogs.com/neversayno/p/5129216.html

复制带随机指针的链表

筅森魡賤 提交于 2020-03-13 01:56:04
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的 深拷贝 。 我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示: val :一个表示 Node.val 的整数。 random_index :随机指针指向的节点索引(范围从 0 到 n-1 );如果不指向任何节点,则为 null 。 /* // Definition for a Node. class Node { public: int val; Node* next; Node* random; Node(int _val) { val = _val; next = NULL; random = NULL; } }; */ class Solution { public: Node* copyRandomList(Node* head) { if(head == NULL){ return head; } Node *p = head; Node *q = NULL; while(p != NULL){ q = new Node(p->val); q->random = p->random; q->next = p->next; p->next = q; p = q->next; } Node

线性数据结构之链表

泄露秘密 提交于 2020-03-13 00:42:17
什么是链表? 链表是一种线性数据结构,由不定数量的节点链接在一起,存储在不连续的内存空间中。按照节点的内部组成以及节点之后的链接形式可以分为 单向链表 、 双向链表 以及 循环链表 。 单链表 由各个节点通过一个Next引用链接在一起组成,每一个节点都存在后继节点(链尾除外),内存结构由数据域和Next 引用组成。 双向链表 由各个节点通过Next引用和 Prev引用链接在一起组成,每一个内存结构都存在前驱节点和后继节点(链头没有前驱,链尾没有后继),节点由数据域、Prev引用和 Next引用组成。 单向循环链表 由各个节点通过一个 Next引用 链接在一起组成,每一个节点都存在后继节点,节点由数据域和 Next 引用组成。 双向循环链表 由各个节点通过Next引用 和Prev引用 链接在一起组成,每一个内存结构都存在前驱节点和后继节点,节点由数据域、Prev引用和Next引用组成。 链表VS数组 底层存储结构上 数组需要一组连续的内存空间存储数据,而链表恰恰相反它并不需要连续的内存空间。 性能上 数组和链表是两种截然不同的内存组织方式。正是因为内存存储的区别,它们插入、删除、随机访问操作的时间复杂度正好相反 实现单链表 /** * 单向链表 */ public class SingleDirectLinkedList<E> { //链表大小 private int size; /