在链接列表中查找损坏

Finding corruption in a linked list

本文关键字:查找 损坏 列表 链接      更新时间:2023-10-16

我今天面试了一个开发人员职位,有人问我一个有趣的技术问题,我不知道答案。我会在这里问它,看看是否有人能为我的好奇心提供解决方案。这是一个多方面的问题:

1( 您得到了一个包含100个元素(整数和指向下一个节点的指针(的单链表,想办法检测链表中途是否有中断或损坏?您可以对链接列表执行任何操作。请注意,您必须在列表中这样做,因为它正在迭代,这是在您意识到列表有任何问题之前的验证。

假设链表中的中断位于第50个元素,则整数甚至指向下一个节点(第51个元素(的指针可能指向垃圾值,该垃圾值不一定是无效地址。

2( 请注意,如果链接列表中存在损坏,如何最大限度地减少数据丢失?

要测试"损坏"的整数,您需要知道有效值的范围。否则,无法确定任何给定(带符号(整数中的值是否无效。因此,假设您对int进行了有效性测试,那么在迭代到下一个元素之前,您将始终检查该值。

测试损坏的指针更为棘手——首先,您需要检查指向下一个元素的指针的值,然后再尝试去引用它,并确保它是一个有效的堆地址。这将避免分割错误。接下来的事情是验证指针指向的实际上是一个有效的链表节点元素——这有点棘手吗?也许可以将指针反引用到列表元素类/结构中,并测试int和"next"指针的有效性,如果它们也很好,那么可以非常确定上一个节点也很好。

在2(上,发现一个损坏的节点后,[如果下一个指针损坏]你应该做的是立即将上一个节点的"下一个指示器"设置为"NULL",将其标记为列表的末尾,并记录你的错误等。如果损坏只是整数值,而不是"下一"元素指针,然后,您应该从列表中删除该元素,并将前面和后面的节点链接在一起,因为在这种情况下,不需要丢弃列表的其余部分!

对于第一部分-重载新运算符。当分配一个新节点时,在节点前后分配一些额外的空间,并在那里放置一些已知值。在遍历中,可以检查每个节点是否在已知值之间。

如果您在设计时知道损坏可能会成为一个关键问题,您可以在节点数据结构中添加一个"神奇值"作为字段,从而确定某些数据是否可能是节点。甚至可以在内存中搜索节点。

或者将一些链接信息加倍,即在每个节点的下一个节点之后存储该节点的地址,以便在一个链接断开时进行恢复。

我看到的唯一问题是,你必须避免分割错误。

如果你可以对链表做任何事情,你可以做的就是计算每个元素的校验和,并将其存储在元素本身上。这样,即使是元素上的一个位错误,也可以检测到损坏。

为了最大限度地减少数据丢失,也许您可以考虑将nextPtr存储在上一个元素中,这样,如果您的当前元素已损坏,您总是可以从上一个中找到下一个元素的位置。

这是一个简单的问题,有几个可能的答案。每一种方法都以稳健和效率为代价。由于提高鲁棒性是所问问题的先决条件,因此存在既牺牲时间(列表遍历速度,以及节点的插入速度和删除速度(又牺牲空间(与每个节点一起存储的额外信息(的解决方案。现在的问题是,这是一个长度为100的固定列表,在这种情况下,链表的数据结构是最不合适的。为什么不让这个谜题更具挑战性,并说列表的大小不是先验的?

由于元素的数量(100(是已知的,第100个节点必须包含一个空指针。如果是,则具有一定概率的列表是有效的(例如,如果第99个节点已损坏并指向某个全为零的内存位置,则无法保证这一点(。否则,就会出现一些问题(这可以作为事实返回(。

upd:此外,在每个步骤中,如果给定指针,可以查看delete将使用的一些结构,但由于使用delete本身在任何意义上都不安全,因此这将是特定于实现的。