-
對象引用機制,從某種角度也間接實現了指針的某些作用。
-
用數組來代替指針,來描述單鏈表
-
首先我們讓數組的元素都是由兩個數據域組成,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靜態鏈表的優缺點
- 優點:
- 在插入和刪除操作時,只需修改遊標,不需要移動元素,從而改進了在順序存儲結構中的插入和刪除操作需要移動大量元素的缺點
- 缺點:
- 沒有解決連續存儲分配帶來的表長難以確定的問題
- 失去了順序存儲結構隨機存取的特性
靜態鏈表其實是爲了給沒有指針的高級語言設計的一種實現單鏈表能力的方法。