Skip to content

概念卡片:线性表与哈希表

一句话机制:栈 LIFO、队列 FIFO、链表插入删除快、哈希表 O(1) 查找。哈希表通过散列函数 h(key) 把关键字直接映射到存储位置,省去比较;冲突靠开放定址法拉链法解决。

栈 vs 队列

栈 Stack队列 Queue
规则LIFO(后进先出)FIFO(先进先出)
操作端只在一端(栈顶)插入/删除前端删、后端插
基本操作push/pop/peekoffer/poll/peek

链表

  • 与数组同级的数据结构,循环遍历效率不高,但插入删除优势明显(不需移动元素)。
  • Java 里 ArrayList 是数组实现(非链表),LinkedList 才是链表。

哈希表(散列表)

  • 定义:根据关键码值直接访问,存储位置 = h(key),一次存取完成查找。
  • 优点:查找/插入/删除接近 O(1),比树快。
  • 缺点:基于数组,难扩建,装满后性能骤降。

哈希函数构造方法

方法公式/思路
直接定址法H(key)=keya*key+b
除余法h(key)=key MOD p(p≤m)
基数转换法关键字按某进制转换
平方取中法关键字平方后取中间几位(分布均匀)
折叠法分割成几部分叠加(移位叠加/间界叠加)

哈希冲突及处理

冲突 = 不同关键字算出相同哈希地址。两种处理:

方法思路特点
开放定址法冲突时按探查序列找下一个空位(线性/二次/双散列)平均查找长度更长
拉链法同义词放在同一单链表(指针数组存头指针)多占指针空间,但比较只发生在同义词间,查找更短
  • 线性探查:x+1, x+2, x+3…;二次探查:x+1², x+2², x+3²…(防聚集)。
  • 双散列函数法:冲突后探查间隔由第二个哈希函数决定。

关键代码示例(哈希应用场景)

Java 的 HashSet 用 HashMap 的 key 存储元素,靠 hashCode 定位;判断重复调 hashCode + equals。

不变量(必须成立的约束)

  • 栈/队列都是操作受限的线性表。
  • 哈希表 O(1) 是平均复杂度,冲突严重会退化。
  • 拉链法平均查找长度低于开放定址法(只与同义词比较)。

常见误解

  • 以为「ArrayList 是链表」→ 是数组(动态数组)。
  • 以为「哈希无需比较」→ 冲突发生时仍需在探查序列/链表里比较。
  • 以为「开放定址法和拉链法等价」→ 开放定址省空间但查找长,拉链省比较但占指针空间。

关联

最近更新