單鏈表反轉的原理和python代碼實現


鏈表是一種基礎的數據結構,也是算法學習的重中之重。其中單鏈表反轉是一個經常會被考察到的知識點。

單鏈表反轉是將一個給定順序的單鏈表通過算法轉為逆序排列,盡管聽起來很簡單,但要通過算法實現也並不是非常容易。現在來給大家簡單介紹一下單鏈表反轉算法實現的基本原理和python代碼實現。

                                       算法基本原理及python代碼
1、方法一:三個指針遍歷反轉
算法思想:使用3個指針遍歷單鏈表,逐個鏈接點進行反轉。

 

(1)分別用p,q兩個指針指定前后兩個節點。其中p.next = q

 

(2)將p指針指向反方向。

 

(3)將q指針指向p。q.next = p,同時用r代表剩余未反轉節點。

 

(4)將p,q指針同時后移一位,回到步驟(2)的狀態。

 

(5)r指針指向剩余未反轉節點。循環執行(3)之后的操作。

# 詳細版
def reverse01(head):
if head == None:
return None
# 分別用p,q兩個指針指定先后兩個節點
p = head
q = head.next

# 將p節點反轉,head節點只能指向None
p.next = None

# 當存在多個后續節點時,循環執行
while q:
r = q.next # 用r表示后面未反轉節點
q.next = p # q節點反轉指向p
p = q
q = r # p,q節點后移一位,循環執行后面的操作

return p

# 精簡版
def reverse01(head):
if not head:
return None
p,q,p.next = head,head.next,None
while q:
q.next,p,q = p,q,q.next
return p
2、方法二:尾插法反轉
算法思想:固定頭節點,然后將后面的節點從前到后依此插入到次節點的位置,最后再將頭節點移動到尾部。

 

# 詳細版
def reverse02(head):
# 判斷鏈表的節點個數
if head == None or head.next == None:
return head

p = head.next
# 循環反轉
while p.next:
q = p.next
p.next = q.next
q.next = head.next
head.next = q

# 將頭節點移動到尾部
p.next = head
head = head.next
p.next.next = None

return head

# 精簡版
def reverse02(head):
if not head or not head.next:
return head
p = head.next
while p.next:
q = p.next
p.next,q.next,head.next = q.next,head.next,q
p.next,head,p.next.next = head,head.next,None
return head
3、方法三:遞歸方式反轉
算法思想:把單鏈表的反轉看作頭節點head和后續節點head.next之間的反轉,循環遞歸。

 

 

 

 

def reverse03(head):
if head.next == None:
return head

new_head = reverse03(head.next)
head.next.next = head
head.next = None

return new_head
                                                      leetcode精簡代碼示例
 單鏈表的反轉邏輯思路比較清晰,因此關於單鏈表反轉重在考查代碼的經精簡度,而Python可以實現代碼的極度簡化,如下:

def reverse04(head):
curr,pre = head,None
while curr:
curr.next,pre,curr = pre,curr,curr.next
return pre
                                    leetcode相關算法習題(92.反轉鏈表II)
利用以上算法思想完成leetcode習題:92.反轉鏈表II

習題描述:

反轉從位置 m 到 n 的鏈表。請使用一趟掃描完成反轉。

說明:
1 ≤ m ≤ n ≤ 鏈表長度。

# 算法思想:采用尾插法反轉思想(方法二)

# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution(object):
def reverseBetween(self, head, m, n):
"""
:type head: ListNode
:type m: int
:type n: int
:rtype: ListNode
"""
root = ListNode(0)
root.next = head
Head = root # 指定一個頭部變量(方法二中固定的head)

for i in range(m-1):
Head = Head.next

if Head.next == None:
return head

pre = Head.next
while pre.next and m < n:
curr = pre.next
pre.next = curr.next
curr.next = Head.next
Head.next = curr
m += 1

# 由於m之前的元素不需要反轉,因此用root.next代替方法二中的head
return root.next

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM