列表
详细介绍见 Josh Hug 为 Berkeley CS61B 编写的教材
基础实现
我们可以创建最基础的链表如下:
public class IntList {
public int first;
public IntList rest;
public IntList(int f, IntList r) {
first = f;
rest = r;
}
/** Return the size of the list using... recursion! */
public int size() {
if (rest == null) {
return 1;
}
return 1 + this.rest.size();
}
/** Return the size of the list using no recursion! */
public int iterativeSize() {
IntList p = this;
int totalSize = 0;
while (p != null) {
totalSize += 1;
p = p.rest;
}
return totalSize;
}
}如果我们想加入数字 5、10、15,可以采取以下方式:
或者:
直观的显示为:

SLList
首先创建列表的单个元素:
再创建一个类用于与用户交互,简化用户的操作:
这样处理后的类更易于使用:
直观的表示为:

进一步,我们可以采用嵌套类整合代码。如果嵌套类不需要使用外层类的任何实例方法和变量,可以将其声明为 static,这意味着静态类中的方法不能访问封闭类的任何成员,在下面代码即表现为 IntNode 中的任何方法都无法访问 first、addFirst 或者 getFirst,这样设置关键词可以节省少量内存。
另一个改进是跟踪当前表的 size,这种保存重要数据以加快检索速度的方法有时称为缓存。
考虑创建或插入空链表时可能导致的特殊情况(使用 sentinel node)。
DLList
DLList 将是基于 SLList 的改进。改进方向:
双向链表,可以降低 addLast 运行耗时,同时解决哨兵节点在链表为空时出现的问题。
使用泛型,可以储存任何类型的数据结构
AList
AList 也是一个可以存储任意长数据的列表,与前面不同的是,它使用数组而非链表,其优势主要在于 get(int i) 即获取特定索引的值的函数的响应时间。
该方法的主要难点在于数组的大小调整,做法是创建一个新的数组并复制原数组的内容,但需要考虑到程序用时与内存占用。
具体操作是:
RFACTOR 为拓展因子,在需要对数组进行拓展时使用乘法拓展;
THRESHOLD 为触发数组缩小的使用率阈值,即数组中非空部分占比小于此值,对数组进行缩小以减少空间占用;
Last updated