动态

详情 返回 返回

反轉鏈表的兩種解法 - 动态 详情

反轉鏈表可以用兩種方法來實現,一種是常見的迭代法,還有一種方法就是遞歸,下面來分析一下具體是怎麼實現的。

迭代法

思路:

初始化一個變量來存儲前驅節點pre,從頭節點開始遍歷鏈表,每遍歷一個節點,就將該節點的後驅節點指向pre,完成了反轉,然後更新pre的值為當前節點以便下一個節點的使用,遍歷完以後以前的尾節點就是新的頭節點。

func (head *Node) reverse() *Node {
    if head == nil {
        return nil
    }
    var reverseHead *Node // 反轉後單鏈表的頭結點
    var preNode *Node
    curNode := head
    for curNode != nil {
        nextNode := curNode.next
        if nextNode == nil {
            reverseHead = curNode // 尾結點轉換為頭結點
        }
        // 反轉實現,當前結點的前驅結點變成後驅結點
        curNode.next = preNode
        // 設置下一個結點的前驅結點
        preNode = curNode
        curNode = nextNode
    }
    return reverseHead
}

遞歸法

思路

image.png
遞歸的方法會不斷壓棧,反轉(head.Next)的前提是反轉(head.Next.Next),一直到終止條件head.Next == nil時拿到尾節點的值才真正開始處理,last節點的變化如下:
6
6->5
6->5->4
6->5->4->3
6->5->4->3->2
6->5->4->3->2->1

假設reverse(head.Next)返回的已經是反轉後的節點last,現在還需要做的就是將2號節點的後驅節點指向head,以及原head節點的後驅節點指向nil,一個節點的case想明白了,其他的其實就是一樣的過程了。

func reverse(head *Node) *Node {
    if head == nil || head.Next == nil {
        return head
    }
    last := reverse(head.Next)
    head.Next.Next = head
    head.Next = nil
    return last
}
參考資料:https://labuladong.github.io/...

Add a new 评论

Some HTML is okay.