其实C语言真是好东西,它具有的指针能力,使得它可以非常容易地操作内存中的地址和数据,这比其他高级语言更加灵活方便。
    后来的面向对象语言,如Java、C#等,虽不使用指针,但因为启用了对象引用机制,从某种角度也间接实现了指针的某些作用。
    但对于一些语言,如Basic、Fortran等早期的编程高级语言,由于没有指针,链表结构按照前面我们的讲法,它就没法实现了。怎么办呢?

    有人就想出来用数组来代替指针,来描述单链表。真是不得不佩服他们的智慧,我们来看看他是怎么做到的。
    首先我们让数组的元素都是由两个数据域组成,data和cur。也就是说,数组的每个下标都对应一个data和一个cur。数据域data,用来存放数据元素,也就是通常我们要处理的数据;而cur相当于单链表中的next指针,存放该元素的后继在数组中的下标,我们把cur叫做游标。
    我们把这种用数组描述的链表叫做静态链表,这种描述方法还有起名叫做游标实现法。
    为了我们方便插入数据,我们通常会把数组建立得大一些,以便有一些空闲空间可以便于插入时不至于溢出。

    1. /* 线性表的静态链表存储结构 */
    2. /* 假设链表的最大长度是1000 */
    3. #define MAXSIZE 1000
    4. typedef struct
    5. {
    6. ElemType data;
    7. /* 游标(Cursor),为0时表示无指向 */
    8. int cur;
    9. } Component,
    10. /* 对于不提供结构struct的程序设计语言,
    11. 可以使用一对并行数组data和cur来处理。 */
    12. StaticLinkList[MAXSIZE];

    另外我们对数组第一个和最后一个元素作为特殊元素处理,不存数据。
    我们通常把未被使用的数组元素称为备用链表。

    • 而数组第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;
    • 而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于单链表中的头结点作用,当整个链表为空时,则为0。

    如图3-12-1所示。
    image.png
    图3-12-1
    此时的图示相当于初始化的数组状态,见下面代码:

    1. /* 将一维数组space中各分量链成一备用链表, */
    2. /* space[0].cur为头指针,"0"表示空指针 */
    3. Status InitList(StaticLinkList space)
    4. {
    5. int i;
    6. for (i = 0; i < MAXSIZE - 1; i++)
    7. space[i].cur = i + 1;
    8. /* 目前静态链表为空,最后一个元素的cur为0 */
    9. space[MAXSIZE - 1].cur = 0;
    10. return OK;
    11. }