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

链表删除元素逻辑错误:删除目标元素时误删后继元素求助

链表删除元素逻辑错误排查与修复

问题现象

实现链表删除功能时出现逻辑错误:删除指定元素时,实际被删除的是该元素的后继元素。例如依次输入元素:"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

错误分析

  1. 目标元素标识错误:在DeleteD方法中,找到目标元素后,ReturnVal被赋值为LinkedL(Counter).Pointer(即目标元素的后继节点索引),而非目标元素自身的索引。后续操作基于这个错误的索引修改指针,导致删除的是后继元素。
  2. 遍历逻辑错误:遍历链表时使用Counter += 1而非通过节点的Pointer属性跳转,这违背了链表的遍历规则。虽然初始分配时节点索引连续,但删除操作会打破这种连续性,同时这种遍历方式会遗漏最后一个节点(循环终止条件是LinkedL(Counter).Pointer = -1,最后一个节点的Pointer是-1,循环会提前终止,无法检查最后一个节点的Data)。
  3. 前驱节点查找逻辑冗余且错误:单独循环查找前驱节点完全没必要,遍历目标元素时可以同时记录前驱节点,提升效率且避免逻辑错误。

修正方案

重写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

修正点说明

  1. 正确遍历链表:通过currentNode = LinkedL(currentNode).Pointer实现链表的标准遍历,确保所有节点都能被检查到,包括最后一个节点。
  2. 记录目标与前驱节点:遍历过程中同时记录目标节点索引和其前驱节点索引,无需后续二次查找。
  3. 处理头节点特殊情况:如果删除的是头节点,直接更新StartPointer为头节点的后继。
  4. 回收空闲节点:将删除的节点重新加入空闲链表(更新NextPointer),实现链表节点的复用,符合链表的内存管理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:25:02