通過自己實現連結串列的增刪改查瞭解連結串列這些方法的實現原理
連結串列:
連結串列和陣列都是線性表:
陣列:將元素順序地存放在一塊連續的儲存區內,元素間的順序關係由它們的儲存順序自然表示。
連結串列:將元素存放在通過連結構造起來的一系列儲存塊中。
特點:不用連續儲存,不需要知道儲存的數量,分散儲存。
尋找元素的方式:比如有個list li = [200,400,600]
200這個元素儲存著400的記憶體地址,400儲存著600的記憶體地址,
既一個連結串列元素儲存著兩個東西:1、資料區2、連結區
單向連結串列:
前一個節點指向下一個節點,單向的。尾節點的連結區指向為空。
通過類實現以下功能
單鏈表的操作
- is_empty() 連結串列是否為空
- length() 連結串列長度
- travel() 遍歷整個連結串列
- add(item) 連結串列頭部新增元素
- append(item) 連結串列尾部新增元素
- insert(pos, item) 指定位置新增元素
- remove(item) 刪除節點
- search(item) 查詢節點是否存在
在例如c語言中,申明一個變數需要規定好這個變數的型別,例如:int a = 10,這是因為c在申明變數後,會在記憶體中
劃出一個空間存放10,這個空間的別名為a,a就算改變也只能是int型別,而在python中 a = 10的意思是a
代表著記憶體,存放著數字10的記憶體地址,既指標概念,換成其他型別也不影響(例如浮點,函式等)。
一個元素有兩個屬性:
1、elem 為此元素的值
2、next為指向下一個元素位置的記憶體地址
class Node:#元素 def __init__(self,elem): self.elem = elem#此節點的數值 self.next = None#下一個節點的記憶體地址 class SingleLinkList:#單向連結串列 def __init__(self): self._head = None def is_empty(self):#連結串列是否為空 pass def length(self):#連結串列長度 pass def travel(self):# 遍歷整個連結串列 pass def add(self,item):#連結串列頭部新增元素 pass def append(self,item):#連結串列尾部新增元素 pass def insert(self,pos, item):#指定位置新增元素 pass def remove(self,item):#刪除節點 pass def search(self,item):#查詢節點是否存在 pass
先定義兩個類,節點和單向連結串列。
初始化連結串列,連結串列的頭元素(_head=None)為None空,要想向連結串列新增一個節點,則必須先例項化一個Node物件。
sll = SingleLinkList()
node = Node(100)
向sll連結串列新增一個節點100,則sll._head 指向100。
is_empty
現在可以寫出is_empty的方法,當_head == None則表示連結串列為空。
def is_empty(self): # 連結串列是否為空
return self._head == None
length
要想實現知道連結串列裡元素的個數,則需要一個指標或者遊標來計數。
計數初始,遊標在_head處,然後通過_head指向的頭節點找到第一個節點,然後再從第一個節點的連結self.next找到下一個節點。
判斷是否是最後一個節點的標誌是此時節點的next屬性是否為None,如果為None則是最後一個節點。
def length(self): # 連結串列長度
#要考慮到連結串列為空的情況
count = 0
cur = self._head#遊標
while cur != None:
count += 1
cur = cur.next
return count
同理,遍歷也可以寫出來
travel
def travel(self): # 遍歷整個連結串列
cur = self._head#遊標
while cur != None:
print(cur.elem)
cur = cur.next
append
def append(self, item): # 連結串列尾部新增元素 item為資料,不是節點,讓使用者使用起來方便,只要使用者輸入數字
node = Node(item)
if self.is_empty():
self._head = node
else:
cur = self._head
while cur.next != None:
cur = cur.next
cur.next = node
insert
def insert(self, pos, item): # 指定位置新增元素
count = 0
cur = self.__head
if pos <= 0:
self.add(item)
elif pos > self.length() - 1:
self.append(item)
else:
while count < pos - 1:#在指定位置的前一個節點,插入新的節點,
cur = cur.next#遊標指向下一個
count += 1
node = Node(item)
node.next = cur.next#新的節點的下一個節點指向原來位置為pos的節點
cur.next = node#然後在把遊標的下一個節點指向要插入的節點,要注意先後順序
remove
def remove(self, item): # 刪除節點
cur = self.__head#遊標在第一個節點
prev = None#此時遊標的上一個位置為None
while cur != None:#當遊標部位不為空時
if cur.elem == item:#找到要刪除逇數字
if cur == self.__head:#如果要刪除的節點為第一個節點
self.__head == cur.next#把首節點指向第二個節點
else:
prev.next = cur.next#其餘情況下則把要刪除節點的上一個節點指向下一個節點
break
else:
prev = cur
cur = cur.next
search
def search(self, item): # 查詢節點是否存在
cur = self.__head#遊標
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
完整版:
class Node: # 元素
def __init__(self, elem):
self.elem = elem # 此節點的數值
self.next = None # 下一個節點的記憶體地址
class SingleLinkList: # 單向連結串列
def __init__(self):
self.__head = None
def is_empty(self): # 連結串列是否為空
return self.__head == None
def length(self): # 連結串列長度
#要考慮到連結串列為空的情況
count = 0
cur = self.__head#遊標
while cur != None:
count += 1
cur = cur.next
return count
def travel(self): # 遍歷整個連結串列
cur = self.__head#遊標
while cur != None:
print(cur.elem, end=" ")
cur = cur.next
def add(self, item): # 連結串列頭部新增元素
node = Node(item)
node.next = self.__head
self.__head = node
def append(self, item): # 連結串列尾部新增元素 item為資料,不是節點,讓使用者使用起來方便,只要使用者輸入數字
node = Node(item)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
def insert(self, pos, item): # 指定位置新增元素
count = 0
cur = self.__head
if pos <= 0:
self.add(item)
elif pos > self.length() - 1:
self.append(item)
else:
while count < pos - 1:#在指定位置的前一個節點,插入新的節點,
cur = cur.next#遊標指向下一個
count += 1
node = Node(item)
node.next = cur.next#新的節點的下一個節點指向原來位置為pos的節點
cur.next = node#然後在把遊標的下一個節點指向要插入的節點,要注意先後順序
def remove(self, item): # 刪除節點
cur = self.__head#遊標在第一個節點
prev = None#此時遊標的上一個位置為None
while cur != None:#當遊標部位不為空時
if cur.elem == item:#找到要刪除逇數字
if cur == self.__head:#如果要刪除的節點為第一個節點
self.__head == cur.next#把首節點指向第二個節點
else:
prev.next = cur.next#其餘情況下則把要刪除節點的上一個節點指向下一個節點
break
else:
prev = cur
cur = cur.next
def search(self, item): # 查詢節點是否存在
cur = self.__head#遊標
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
sll = SingleLinkList()
print("是否為空",sll.is_empty())
print("連結串列長度",sll.length())
sll.append(1)
sll.append(2)
sll.append(3)
sll.append(4)
sll.travel()
sll.remove(4)
sll.travel()
sll.remove(3)
sll.travel()