Python链表赋值疑问:修改引用变量为何会改变原链表?
链表指针修改原链表的疑问解答
先看修正后的完整代码:
class Node: def __init__(self, val): self.val = val self.next = None def addNode(self, val): root = self while root.next is not None: root = root.next root.next = Node(val) def iterateLL(self): root = self while root is not None: print(str(root.val) + " ", end="") root = root.next print() if __name__ =="__main__": L = Node(1) L.addNode(2) L.addNode(3) L.addNode(4) # 遍历链表并打印 L.iterateLL() # 修改指针的指向不会影响原链表L P = L P = P.next L.iterateLL() # L没有变化 # 修改指针指向节点的next属性会影响原链表L P = L P.next = P.next.next L.iterateLL() # 现在跳过了节点2 # 修改指针指向节点的val属性会影响原链表L P = L P.val = 10 L.iterateLL()
核心逻辑:Python变量是对象引用
当执行P = L时,不是把L的内容复制给P,而是让P和L指向内存中同一个Node对象。这就像两个人拿着同一扇门的钥匙,谁都能打开门修改里面的东西,不存在单向只读的关系。
分情况解释代码里的现象
情况1:
P = P.next不影响L
这一步只是把P的“钥匙”换成了下一个节点的钥匙,P现在指向第二个节点,但L手里的钥匙还是第一个节点的。原链表的节点本身没被修改,所以遍历L的时候还是原来的样子。情况2:
P.next = P.next.next影响L
此时P和L都指向第一个节点,修改P.next本质是直接修改这个节点的next属性——相当于用钥匙打开第一个节点的门,把它原本指向第二个节点的“门牌号”改成了第三个节点的。L指向的还是这个被修改过的第一个节点,所以遍历L的时候,第一个节点的next直接跳去第三个,自然跳过了节点2。情况3:
P.val = 10影响L
和情况2同理,P和L指向同一个第一个节点,修改P.val就是修改这个节点的val属性,相当于打开门把里面的数值改成了10。L指向的还是这个节点,遍历的时候自然会显示修改后的数值。
内容的提问来源于stack exchange,提问作者GTordon
相关产品推荐
相关产品推荐

