-
对象引用机制,从某种角度也间接实现了指针的某些作用。
-
用数组来代替指针,来描述单链表
-
首先我们让数组的元素都是由两个数据域组成,data和cur。也就是说,数组的每个下标都对应一个data和一个cur。
-
数据域data,用来存放数据元素。
-
cur相当于单链表中的next指针,存放该元素的后继在数组中的下标,将cur叫做游标。
-
用数组描述的链表叫做静态链表,这种描述方法叫做游标实现法。
-
对数组的第一个和最后一个元素作为特殊元素处理,不存数据。
最后一个有值元素,它的cur设置为0
# space[0].cur为头指针,0表示空指针
InitList(space):
i = 0
while i<MAXSIZE-1:
space[i].cur = i+1
i++
space[MAXSIZE-1].cur = 0 # 目前静态链表为空,最后一个元素的cur为0
return OK
3.4.1静态链表的插入操作
静态链表要解决的问题:
如何用静态模拟动态链表结构的存储空间的分配,需要时申请,无用时释放。
为了辨明数组中哪些分量未被使用,解决的方法是将所有未被使用过的及已被删除的分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上取得第一个结点作为待插入的新结点。
# 若备用空间链表非空,则返回分配的结点下标,否则返回0
Malloc(space):
i = space[0].cur # 当前数组第一个元素的cur存的值,就是要返回的第一个备用空间的下标
if space[0].cur:
space[0].cur = space[i].cur # 由于要拿出一个分量来使用了,所以我们就得把它的下一个分量用来备用
return i
ListInsert(L,i,e):
k = MAX_SIZE - 1 # 注意k首先是最后一个元素的下标
if i<1 or i>(ListLength(L)+1):
return ERROR
j = Malloc(L) # 获得空闲分量的下标
if j:
L[j].data = e # 将数据赋值给此分量的data
l = 1
while l <= (i-1): # 找到第i个元素之前的位置
k = L[k].cur
l++
L[j].cur = L[k].cur # 把第i个元素之前的cur赋值给新元素的cur
L[k].cur = j # 把新元素的下标赋值给第i个元素之前元素的cur
return OK
return ERROR
3.4.2 静态链表的删除操作
# 将下标为k的空间结点回收到备用链表
Free(space,k):
space[k].cur = space[0].cur # 把第一个元素cur值赋给要删除的分量cur
space[0].cur = k # 把要删除的分量下标赋值给第一个元素的cur
# 删除在L中第i个数据元素e
ListDelete(L,i):
if i<1 or i>ListLength(L):
return ERROR
k = MAX_SIZE -1
j = 1
while j<=(i-1):
j++
k = L[k].cur
j = L[k].cur
L[k].cur = L[j].cur
Free(L,j)
return OK
ListLength(L):
j = 0
i = L[MAX_SIZE-1].cur # 获得存放第一个元素的下标
while i:
i = L[i].cur
j++
return j
3.4.3静态链表的优缺点
- 优点:
- 在插入和删除操作时,只需修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点
- 缺点:
- 没有解决连续存储分配带来的表长难以确定的问题
- 失去了顺序存储结构随机存取的特性
静态链表其实是为了给没有指针的高级语言设计的一种实现单链表能力的方法。