创建: 2017/12/26
【TODO】
S4, S5, S14来处理动态数组 CAF8A81B790F
|
链表的定义 |
| 定义 |
存储大量数据的数据结构 |
| 性质 |
● 相邻元素用指针连接
● 最后的要素指向NULL
● 程序运行时动态调整大小(size)
● (在计算机内存范围内)能获取需要的长度
● 不浪费内存空间(但是指针需要多余的内存) |
| |
|
| |
|
| |
|
|
链表ADT |
| 链表的主要运算 |
● 插入: 插入元素
● 删除: 删除指定位置的元素 |
| 链表的额外运算 |
● 链表删除: 删除链表的所有元素(删除链表)
● 计数: 获取链表内元素的个数
● 获取链表末尾第n个元素 |
| |
|
| |
|
| |
|
|
使用链表的理由 |
| 数组概览 |
| 定义 |
数组全体分配一个内存块
用index花费固定时间(O(1))来接入 |
获取元素花费一定时间
O(1) |
获取元素A[n]时,
n为元素到首元素的位差,
位差n*元素大小为首元素内存与目标元素的差
获取元素: 一次乘法和一次加法
O(1) |
| 优点 |
● 简单好用
● 获取元素高速 O(1) |
| 缺点 |
● 大小(size)固定: 不能动态指定
● 分配一个内存块: 定义时分配,太大悲剧
● 插入操作非常坑: 要把后面的一个一个移开 |
| 动态数组 |
● 满了长度x2
● 不到一半, 长度/2
CAF8A81B790F
【TODO】S4, S5,
S14来处理 |
|
| 链表的优劣 |
| 优点 |
● 增减元素只花费固定时间O(1) |
| 缺点 |
● 获取单个元素花费大量时间O(n)
● 多余的指针浪费内存空间 |
|
数组与链表的
时间复杂度比较 |
| |
链表 |
数组 |
动态数组 |
| 获取元素 |
O(n) |
O(1) |
O(1) |
| 插入/删除开头 |
O(1) |
- |
O(n) |
| 插入/删除结尾 |
O(n) |
- |
O(1), 数组没满的时候
O(n), 数组满了的时候 |
| 插入/删除中间 |
O(n) |
- |
O(n) |
| 内存的浪费 |
O(n) |
0 |
O(n) |
|
| |
|
|
单向链表 |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
双向链表 |
| 概要 |
| 优点 |
●可以双向移动,操作便利 |
| 缺点 |
●需要额外的指针,额外消耗内存
●插入/删除更花时间(因为指针操作更多) |
| |
|
| |
|
| |
|
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
循环链表 |
| |
用于轮询调度算法等 |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
内存高效率的双向链表 |
| |
|
| |
|
| |
|
| |
|
| |
|
|
链表的不足 |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|