題目描述
給定帶頭結點的單鏈表,將其逆序
分析
由於單鏈表與數組的不同,單鏈表的每個結點的地址都儲存在其前驅結點的指針域中,對單鏈表中任一結點的訪問只能從頭結點開始遍歷。在對鏈表操作的時候應該注意在修改指針域的時候保存其后繼結點的地址,以免丟失后繼結點
方法一、就地逆序
方法介紹
在遍歷鏈表的時候,修改當前節點指針域的指向,使其指向他的前驅節點,這就需要三個指針變量保存結點指針域:當前結點、前驅結點和后繼結點
源代碼
class Node(object):
"""結點"""
def __init__(self,data=None):
self.data = data
self.next = None
def reverse(head):
"""鏈表逆序"""
if head == None or head.next == None:
return
cur = head.next #當前節點
next = cur.next #后繼節點
#將原來的頭結點變為為節點
pre = cur #前驅節點
cur.next = None
cur = next
while cur.next != None:
next = cur.next
cur.next = pre
pre = cur
cur = next
#最后一個進不了循環,在外面整
cur.next = pre
head.next = cur
def main():
#創建單鏈表
print("逆序前的鏈表為:", end=" ")
head = Node()
for i in range(10):
"""創建單鏈表"""
node = Node(i)
cur = head
if head.next == None or head == None:
head.next = node
else:
while cur.next != None:
cur = cur.next
cur.next = node
cur = head
while cur.next != None:
cur = cur.next
print(cur.data, end=" ")
print("\n逆序后的鏈表為:", end=" ")
reverse(head)
cur = head
while cur.next != None:
cur = cur.next
print(cur.data, end=" ")
if __name__ == '__main__':
main()
算法性能分析
以上方法只需要對鏈表進行一次遍歷,因此時間復雜度為O(N),N為鏈表的長度。此種方法需要兩個額外的變量儲存前驅結點和后繼結點,所以它的空間復雜度為O(1)。
方法二、插入法逆序
方法介紹
從鏈表的第二個結點開始,把遍歷到的結點插入到頭結點的后面,直到遍歷結束。
源代碼
class Node(object):
"""結點"""
def __init__(self,data=None):
self.data = data
self.next = None
def reverse(head):
"""鏈表逆序"""
if head == None or head.next == None:
return
cur = head.next.next
head.next.next = None
while cur != None:
next = cur.next
cur.next = head.next
head.next = cur
cur = next
def main():
#創建單鏈表
print("逆序前的鏈表為:", end=" ")
head = Node()
for i in range(10):
"""創建單鏈表"""
node = Node(i)
cur = head
if head.next == None or head == None:
head.next = node
else:
while cur.next != None:
cur = cur.next
cur.next = node
cur = head
while cur.next != None:
cur = cur.next
print(cur.data, end=" ")
print("\n逆序后的鏈表為:", end=" ")
reverse(head)
cur = head
while cur.next != None:
cur = cur.next
print(cur.data, end=" ")
if __name__ == '__main__':
main()
算法性能分析
這種方法也只需要對鏈表進行一次遍歷,時間復雜度同樣為O(n),與方法一相比,這種方法不需要額外變量保存前驅結點地址,因此空間復雜度更低