链表合并算法疑问:为何打印tail.next显示完整子链表而非单个节点?
问题背景
我正在实现合并两个有序链表的算法,代码如下:
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: x = ListNode() tail = x while list1 and list2: if list1.val <= list2.val: tail.next = list1 # print(tail.next) list1 = list1.next else: tail.next = list2 # print(tail.next) list2 = list2.next tail = tail.next if list1: tail.next = list1 # print(tail.next) else: tail.next = list2 # print(tail.next) # print(x.next) return x.next
输入list1=[1,2,4]、list2=[1,3,4]时,输出结果正确为[1,1,2,3,4,4]。但打印tail.next时发现,例如首次进入if分支时,我预期应仅显示当前选中的单个ListNode(如val=1的节点),实际却打印出list1的剩余完整子链表,后续打印也存在类似情况,具体打印输出如下:
ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 4, next: None}}}
ListNode{val: 1, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}
ListNode{val: 2, next: ListNode{val: 4, next: None}}
ListNode{val: 3, next: ListNode{val: 4, next: None}}
ListNode{val: 4, next: None}
ListNode{val: 4, next: None}
ListNode{val: 1, next: ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 3, next: ListNode{val: 4, next: ListNode{val: 4, next: None}}}}}}
原因分析
这是因为链表节点是引用类型,每个ListNode对象的next属性指向的是另一个ListNode的引用。当你打印一个链表节点时,Python会递归打印它所有的后续节点(直到next为None),而不是只打印当前节点本身。
举个例子,首次进入if分支时,tail.next = list1,此时的list1就是原链表的第一个节点(val=1),这个节点的next本来就指向原list1的第二个节点(val=2),而第二个节点的next又指向val=4的节点。所以打印这个节点时,Python会顺着next链把所有关联的节点都打印出来,这不是代码逻辑的问题,只是打印行为的特性。
你的合并逻辑是完全正确的——虽然打印出来的是整个剩余子链表,但实际上你只是把当前节点的引用挂到了结果链表的尾部,之后通过list1 = list1.next移动指针,并不会影响已经挂到结果链上的节点。后续合并过程中,结果链表会逐步把这些节点的next正确衔接,最终得到有序的合并链表。
验证方式
如果想只打印当前节点的val值,而不是整个子链表,可以修改打印语句为:
print(tail.next.val)
这样就能只输出当前节点的数值,符合你预期的“单个节点”展示效果。
内容的提问来源于stack exchange,提问作者romesh prasad

