封装
我们创立了一些函数作为"中间人",正常情况下访问数据结构应该通过中间人进行,这样我们可以保证使用他们的人不做一些我们不想做的事情,我们可以使用private去控制相应的权限(但是只是向其他程序员发的信号)
嵌套类
在嵌套类里面使用static的关键字,相当于说它"永远不会向外看"
SLList和IntNode
SLList是 IntNode 的一个封装,只包括了头节点和所要用到的方法
对SLList写求它的大小的递归写法不是很显然,需要在IntNode里写一个方法求它的大小(原因是SLList并不是一个递归的数据结构,但是IntNode是)
public class SLList {
private IntNode first;
private static class IntNode {
public int item;
public IntNode rest;
public IntNode(int f,IntNode r)
{
item = f;
rest =r;
}
}
public SLList(int x)
{
first = new IntNode(x,null);
}
public void addFirst(int x)
{
first = new IntNode(x,first);
}
public int getFirst()
{
return first.item;
}
public void addLast(int x)
{
IntNode p = first;
while (p.rest != null)
{
p=p.rest;
}
p.rest = new IntNode(x,null);
}
public int size()
{
int count = 0;
IntNode p= first;
while (p != null)
{
p = p.rest;
count++;
}
return count;
}
优化
每次调用size和addLast都要从头遍历,有点慢,可以动态维护size和尾指针
添加新功能
我们添加一个创建空链表的构造函数
public SLList()
{
first = null;
size = 0;
}
看起来一切正常,但是如果我们调用了addLast,会出现bug
我们可以进行特判,但是特判会让代码比较臃肿
sentinel
在链表的最开始建立一个哨兵节点,这样我们可以永远知道前面有一个哨兵节点,这样就创建了一个永远保证为真的不变量
这样我们就得到了一个带哨兵的链表,这可以让我们在很多时候不用特判链表为空的情况