链表删除元素逻辑错误:删除目标元素时误删后继元素求助
链表删除元素逻辑错误排查与修复
问题现象
实现链表删除功能时出现逻辑错误:删除指定元素时,实际被删除的是该元素的后继元素。例如依次输入元素:"Hello"、"This"、"Is"、"Not"、"A"、"Test",执行删除"Not"的操作后,被删除的却是"A"。
原始代码
Module Program Public Resp, Counter1, CurrentPointer, NextPointer, StartPointer, Counter, ReturnVal, PrevP As Integer Public SearchQ As String Structure DP Dim Data As String Dim Pointer As Integer End Structure Public LinkedL(10) As DP Sub Main(args As String()) Call Initialise() Do Console.WriteLine("Select 1 to enter data") Console.WriteLine("Select 2 to delete data") Console.WriteLine("Select 3 to output data") Console.WriteLine("Select -1 to exit") Resp = Console.ReadLine If Resp = 1 Then Call EnterD() ElseIf Resp = 2 Then Call DeleteD() ElseIf Resp = 3 Then Call OutputD() ElseIf Resp = -1 Then Console.WriteLine("Goodbye") Exit Do End If Loop End Sub Sub Initialise() StartPointer = 0 NextPointer = 0 Counter1 = 1 For Counter = 0 To 9 LinkedL(Counter).Pointer = Counter1 Counter1 += 1 Next LinkedL(10).Pointer = -1 End Sub Sub EnterD() If NextPointer = -1 Then Console.WriteLine("Linked list is full") Else CurrentPointer = NextPointer Console.WriteLine("Enter data") LinkedL(CurrentPointer).Data = Console.ReadLine() NextPointer = LinkedL(CurrentPointer).Pointer Console.WriteLine("Done") End If End Sub Sub DeleteD() Console.WriteLine("Enter data to delete") SearchQ = Console.ReadLine Counter = StartPointer ReturnVal = -1 Do If LinkedL(Counter).Data = SearchQ Then ReturnVal = LinkedL(Counter).Pointer Exit Do Else Counter += 1 End If Loop Until LinkedL(Counter).Pointer = -1 If LinkedL(Counter).Pointer = -1 Then Console.WriteLine("Data to be deleted is not found") End If If ReturnVal <> -1 Then Counter = 0 Do If LinkedL(Counter).Pointer = ReturnVal Then PrevP = Counter LinkedL(PrevP).Pointer = LinkedL(ReturnVal).Pointer Exit Do Else Counter += 1 End If Loop Console.WriteLine("Successfully deleted") End If End Sub Sub OutputD() Counter = StartPointer Do Console.WriteLine(LinkedL(Counter).Data) Counter = LinkedL(Counter).Pointer Loop Until Counter = -1 End Sub End Module
错误分析
- 目标元素标识错误:在
DeleteD方法中,找到目标元素后,ReturnVal被赋值为LinkedL(Counter).Pointer(即目标元素的后继节点索引),而非目标元素自身的索引。后续操作基于这个错误的索引修改指针,导致删除的是后继元素。 - 遍历逻辑错误:遍历链表时使用
Counter += 1而非通过节点的Pointer属性跳转,这违背了链表的遍历规则。虽然初始分配时节点索引连续,但删除操作会打破这种连续性,同时这种遍历方式会遗漏最后一个节点(循环终止条件是LinkedL(Counter).Pointer = -1,最后一个节点的Pointer是-1,循环会提前终止,无法检查最后一个节点的Data)。 - 前驱节点查找逻辑冗余且错误:单独循环查找前驱节点完全没必要,遍历目标元素时可以同时记录前驱节点,提升效率且避免逻辑错误。
修正方案
重写DeleteD方法,修复上述问题:
Sub DeleteD() Console.WriteLine("Enter data to delete") SearchQ = Console.ReadLine() Dim currentNode As Integer = StartPointer Dim prevNode As Integer = -1 Dim targetNode As Integer = -1 ' 遍历链表查找目标元素,同时记录前驱节点 Do While currentNode <> -1 If LinkedL(currentNode).Data = SearchQ Then targetNode = currentNode Exit Do End If prevNode = currentNode currentNode = LinkedL(currentNode).Pointer Loop If targetNode = -1 Then Console.WriteLine("Data to be deleted is not found") Return End If ' 处理删除逻辑 If prevNode = -1 Then ' 要删除的是头节点 StartPointer = LinkedL(targetNode).Pointer Else ' 修改前驱节点的指针,跳过目标节点 LinkedL(prevNode).Pointer = LinkedL(targetNode).Pointer End If ' 回收节点(将删除的节点加入空闲链表) LinkedL(targetNode).Pointer = NextPointer NextPointer = targetNode Console.WriteLine("Successfully deleted") End Sub
修正点说明
- 正确遍历链表:通过
currentNode = LinkedL(currentNode).Pointer实现链表的标准遍历,确保所有节点都能被检查到,包括最后一个节点。 - 记录目标与前驱节点:遍历过程中同时记录目标节点索引和其前驱节点索引,无需后续二次查找。
- 处理头节点特殊情况:如果删除的是头节点,直接更新
StartPointer为头节点的后继。 - 回收空闲节点:将删除的节点重新加入空闲链表(更新
NextPointer),实现链表节点的复用,符合链表的内存管理逻辑。
内容的提问来源于stack exchange,提问作者Borkode
相关产品推荐
相关产品推荐

