Python单链表remove函数失效,请求代码错误排查帮助
Hey,你的单链表大部分功能都没问题,但remove函数里藏了几个容易踩的坑,导致它彻底失效。我帮你把这些问题揪出来,再给你修复后的代码:
1. 赋值运算符误用(== vs =)
这是低级但致命的错误:你在remove函数里用了比较运算符==来做变量赋值,比如prev == self.head和prev == prev.next,这些语句根本不会改变prev的值,等于白写。必须改成赋值运算符=才能正确更新变量。
2. 前驱节点查找逻辑错误
你当前的循环只是一个劲往后遍历,完全没判断是否找到了目标节点v的前一个节点。正确的逻辑应该是循环到prev.next == v时停下来,这时候的prev才是我们需要的前驱节点。
3. 删除节点后未维护size属性
你忘了在删除节点后将self.size -= 1,这会导致链表的长度统计和实际节点数不一致,后续的size命令输出也会出错。
4. remove函数无返回值,但调用时做了返回值判断
你的主程序里用if L.remove(x)判断删除是否成功,但原remove函数没有返回值(默认返回None),所以这个判断永远为False,会一直输出错误提示。我们需要让remove返回True/False来表示操作是否成功。
5. 冗余的size方法引发递归死循环
你已经实现了__len__方法,又额外定义了def size(self): return self.size,这会触发无限递归调用(self.size会调用该方法,方法内部又返回self.size),直接报错。这个方法完全可以删掉,用len(L)就能正确获取链表长度。
修正后的完整代码
class Node: def __init__(self, key=None): self.key = key self.next = None def __str__(self): return str(self.key) class SinglyLinkedList: def __init__(self): self.head = None self.size = 0 def __len__(self): return self.size def printList(self): v = self.head while(v): print(v.key, "->", end=" ") v = v.next print("None") def pushFront(self, key): new_node = Node(key) new_node.next = self.head self.head = new_node self.size += 1 def pushBack(self, key): new_node = Node(key) if self.size == 0: self.head = new_node else: tail = self.head while tail.next != None: tail = tail.next tail.next = new_node self.size += 1 def popFront(self): key = None if len(self) > 0: key = self.head.key self.head = self.head.next self.size -= 1 return key def popBack(self): if self.size == 0: return None else: previous, current = None, self.head while current.next != None: previous, current = current, current.next tail = current key = tail.key if self.head == tail: self.head = None else: previous.next = tail.next self.size -= 1 return key def search(self, key): v = self.head while v: if v.key == key: return v v = v.next return None def remove(self, v): if self.head is None or v is None: return False # 处理目标节点是头节点的情况 if v == self.head: self.head = v.next self.size -= 1 del v return True # 查找目标节点的前驱节点 prev = self.head while prev is not None and prev.next != v: prev = prev.next # 目标节点不在链表中 if prev is None: return False # 调整指针删除节点 prev.next = v.next self.size -= 1 del v return True L = SinglyLinkedList() while True: cmd = input().split() if cmd[0] == "pushFront": L.pushFront(int(cmd[1])) print(int(cmd[1]), "is pushed at front.") elif cmd[0] == "pushBack": L.pushBack(int(cmd[1])) print(int(cmd[1]), "is pushed at back.") elif cmd[0] == "popFront": x = L.popFront() if x == None: print("List is empty.") else: print(x, "is popped from front.") elif cmd[0] == "popBack": x = L.popBack() if x == None: print("List is empty.") else: print(x, "is popped from back.") elif cmd[0] == "search": x = L.search(int(cmd[1])) if x == None: print(int(cmd[1]), "is not found!") else: print(int(cmd[1]), "is found!") elif cmd[0] == "remove": x = L.search(int(cmd[1])) if L.remove(x): print(x.key, "is removed.") else: print("Key is not removed for some reason.") elif cmd[0] == "printList": L.printList() elif cmd[0] == "size": print("list has", len(L), "nodes.") elif cmd[0] == "exit": print("DONE!") break else: print("Not allowed operation! Enter a legal one!")
现在你可以测试remove功能了:不管是删除头节点还是中间节点,链表都会正确更新,size也会同步变化,主程序里的删除成功提示也能正常触发。
内容的提问来源于stack exchange,提问作者DeadlyCuteprogramming

