卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34553本站已运行393

一行内反向链表

一行内反向链表

php小编鱼仔为您介绍一种常见的数据结构算法——“一行内反向链表”。在这个算法中,我们需要将一个链表中的节点顺序进行反转。通过简洁而高效的代码实现,我们可以在一行内完成这个操作,使得链表的顺序完全颠倒过来。这个算法在实际编程中非常有用,无论是在数据处理还是算法设计中,都能发挥重要作用。让我们一起来了解一下这个精彩的算法吧!

问题内容

我刚刚在 leetcode 上使用 go 中的一行找到了反向链表的解决方案。它确实有效,但我不明白如何实现。

就是这样:

func reverselist(head *listnode) (prev *listnode) {
    for head != nil {
        prev, head, head.next = head, head.next, prev 
    }
    
    return
}

例如,让列表为 [1->2->3->4->5->nil]

我知道它的工作原理如下:

  1. 首先去执行 head.next = prev (head.next = nil, 所以现在 head = [1->nil])

  2. 然后, prev = head (在这一步 prev = [1->nil] 就像上一步中的 head 一样)

  3. head = head.next 这就是魔法。对于第二步go中的prev,使用head = [1->nil],但是在这一步之后head = [2->3->4->5->nil]

因此,当 head != nil 时,它会进行迭代,并在第二步 prev = [2->1->nil]head = [3->4->5->nil] 等等。

这条线可以表示为:

for head != nil {
        a := *head
        prev, a.Next = &a, prev
        head = head.Next
    }

我说得对吗?为什么会这样?

解决方法

表达式左侧的变量将被分配给当时表达式右侧的值。这是语言的巧妙运用。

为了更容易理解,我们来看一个例子。

设置

这是我们的链接列表: 1 -> 2 -> 3 -> 4 -> 无

在函数执行之前,

  • 头是*节点 1
  • prev 为零(未初始化)
  • head.next 是*节点 2

一步一步

prev, head, head.next = head, head.next, prev

让我们分解一下,

  • prev (nil) = head (*节点 1)
  • head (*节点 1) = head.next (*节点 2)
  • head.next (*节点 2) = prev (nil)

下一次迭代,

  • prev (*节点 1) = head (*节点 2)
  • head (*节点 2) = head.next (*节点 3)
  • head.next (*节点 3) = prev (*节点 1)

摘要

基本上,它将 head.next 反转到前一个节点,并将 prev 和 head 移动到下一个节点。

将其与 go 中的教科书算法进行比较以明确:

func reverseList(head *ListNode) *ListNode {
    var prev *ListNode

    for head != nil {
        nextTemp := head.Next
        head.Next = prev
        prev = head
        head = nextTemp
    }

    return prev
}
卓越飞翔博客
上一篇: 如何以不变性公开切片成员?
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏