繁体   English   中英

理解单向链表的头部和指针

[英]understand head and pointers for a singly-linked list

也许这是一个相当基本的问题,但我在 leetcode 上似乎有很多这样的问题。

例如,一个人为我提供了一个单向链表的头,而不是我定义一个指针变量说:

curr = head 

在我恢复头部之后:

def revert(head):     
    prev, curr = None, head 

    while curr: 
        nxt = curr.next 

        curr.next = prev 
        prev = curr 

        curr = nxt 

    return prev

现在我将获得一个单链表,在这种情况下,顺序是相反的,prev 是它的头部。

当循环完成时,当然 curr 指针指向None ,我想知道为什么 head 被修改为只包含最后一个元素。

一个更普遍的问题是,一旦指针改变,头部怎么会自动更新? 这是由 leetcode 后端实现的还是从数据结构的角度来看的。

一旦指针改变,头部怎么会自动更新?

简短的回答是它不会自动更新。

在您的示例中,变量head指向一个可变的 object,这意味着即使从 function scope 完成修改也会就地发生。

常规的 python list也是可变的,为了演示让我们采用常规的 python 列表并对内容进行一些修改。

def change_last_index(example):
    lst = example  # lst and example both point to the same mutable object
    lst[-1] = 153

example = [1, 2, 3]
change_last_index(example)

print(example) # [1, 2, 153]

这与链表的链接/节点是相同的概念。


让我们创建一个与您的 function 一起使用的示例Node类/数据结构。

class Node:
    def __init__(self, val):
        self.val = val
        self.next = None
    def __repr__(self): 
        return f"{self.val} -> {self.next}"

为了证明它的可变性,我们可以创建一个 function 来创建一个新节点并将其分配给它的下一个属性。

def set_next_node(node, value):
    node1 = node  #  node1, node, and head all point to same object
    node1.next = Node(value)  # create new node and assign to head.next
    
head = Node(0)
print(head)               # output:  0 -> None

set_next_node(head, 1)
# the function will create a new node with value of 1 set it to `head.next`

print(head)               # output:  0 -> 1 -> None

在第一行的revert function 中......

prev, curr = None, head 

... curr变量现在指向head指向的同一个 object。 因此,在while循环的第一次迭代中,当执行curr.next = prevhead.next会更改为None

然后在第二次迭代中,同一行将head分配给不同节点的next属性,因为当执行prev = curr行时, prev被重新分配给head object。

这是一个示例,您可以使用上面的revert function 和示例Node class 运行。 我建议在 IDE/调试器中运行它和上面的所有代码,这样你就可以一步一步地跟踪变化,并运行你自己的实验,比如延长链表或将节点值更改为字符串。

head = Node(0)
head.next = Node(1)
head.next.next = Node(2)

print(head)  # 0 -> 1 -> 2 -> None

def revert(head):
    prev, curr = None, head
    while curr:
        nxt = curr.next
        curr.next = prev
        prev = curr
        curr = nxt
    return prev

result = revert(head)

print(head) # 0 -> None
print(result) # 2 -> 1 -> 0 -> None

希望您能看到没有任何事情是自动发生的。 head和链表的所有其他元素的所有修改都是在您的 function 中执行的步骤的直接结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM