数组 链表 hash

数组在内存空间是连续的.

链表(linked List)的储存空间可以是不连续的,每个数据之间是通过指针来联系起来的,

链表分为单链表,双链表,循环链表(单向循环,双向循环)

链表核心操作 插入,删除,遍历

单链表中的内存结构是通过next指针链接在一起组成,next指针指向下一个数据域,(节点)内存结构由数据data和next指针两部分区块组成.链尾的next指针设为null[指向空],遍历方向单一从头到尾

双向链表由next指针和prew指针和数据三个区块组成,next指针指向下一个数据域,指向的内存结构叫做后继,链尾next指针设为null[指为空], prew指针指向上个数据域,指向的内存结构叫做前驱,连头prew指针设为null[指为空],一般情况下next方向是头到尾,这篇说的都是在next方向是头到尾的情况下.

循环链表单向循环 链尾next指针指向链头,形成闭环,其实没有链头和链尾

双向循环链表链尾next指针指向链头,链头prew指针指向链尾,形成闭环,其实没有链头和链尾

指针其实是下一个数据域的地址

红黑树(平衡二叉树的一种变体,不是严格意义上的平衡二叉树,左右子树高差可能大于1 )

一种特殊的二叉树,通过左右子树节点左移右移来维持平衡.

hashmap 中当链表元素个数大于8时(当整个散列桶(数组)的大小已经超过64),转成红黑树,低于6时转回链表,为了解决hash冲突和map元素过多

散列类型(hash类型)(redis中hash ,这与Java中的hashmap本质相同)

散列是<k,v>对的集合,不过KV都只能是字符串类型的,不能嵌套

不区分插入和更新,当设置一个field的时候如果不存在的话就是新增返回1,存在的话就视为更新,会覆盖原始数据返回0

<使用hmset可以一次付多个值

使用hsetnx只有当指定的field不存在时才赋值,为了比年覆盖已有的值

hget单个取值 hmget取多个值

hgetall取出全部的field和value

hkeys....获取hash表中的field集合

hvals.....获取value表中的value集合

hash冲突简单的说就是通过hash函数计算时,不同的key值,有相同的value>

以上中的field字段值就是指KV中 的k,key指的是表名

每个hash表名存储的最大是2的32次方减一的键值对

散列桶(分离链表法)

哈希桶就是为了解决哈希冲突

哈希桶算法其实就是链地址解决冲突的方法

哈希桶的每个桶由一个链表来存储数据

每个桶储存的是此格里链表的一个数据的key(地址值)

hashmap的几种方法

hash表的底层结构是一个数组,数组长度即哈希表的长度,数组中方的每个空间(桶)存放一个链表,链表每个节点存放元素

hash查找 是通过一种hash函数(如 value=key % 3)进行计算方便查找的方法

直接定址法 除留取余法 平均取余法 平均取中法 折叠法 随机数法 数据分析法    分离链接法和开放定址法  其中最后两个解决哈希冲突

一致性哈希(哈希圆环(虚拟圆环)0-2^32)(优点是即使缓存服务器的数量发生改变,部分的服务器还是可以能正常使用)(一致性哈希使用的32个bits,4个bytes,肯定也会有哈希碰撞的问题存在)解决分布式缓存问题

key或节点数值,ip ---hash()---->值----取余---->余数_

hash(节点(服务器或服务)特有数据或者ip)%机器数=余数,余数对应哈希环上的对数值的点,分布在圆环上,其为节点.

hash(处理的数据的值(key))%机器数=余数,余数对应哈希环上的对应数值的点,分布在圆环上,顺时针差找第一个节点,为该数据的存储节点.

哈希倾斜,是因为节点因为计算可能会分布不均,导致各个节点的存储数据不均匀

虚拟节点有效的缓解可以说解决哈希倾斜,通过服务器的物理真实节点,映射出多个虚拟节点,将这些虚拟节点映射到哈希环上,增加均匀缓存的概率,通过上面的顺时针查找,,找到第一个虚拟节点,通过这个虚拟节点映射对应的真实的节点,之后进行存储或读取.

虚拟节点机制,一般不会把真实节点放在哈希环上,只放虚拟节点

一致性哈希可能会因为一个节点的缺失,导致下一个节点需要缓存的数据激增,可能导致这个节点也崩溃,这样会造成连锁反应,这就是哈希雪崩.(虚拟节点机制也可以缓解哈希雪崩)

哈希槽

声明:使用这些类是使用者的自愿行为,作者对源代码的质量不提供任何形式的担保,如果使用者因使用这些类而造成的任何损失都与作者无关,作者不承担任何责任。<br><br>/*************** 这些头文件不必包含 ***************/<br>node.h: 普通链表结点<br>dnode.h: 双向循环链表结点<br>treenode.h: 二叉树结点<br>avltreenode.h: AVL 树结点<br>/**************************************************/<br><br>array.h: 安全数组,可自动增长大小(随机访问,但扩充时效率低)<br>linkedlist.h: 普通链表(可随机访问,但访问效率低)<br>dclinkedlist: 双向循环链表(不可随机访问,但插入、遍历的效率都比普通链表高)<br>hashtable.h: 哈希表(使用键值标识元素,键值一样的元素即认为相等,需重载 == 运算符并由用户定义哈希函数)<br>binstree.h: 二叉搜索树(需重载 == < 运算符)<br>avltree.h: AVL 树(需重载 == < 运算符)<br><br>如果要存储集合(元素不可重复)并快速查找,最佳的是 binstree.h(二叉搜索树)。<br>如果要存储二维或更高维的表格,最佳的是 hashtable.h(哈系表)。<br><br>AVL 树的插入成本非常高(删除函数也没有实现),但 AVL 的搜索效率极高,所以适用于在程序开始前初始化程序中经常要用到的集合,一般应用二叉搜索树已经足够了。<br><br>以上代码都是作者照书上改写的,并未经过严格测试,如果使用过程中发现任何问题、源代码错误或可改进的地方,非常欢迎来信与我讨论。电子邮件地址:pro_zw@lol35.com<br><br>作者会根据各位所发现的问题不断改进各类并增加新的数据结构,使其更加完善。<br><br>参考书目:<br>《数据结构-C++ 语言描述》 William Ford William Topp 著 清华大学出版社<br>《计算机程序设计艺术》 DONALD E.KNUTH 著 清华大学出版社<br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值