class Node(object):
def __init__(self, item):
self.item = item
self.next = None
def __str__(self):
return str(self.item)
# 單向鏈表
class LinkedList(object):
def __init__(self):
self.head: Node = None
def is_empty(self):
return self.head is None
def length(self):
"""
O(n) 此處可以存儲爲一個長度變量
:return:
"""
length = 0
cur = self.head
while cur is not None:
cur = cur.next
length += 1
return length
def append(self, value: object):
"""
O(n) 將元素添加到最後 如果這裏是雙端鏈表,那麼會有tail指向最後一個,能夠提高到O(1)
:param value:
:return:
"""
node = Node(value)
cur = self.head
if cur is None:
self.head = node
else:
while cur.next is not None: # 只有當前節點有下一個節點, 才進行賦值
cur = cur.next
cur.next = node
def add(self, value: object):
"""
O(1) 將元素添加到頭部
:param value:
:return:
"""
node = Node(value)
node.next = self.head # 將新節點的下一節點指向當前鏈表頭部第一個節點
self.head = node # 更新當前鏈表的節點
def insert(self, index, value):
"""
O(1) or O(n)
:param index:
:param value:
:return:
"""
# index = index - 1
if index <= 0 or self.is_empty():
self.add(value) # 在頭部插入
elif index >= self.length():
self.append(value) # 在尾部插入
else:
node = Node(value)
count = 0
cur = self.head
while cur is not None:
if index - 1 == count: # 判斷是否是需要插入的位置
node.next = cur.next # 將新節點的下一節點指向當前節點(當前cur節點)的下一節點
cur.next = node # 將當前遍歷節點的下一節點指向新節點
break
cur = cur.next
count += 1
def insert2(self, index, value):
"""
O(1) or O(n)
:param index:
:param value:
:return:
"""
if index <= 0 or self.is_empty():
self.add(value) # 在頭部插入
elif index >= self.length():
self.append(value) # 在尾部插入
else:
node = Node(value)
count = 0
cur = self.head
while count < (index - 1):
cur = cur.next
count += 1
node.next = cur.next
cur.next = node
def reverse(self):
"""
反轉鏈表: 順序遍歷每個節點, 將每個節點的next指針指向上一個節點
"""
cur = self.head # 當前節點指向頭部
prev_node = None # 上一個節點
while cur is not None:
next_node = cur.next # 當前節點的下一個節點 必須第一步
cur.next = prev_node # 設置當前節點的下一個節點爲上一節點(反轉指向)
prev_node = cur # 更新變量 設置上一個節點爲當前節點(下一次循環使用)
cur = next_node # 更新變量 設置當前節點爲下一節點(下一次循環使用)
if cur is not None: # 最後一個節點的next必定爲None, 所以這裏要判斷 設置head指針指向最後一個節點
self.head = cur
def remove(self, item):
cur = self.head # 雙指針-當前
prev_node: Node = None # 上一個
while cur is not None:
if cur.item == item:
if prev_node is None: # 上一個節點
self.head = cur.next
else:
prev_node.next = cur.next # 刪除中間元素
return True
else:
prev_node = cur
cur = cur.next
return False
def get(self, index):
cur = self.head
count = 0
while cur is not None: # 遍歷節點
if count == index: # 如果次數一樣
return cur.item # 返回元素
cur = cur.next
count += 1
return None
def find(self, item):
cur = self.head
count = 0
while cur is not None:
if cur.item == item:
return count
cur = cur.next
count += 1
return -1
def __iter__(self):
"""遍歷"""
cur = self.head
while cur is not None:
yield cur.item
cur = cur.next
if __name__ == '__main__':
linked = LinkedList()
assert linked.is_empty() is True
linked.append(1)
linked.append(2)
linked.append(3)
linked.add(99)
# 鏈表長度
li = [i for i in linked]
assert li == [99, 1, 2, 3]
assert linked.length() == len(li)
# 鏈表反轉
linked.reverse()
li = [i for i in linked]
assert li == [3, 2, 1, 99]
assert linked.length() == len(li)
# 鏈表插入
linked.insert(1, 100)
li = [i for i in linked]
assert li[1] == 100
# 鏈表刪除
linked.remove(100)
li = [x for x in linked]
assert li == [3, 2, 1, 99]
# 獲取元素
assert linked.get(3) == 99
assert linked.get(4) is None
# 查找位置
assert linked.find(99) == 3
assert linked.find(3) == 0
print(li)
Python單向單端鏈表
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.