python單鏈表
單鏈表的定義
連結串列是線性表的一種,線性錶鏈式儲存結構的特點是:用一組任意的儲存單元儲存線性表的資料元素(這組儲存的單元可以是連續的,也可以是不連續的)。
為了清楚地表示單鏈表,我們還要引入節點的概念
節點的定義
為了表示連結串列中每一個數據元素a(i)與其直接後繼資料元素a(i+1)之間的邏輯關係,對於資料a(i)來說,除了儲存其本身的資訊之外還需要儲存一個指向其直接後繼的資訊。這兩部分組成資料元素a(i)的儲存映像,稱為節點。節點有兩個域,一個是儲存資訊的資料域,一個是儲存下一個節點位置的指標域。指標域中儲存的資訊稱作指標或鏈。
有了節點這個概念,我們就可以用python中的類來實現,節點的兩個域我們可以實列的屬性表示,通過例項化這個類就可以生成節點。
節點的實現:
class Node():
def __init__(self, dataval=None):
self.dataval = dataval # 資料域,生成節點需要具體內容
self.nextval = None # 指標域
n個節點鏈結成一個連結串列。如果每個節點只包含一個指標域,那麼這個連結串列就是線性連結串列又稱單鏈表
我們一般將連結串列畫成用箭頭相連結的節點序列
為了處理方便,我們一般在單鏈表的第一個節點(首元節點)之前再加一個節點,稱為頭節點,頭節點的資料域一般不儲存內容,或者存與整個連結串列相關的資訊,比如連結串列的長度之類的,頭節點的指標域指向首元節點。
同時還要引入一個概念:頭指標,頭指標指向列表開始的位置,如果有頭節點就指向頭節點,如果沒有頭節點就指向首元節點。
再加一個頭節點是為了連結串列處理起來更加方便,這樣就不必對元首節點做特俗處理,而且即便連結串列為空,頭指標的指向也不為空。
### 程式碼實現
在python中我們一般用類和例項來實現連結串列,下面是python程式碼:
# 節點 class Node(): def __init__(self, dataval=None): self.dataval = dataval # 資料域 self.nextval = None # 指標域 # 連結串列 class Slinkedlist(): def __init__(self): self.headval = None # 初始化頭指標 list1 = Slinkedlist() # 生成連結串列 list1.headval = Node() # 設定一個頭節點,頭指標指向頭節點 e1 = Node("Mon") #生成節點 e2 = Node("Tus") e3 = Node("Wed") # 再將各個節點連起來 list1.headval.nextval = e1 # 將頭節點的指標域指向首元節點 e1.nextval = e2 # 下面一次按順序連起來 e2.nextval = e3
實現了連結串列,接下來就是實現連結串列的方法和屬性
1.列印連結串列,思路就是從首節點開始,通過節點指標域不斷跳轉到下一個,直到節點域為空為止
class Slinkedlist():
def __init__(self):
self.headval = None # 初始化頭指標
def printlist(self): # 遍歷連結串列
printval = self.headval.nextval # 這裡是從元首節點開始
while printval:
print(printval.dataval) # 列印內容
printval = printval.nextval
2.求連結串列長度,思路差不多,加一個計數器就行了
class Slinkedlist():
def __init__(self):
self.headval = None # 初始化頭指標
def __len__(self): # 求連結串列的長度
lenval = self.headval.nextval
num = 0
while lenval:
num += 1
lenval = lenval.nextval
self.headval.dataval = num # 頭節點儲存連結串列的長度
return num
3.通過下標取值,這裡依賴前面的求長度的方法來判斷輸入下標的合法性
class Slinkedlist():
def __init__(self):
self.headval = None # 初始化頭指標
def get(self, index, k=0): # 取值操作
nm = -1 # 從-1開始表示從頭節點開始,但是一般來說輸入的下標是從0開始的
lenth = self.__len__() # 先求出長度判斷是否越界
if index > lenth - 1 or index < -1:
raise "連結串列下標越界"
node = self.headval # 定義第一個值,從頭節點開始找
while nm < index:
node = node.nextval
nm += 1
if k == 0:
return node.dataval
else:
return node
4.通過值求下標,我們規定,頭節點的下標為-1,首元節點的下標為0,後面依次遞增
class Slinkedlist():
def __init__(self):
self.headval = None # 初始化頭指標
def index(self, data): # 通過值拿到下標
nm = 0
node = self.headval.nextval
while node:
if node.dataval == data:
return nm
else:
nm += 1
node = node.nextval
else:
return None
5.插入操作,連結串列的插入操作和順序表不同,連結串列的插入不需要移位,只需要將要插入的位置的前一個節點的指標域改為指向新的節點,同時新加入的節點的指標域要指向後面的節點。因為有頭節點,所以我們不需要對首元節點特殊處理。
class Slinkedlist():
def __init__(self):
self.headval = None # 初始化頭指標
def insert(self, index, value): # 插值操作
newnode = value # 獲取新的節點
ahead = self.get(index - 1, k=1) # 獲取要插入位置前面的節點
newnode.nextval = ahead.nextval
ahead.nextval = newnode
6.刪除操作,同插入操作類似,這裡我們將通過下標刪除和通過值刪除合在一起
class Slinkedlist():
def __init__(self):
self.headval = None # 初始化頭指標
def remove(self, obj):
if type(obj) == int:
if obj < -1:
raise "輸入的值不合法"
data = self.get(obj,k=1)
ahead = self.get(obj - 1,k=1)
ahead.nextval = data.nextval
else:
index = self.index(obj)
data = self.get(index,k=1)
ahead = self.get(index -1,k=1)
ahead.nextval = data.nextval
好了,python單鏈表基本就這些了。