CS 61B笔记 2. Lists

1. 前情提要

在2.1中,我们创建了IntList类,作为一种列表数据结构。尽管它能完成所要求的全部事情,但是结构不够好,还可以改进。尤其是IntList用的Naked recursive,使代码很难理解。在2.2中我们将再写一个SLList类来改进IntList的不足之处。

2. 改进过程

1. 改名

把名字全改了,看起来更加专业。

public class IntList {
    public int first;
    public IntList rest;

    public IntList(int f, IntList r) {
        first = f;
        rest = r;
    }
...

改成:

public class IntNode {
    public int item;
    public IntNode next;

    public IntNode(int i, IntNode n) {
        item = i;
        next = n;
    }
}

2. 操作性

1. SLList隐藏了NULL:隐含的好处,以后会说。

2. addFirst and getFirst

public void addFirst(int x){

        first = new IntNode(x, first);

    }

    public int getFirst(){

        return first.item;

    }

由此产生的SLList类更易于使用。对比:

SLList版本:

SLList L = new SLList(15);
L.addFirst(10);
L.addFirst(5);
int x = L.getFirst();

IntList版本:

IntList L = new IntList(15, null);
L = new IntList(10, L);
L = new IntList(5, L);
int x = L.first;

可见在写列表的时候SLList版本可以更无脑,而IntList版本需要一定程度思考。

本质上,SLList 类充当了列表用户和裸递归数据结构之间的中间人。如上文 IntList 版本所述,IntList 用户有可能不希望变量指向 IntList 的中间部分。正如奥维德所说凡人不能直视神明而不死,所以最好还是让 SLList 来充当我们的中间人。
 

对比这两个图解可以看出SLList和IntList区别

IntList_vs_SLList.png

3. Public vs. Private

Private变量和方法只能在同一个.java文件中被调用,其他文件不能调用它,增加了安全性。

4. 嵌套类(Nested Classes)

在java中可以很自然的将一个类放在另一个类里,即嵌套在另一个类中。如果一个类只有一个功能或者只被一个其他类调用过,那就没有必要把它拿出来单独做成一个类。

5. 缓存法

关注size方法,如果列表大小为1000,size耗时2秒,但如果列表大小1,000,000,size耗时会达到2,000秒,为了节约时间,我们可以在SLList类中添加一个size变量来实时跟踪当前的大小,就能节省时间。这种在过程中保存重要数据以加快检索速度的方法称为缓存法

6. 空列表

2.3 DLList

双向链表,没什么好说的了。

2.4 Arrays

本节讨论java里的数组。

1. 数组的声明:

x = new int [3];
y = new int []{1,2,3,4,5}
int [] z = {6,7,8,9,0}

2. 数组和类的区别

  • 数组内元素使用[ ]访问,而类中的元素采用点符号 . 来访问。
  • 数组必须是同一类型,类中的元素可以有不同的类型。

这些差异带来的一个特别显著的影响是,[ ] 符号允许我们在运行时指定所需的索引,如int[] x={5,6,7,8}; int k = x[2]; 如此指定列表中某一个元素。链表指定不了。

相比之下,在类中指定字段不是我们在运行时要做的事情。例如,请看下面的代码:

String fieldOfInterest = "mass";
Planet p = new Planet(6e24, "earth");
double mass = p[fieldOfInterest];

2.5 The AList

在本节中,我们将创建一个名为 AList 的新类,它可以用来存储任意长的数据列表,类似于我们的 DLList。与 DLList 不同的是,AList 将使用数组而不是链表来存储数据。

链表走长列表很慢。

Resizing Arrays

java中的数组都是定长度的,定义以后长度不能改变。但是可以用System.

arraycopy来定义一个更长的数组,再把数据复制进去。

但是这种resize相当慢,耗时间耗内存。

Improved Resizing Arrays

拓展数组长度时,用加法拓展size是非常慢的,如果使用乘法或其他几何方法就可以非常快。

Generic ALists

Generic Array泛型的数组在java中不允许。

所以必须改成一个很麻烦的形式

items = (Glorp []) new Object[8];

创建对Glorps的引用数组时:

  • (Glorp [ ]) new Object[cap];

这样会导致一个编译器警告,但只需要忽略它即可。

  • 为什么不能用new Glorp[cap]:

这样会导致一个"generic array creation"error。

Nulling Out Deleted Items

只有对对象的最后一个引用消失时,java的Garbage Collector才会工作。所以不用的东西及时设置成null。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值