单链表最大重复元素序列删除逻辑失效,执行异常求助
问题解决:单链表删除最长重复序列的BUG修复
你的代码核心逻辑方向没问题,但在指针处理、边界判断和状态变量管理上出了漏洞,导致程序卡住、报错或删除逻辑失效。下面梳理问题,给出修复后的代码和关键说明。
原代码的核心问题
- 非法访问None属性:第一个while循环中,当
pointer是最后一个节点时,pointer.next为None,此时执行pointer.next.elem直接触发报错,这也是你之前遇到崩溃的原因。 - 状态变量逻辑混乱:变量
a的切换时机完全错误,导致序列的起始/结束位置记录彻底混乱,最后一个元素无法被正常处理,后续删除逻辑也找不到正确的前驱和后继节点。 - 依赖位置计数易出错:用
count、first、last这类位置变量跟踪序列,远不如直接用指针跟踪节点准确,很容易因为计数偏差导致误删整个链表或删不掉目标序列。 - 删除阶段指针越界:后续for循环中,当
pointer2遍历到链表尾部时,pointer2.next为None,访问pointer2.next.elem会再次报错,且无法正确定位first_after_sequence。
修复后的代码
from slistH import SList from slistH import SNode class SList2(SList): def delLargestSeq(self): # 空链表或只有一个节点,无需处理直接返回 if self._head is None or self._head.next is None: return # 初始化变量:跟踪最长重复序列的前驱、结束节点,以及当前序列长度 max_seq_len = 1 current_seq_len = 1 prev_node = self._head current_node = self._head.next # 记录最长序列的关键节点:前驱节点、结束节点 max_prev_node = None max_end_node = self._head while current_node is not None: if current_node.elem == prev_node.elem: current_seq_len += 1 # 当前序列长度超过已记录的最长序列时,更新最长序列信息 if current_seq_len > max_seq_len: max_seq_len = current_seq_len # 找到当前序列的前驱节点 temp = self._head max_prev_node = None while temp != prev_node and temp is not None: max_prev_node = temp temp = temp.next max_end_node = current_node else: # 当前序列结束,比较长度是否更新最长序列 if current_seq_len > max_seq_len: max_seq_len = current_seq_len temp = self._head max_prev_node = None while temp != prev_node and temp is not None: max_prev_node = temp temp = temp.next max_end_node = prev_node # 重置当前序列长度 current_seq_len = 1 # 移动指针继续遍历 prev_node = current_node current_node = current_node.next # 处理最后一段未比较的序列 if current_seq_len > max_seq_len: max_seq_len = current_seq_len temp = self._head max_prev_node = None while temp != prev_node and temp is not None: max_prev_node = temp temp = temp.next max_end_node = prev_node # 执行删除操作 if max_prev_node is None: # 最长序列在链表头部,直接修改head指向序列后的第一个节点 self._head = max_end_node.next else: # 前驱节点的next指向最长序列后的第一个节点 max_prev_node.next = max_end_node.next # 测试代码 nodes_list = SList2() for i in (1, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6): nodes_list.addLast(i) print(nodes_list) nodes_list.delLargestSeq() print(f"{nodes_list} || final list")
关键修复说明
- 提前处理边界情况:先判断空链表或只有一个节点的场景,直接返回避免后续逻辑出错。
- 用指针直接跟踪序列:放弃位置计数,改用
prev_node和current_node跟踪当前序列,同时记录最长序列的max_prev_node(前驱节点)和max_end_node(结束节点),删除时只需修改指针指向即可,逻辑更可靠。 - 避免非法访问:所有访问节点
next或elem的操作,都确保当前节点不为None。 - 补全最后序列的判断:遍历结束后单独处理最后一段序列的长度比较,避免漏掉最后一段重复序列。
- 正确处理头部序列:如果最长序列在链表头部,直接修改
self._head指向序列后的节点,无需额外找前驱。
测试你的输入链表[1,3,3,3,3,4,4,5,5,5,6,6],最长重复序列是4个3,删除后链表会变成[1,4,4,5,5,5,6,6],程序可以正常结束,不会出现卡住、报错或删除错误的情况。
内容的提问来源于stack exchange,提问作者Raúl Armas
相关产品推荐
相关产品推荐

