文章目錄
參考學習視頻
python03-04-01單向鏈表
一、單向鏈表介紹
鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,但是並不會按線性的順序存儲數據,而是在每一個節點裏存到下一個節點的指針(Pointer)。像鎖鏈一樣,由一節節節點連在一起,組成一條數據鏈。
1.1 鏈表節點結構:
1.2 單向鏈表的結構
1.3 單鏈表和單向循環鏈表
- 單鏈表:每個節點只有一個屬性.next,用於存放其後繼節點;尾節點的後繼爲None;若鏈表爲空,則頭節點.head爲None。
- 單向循環鏈表:每個節點只有一個屬性.next,用於存放其後繼節點;由於循環,故尾節點的後繼爲頭節點;若鏈表爲空,則頭節點.head爲None。
二、操作單鏈表
2.1 常用方法(自己定義的)
方法 | 作用 |
---|---|
is_empty() | 鏈表是否爲空 |
length() | 鏈表長度 |
travel() | 遍歷整個鏈表 |
add(item) | 鏈表頭部添加元素 |
append(item) | 鏈表尾部添加元素 |
insert(pos, item) | 指定位置添加元素 |
remove(item) | 刪除節點 |
search(item) | 查找節點是否存在 |
2.2 單向鏈表的實現
1、單節點類結構
class SingleNode(object):
"""單鏈表的結點"""
def __init__(self,item):
# item存放數據元素
self.item = item
# next是下一個節點的標識
self.next = None
2、單鏈表的增刪改查
# #
class Node():
"""表節點結構實現 私有屬性__next是指向下個節點的指針,__value爲此節點的值"""
def __init__(self, value=None, next=None, ):
self._value = value
self._next = next
# 將方法封裝
def getValue(self):
return self._value
def getNext(self):
return self._next
def setvalue(self, value):
self._value = value
def setNext(self, next):
self._next = next
class SingleLinkList(object):
"""操作單鏈表的方法"""
def __init__(self, Node=None):
"""設置一個頭節點"""
self.head = Node
def is_empty(self):
"""判斷鏈表是否爲空"""
return self.head is None
def add(self, node):
"""向鏈表頭添加輸入"""
# 將插入元素實例化
tmp = Node(node)
# 如果鏈表爲空,則讓頭指針指向實例化的節點
if self.is_empty():
self.head = tmp
else:
# 如果鏈表不爲空,則先將頭部節點指向的節點(內存地址),賦值給要插入節點的指針域
# 然後將頭部節點指針域指向要插入的節點
tmp.setNext(self.head)
self.head = tmp
def append(self, node):
"""向鏈表尾添加數據"""
end_Node = Node(node)
cursor = self.head
# 判斷列表是否爲空,如果爲空,則頭部插入
if self.is_empty():
self.add(end_Node)
else:
# 如果不爲空,
while cursor.getNext() is not None:
cursor = cursor.getNext()
cursor.setNext(end_Node)
def tarver(self):
"""遍歷整個鏈表"""
cur = self.head
while cur is not None:
print(cur.getValue(), end=" ")
cur = cur.getNext()
print() # 換行
def length(self):
"""鏈表長度"""
cur = self.head
count = 0
while cur is not None:
count += 1
cur = cur.getNext()
return count
def insert(self, index, node):
"""指定位置插入鏈表"""
tmp = Node(node)
if self.is_empty():
print("鏈表爲空")
return
elif index <= 0:
# 如果在頭部直接插入
self.add(node)
elif index > self.length():
# 如果大於鏈表長度,則在尾部插入
self.append(node)
else:
count = 0
cur = self.head
while count < (index - 1):
count += 1
cur = cur.getNext()
tmp.setNext(cur.getNext())
cur.setNext(tmp)
def remove(self, index):
"""通過索引 刪除節點"""
if self.is_empty():
print("鏈表爲空")
return
if index < 0 or index > self.length()-1:
print("索引範圍超出鏈表長度!")
return
# 刪除索引爲0的元素
elif index == 0:
self.head = self.head.getNext()
else:
cur = 0 # 索引
pre = self.head
while cur < index-1:
cur += 1
pre = pre.getNext()
pre.setNext(pre.getNext().getNext())
def search(self, value):
"""鏈表查找節點是否存在,並返回True或者False"""
cur = self.head
if self.is_empty():
print("鏈表爲空!")
return
while cur != None:
if cur.getValue() == value:
return True
cur = cur.getNext()
return False
def change(self, index, value):
"""鏈表內容替換"""
if self.is_empty():
print("鏈表爲空!")
return
if index < 0 or index > self.length()-1:
print("索引範圍超出鏈表長度!")
return
node = self.head
for i in range(self.length()):
if i == index:
node.setvalue(value)
return
node = node.getNext()
if __name__ == '__main__':
obj = SingleLinkList()
obj.add(1)
obj.tarver()
obj.append(2)
obj.append(4)
obj.add(7)
obj.tarver()
obj.insert(3, 5)
obj.tarver()
obj.remove(1)
obj.tarver()
print(obj.search(2))
obj.tarver()
obj.change(2, 55)
obj.tarver()
3、反轉單鏈表
"""
翻轉一條單鏈表
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
"""
class ListNode:
def __init__(self, x, Next=None):
self.val = x
self.next = Next
# 遍歷替換法
def ReverseList(head):
if head == None or head.next == None:
return head
last = None # 前置節點
while head:
tmp = head.next # 保存當前節點的下一個節點,不可缺,因爲後面更改了當前節點的next指向
head.next = last # 更改當前節點的next爲上一個節點
last = head # 將上一個節點移動到當前節點
head = tmp # 當前節點移動到下一個節點
# head.next, last, head = last, head, head.next 可以簡寫成
return last
if __name__ == '__main__':
# 創建一個1-5的鏈表
a = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5,)))))
Node = ReverseList(a)
while Node:
print(Node.val)
Node = Node.next
結果:
5
4
3
2
1