You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中通过集合长度判断删除双向链表重复节点为何失效?

问题根因

你的去重逻辑存在两个核心问题,导致功能无法正常生效:

  • 判断重复的维度错误:往集合seen中添加的是Node类的实例对象,而非节点存储的实际业务数据。Python中自定义类的实例默认按内存地址做哈希校验,哪怕两个节点的data值完全相同,只要是独立创建的不同对象,就会被判定为非重复元素,集合长度会随遍历持续增长,你写的重复判断分支永远不会触发。
  • 遍历链路中断:你通过temp = cur想暂存节点以保留后续遍历位置,但Python对象是引用传递,temp和cur指向同一个内存地址的节点。而你的delete_node方法在删除节点时,会主动将待删除节点的next、prev指针置空,删除操作执行完成后temp.next也会变为None,直接导致遍历提前终止,无法访问链表后续节点。
修正方案

你的delete_node方法、节点类、链表基础方法逻辑均正常,仅需修改remove_duplicates方法即可,修正后代码如下:

def remove_duplicates(self):
    cur = self.head
    seen = set()
    while cur:
        # 提前存储下一个遍历节点,避免当前节点指针被修改后丢失遍历位置
        next_node = cur.next
        if cur.data in seen:
            # 命中重复规则,删除当前节点
            self.delete_node(cur)
        else:
            # 非重复数据加入已见集合
            seen.add(cur.data)
        # 移动到提前存好的下一个节点
        cur = next_node
逻辑说明
  • 不再通过计算集合长度变化判断重复,直接用in关键字判断数据是否已存在,写法更简洁,判断效率为O(1)。
  • 在对当前节点做任何修改操作前,就提前把下一个要遍历的节点引用存到next_node中,不管后续当前节点的指针怎么被修改,都不会影响遍历链路,能完整走完整个链表。
测试验证

可以用以下用例验证效果:

if __name__ == "__main__":
    dll = DoublyLinkedList()
    test_data = [1,2,3,2,1,4,3]
    for val in test_data:
        dll.append(val)
    
    print("去重前链表元素:")
    dll.print_list()
    dll.remove_duplicates()
    print("去重后链表元素:")
    dll.print_list()

运行后输出符合预期,会保留第一次出现的节点,删除后续所有值重复的节点,最终输出为1、2、3、4。

内容的提问来源于stack exchange,提问作者JyZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:30:10