常用数据结构:散列表等

539 阅读2分钟

在数组和链表之上,还可以构建更复杂的数据结构,比如散列表、队列和栈。

定义

散列表是 数组散列函数 结合而成的一种数据结构(其实也包括 链表 )。数组和链表都直接映射到内存,但散列表更复杂,使用散列函数来确定元素的储存位置。 散列表也被成为字典、散列映射、映射和关联数组。python中的dict()

应用

  • 模拟映射关系,快速查找
  • 防止重复
  • 缓存

散列表的内部原理简介

  • 散列表的基本思想是:
  1. 先分配一个大的数组空间,数组每个元素是一个链表的头
  2. 添加时,我们可以根据散列函数计算出一个key(可以是哈希值),这个key就是数组的位置,所以我们可以快速定位到元素的位置和链表,添加这个数据到链表。
  3. 查找时,同理,我们根据散列函数计算出key,快速找到数组和链表中的位置。
  • 散列函数(也叫哈希算法): 简单说,就是把任意长度的输入,通过散列函数,压缩为某一固定长度的输出。Hash算法没有一个固定的公式,只要符合散列思想的算法都可以被称为是Hash算法。散列函数有这几个特点:
  1. 总是将相同的输入映射到相同的索引。
  2. 倾向于将不同的输入映射到不同的索引。(但无法绝对保证)
  3. 散列函数知道数组有多大,因此只返回有效索引
  • 冲突(collision): 就是散列函数把不同的输入,计算成了同样的值。哈希冲突无法避免,所以有了需要链表的使用。但是,多个数据放入链表会导致效率太低。所以要尽量找一个更均匀分配的散列函数,减少冲突,提升效率。

  • 散列函数的选择: 考虑两个因素:

    1. 填装因子 填装因子 = 已包含的元素数 / 散列表总位置。填装因子增大,意味着冲突的可能性升高,当填装因子>1时,一定发生冲突。所以一旦填装因子增大,就需要再散列表中添加位置,这叫做 resizing(调整长度)。一般以0.7位resizing的阈值。
    2. 良好的散列函数 良好的散列函数让数组中的值均匀分布

常用hash算法:取余, SHA, MD5, bcrypt

其他数据结构(待总结)

  • 栈: 先进后出 函数递归 深度优先搜索
  • 队列 广度优先搜索 消息队列
  • 图的模型 二叉树,多叉树,有向图,无向图