1 單鏈表
單鏈表由兩部分組成:元素域與鏈接域。 元素域保存作爲表元素的數據項,鏈接域保存同一個表裏的下一個結點的標識。
單鏈表有以下特點:
- 一個單鏈表由一些具體的表結點組成;
- 每個結點是一個對象,由自己的標識,也稱爲該結點的鏈接;
- 結點之間通過結點鏈接建立起單向的順序鏈接;
- 在python中,通常用None值作爲單鏈表中最後一個結點的鏈接域。
爲方便討論,現在定義一個簡單的表結點類:
class LNode:
def __init__(self,elem,next_=None):
self.elem=elem
self.next=next_
1.1 基本鏈表操作
1.1.1 創建空鏈表:只需要把表頭變量設置成空鏈接,在python語言中設置成爲None。
1.1.2 刪除鏈表:應丟棄這個鏈表裏的所有結點。在python語言中,只需要將表指針賦值爲None,就拋棄了鏈表中的所有結點。python解釋器的存儲管理系統會自動回收不用的存儲。
1.1.3 判斷表是否爲空:將表頭變量的值與空鏈接比較,在python語言中,就是檢查相應的變量是否爲None。
1.1.4 判斷表是否會滿:一般而言鏈表不會滿。
1.2 加入元素
1.2.1 表首端插入: 三步即可完成:
- 創建一個新節點並存入數據;
- 把原鏈表首節點的鏈接域存入新結點的鏈接域next。
- 修改表頭變量,使之指向新節點。
示例代碼段:
q=LNode(13)
q.next=head.next
head=q
1.2.2 表中間元素的插入(包括鏈表末尾插入): 設變量pre已指向要插入元素位置的歉前一結點,操作也分爲三步:
- 創建一個新節點並存入數據;
- 把pre所指結點的next域的值存入新節點的鏈接域next;
- 修改pre的next域,使之指向新結點;
示例代碼段
q=LNode(12)
q.next=pre.next
pre.next=q
1.3 刪除元素
1.3.1 刪除表首元素:刪除表中第一個元素對應於刪除表的第一個結點,爲此只需要修改表頭指針,令其指向表中的第二個結點。
示例代碼段
head=head.next
1.3.2 一般元素的情況刪除:一般情況刪除須先找到刪除元素所在結點的前一結點,設用變量pre指向,然後修改pre的next域,使之指向被刪除域的下一結點。
示例代碼段
pre.next=pre.next.next
1.4 掃描、定位和遍歷
1.4.1 掃描:由於單鏈表只有一個方向的鏈接,開始情況下只有表頭變量在掌握中,所以對錶的內容的檢查只能從表頭變量開始,沿着表中鏈接逐步進行。這種行爲稱之爲鏈表的掃描。
- 按下標定位:按Python慣例,鏈表首結點的元素應看做下標爲0,其他元素依次排列,確定第i個元素所在結點的操作稱爲按下標定位。代碼示例段如下:
p=head
while p is not None and i > 0:
i-=1
p=p.next
- 按元素定位:假設在鏈表中需要找到滿足謂詞pred的元素,示例代碼段如下:
p=head
while p is not None and not pred(p.elem):
p=p.next
- 完整的遍歷
p=head
while p is not None:
print p.elem
p=p.next
1.5 鏈表操作的時間複雜度
- 創建空表:O(1)
- 刪除表:O(1)
- 判斷空表:O(1)
- 加入元素(都需要加一個T()分配時間):
- 首端加入元素,O(1)
- 尾端加入元素,O(n)
- 定位加入元素,O(n),平均情況和最壞情況
- 刪除元素:
- 首端刪除元素:O(1)
- 尾端刪除元素:O(n)
- 定位刪除元素:O(n),平均情況和最壞情況
- 其他刪除:通常需要掃描整個表或其一部分
1.6 LList類的定義,初始化函數和簡單操作
現在基於結點類LNode定義一個單鏈表類,只有一個引用鏈接結點的_head域,初始化爲None表示建立的是一個空表。
class LList:
def __init__(self):
self._head=None
def is_empty(self):
return self._head is None
#insert element on the beginning of the list
def prepend(self):
self._head=LNode(elem,self._head)
def pop(self):
if self._head is None: #if list is none, raise exception
raise Error
e=self._head.elem
self._head=self._head.next
return e
# insert element on the end of the List
def append(self,elem):
if self._head is None:
self._head=LNode(elem)
return
p=self._head
while p is not None:
p=p.next
p.next=LNode(elem)
# delete the last node and return it's value
def pop_last(self):
if self._head is None:
raise ExceptionError
p=self._head
if p.next is None:
e=p.elem
self._head=None
return e
while p.next.next is not None:
p=p.next
e=p.next.elem
p.next=None
return e
#basic scan element in the List
def find(self,pred):
p=self._head
while p is not None:
if pred(p.elem):
return p.elem
p=p.next
# print all elem in the list
def printall(self):
p=self._head
while p is not None:
print p.elem
if p.next is not None:
print ','
p=p.next
print ''
參考文獻
裘宗燕 . 數據結構與算法:Python語言描述[M]. 北京:機械工業出版社,2016:80-88.