題目
單鏈表中的節點應該具有兩個屬性:val 和 next。val 是當前節點的值,next 是指向下一個節點的指針或引用。
請設計一個單鏈表,並在鏈表類中實現下列操作:
- get(index):獲取鏈表中索引 index 節點的值。如果索引無效,則返回-1。
- add_at_head(val):在鏈表的第一個節點之前添加一個值爲 val 的節點。插入後,新節點將成爲鏈表的第一個節點。
- add_at_tail(val):將值爲 val 的節點追加到鏈表的最後一個節點。
- add_at_index(index,val):在鏈表中的索引 index 節點之前添加值爲 val 的節點。如果 index 等於鏈表的長度,則該節點將追加到鏈表的末尾;如果 index 大於鏈表長度,則不會插入節點;如果 index 小於0,則在頭部插入節點。
- delete_at_index(index):如果索引 index 有效,則刪除鏈表中的索引 index 的節點。
說明:鏈表節點的索引 index 是從 0 開始計算,比如鏈表中索引 1 下的節點,指的是鏈表中的第二個節點。
代碼實現
class ListNode: # 定義單鏈表
def __init__(self, val=0, next=None):
self.val = val # 鏈表節點上存儲的元素
self.next = next # 指向下一個鏈表節點
class MyLinkedList:
def __init__(self):
self.dummy_head = ListNode(0) # 定義虛擬頭節點
self.length = 0 # 定義鏈表的長度
def get(self, index: int) -> int:
if 0 <= index < self.length:
cur = self.dummy_head
cur = cur.next # 因爲多了一個虛擬頭節點,所以需提前移動1位
while index: # 循環操作,讓 cur 移動 index 位
cur = cur.next
index -= 1
return cur.val
else: # 鏈表節點不存在,直接返回-1
return -1
def add_at_head(self, val: int) -> None:
cur = self.dummy_head
old_head = cur.next # 臨時保存原鏈表的頭節點
cur.next = ListNode(val=val, next=old_head) # 改變節點指向,讓虛擬頭節點通過 next 指向新加的節點,新節點則通過 next 指向原鏈表的頭節點
self.length += 1 # 鏈表長度+1
def add_at_tail(self, val: int) -> None:
cur = self.dummy_head
while cur.next is not None: # cur 不是鏈表最後一個節點
cur = cur.next
cur.next = ListNode(val=val, next=None) # 鏈表最後一個節點通過 next 指向新加的節點,新節點則通過 next 指向None
self.length += 1 # 鏈表長度+1
def add_at_index(self, index: int, val: int) -> None:
if 0 <= index <= self.length:
cur = self.dummy_head
while index: # 循環操作,讓 cur 移動 index 位
cur = cur.next
index -= 1
if index != self.length: # 如果 index 不等於鏈表長度, 那麼讓cur通過 next 指向新加的節點,新節點則通過 next 指向cur的下個節點
post_head = cur.next
cur.next = ListNode(val=val, next=post_head)
else: # 如果 index 恰好等於鏈表長度,那麼在鏈表末尾添加節點
cur.next = ListNode(val=val, next=None)
self.length += 1 # 鏈表長度+1
elif index < 0:
self.add_at_head(val)
def delete_at_index(self, index: int) -> None:
if 0 <= index < self.length:
cur = self.dummy_head
while index: # 循環操作,讓 cur 移動 index 位
cur = cur.next
index -= 1
cur.next = cur.next.next # 刪除節點
self.length -= 1 # 鏈表長度-1
def list_node_to_list(node): # 將單向鏈表轉換爲列表
result = []
while node:
result.append(node.val)
node = node.next
return result
測試過程
if __name__ == '__main__':
obj = MyLinkedList()
obj.add_at_head(10) # 在鏈表開頭加新節點
obj.add_at_tail(3) # 在鏈表末尾加新節點
print(list_node_to_list(obj.dummy_head.next))
obj.add_at_index(1, 2) # 在鏈表索引1位置加新節點
print(list_node_to_list(obj.dummy_head.next))
print(obj.get(1))
obj.delete_at_index(1) # 刪除鏈表索引1位置的節點
print(obj.get(1))
print(list_node_to_list(obj.dummy_head.next))
執行代碼後,得到如下結果:
[10, 3]
[10, 2, 3]
2
3
[10, 3]
更多Python編程題,等你來挑戰:Python編程題彙總(持續更新中……)