【问题标题】:Inserting an item to a linked list - is iteration necessary (C)?将项目插入链表 - 是否需要迭代(C)?
【发布时间】:2015-12-29 05:23:33
【问题描述】:

我目前正在研究面试准备的链接列表,如果有人能对此有所了解,我将不胜感激。 C 中的以下函数应该在某个 Element elem 之后将一个新元素插入到列表中(作为参数传递给函数):

bool insertAfter(Element * elem, int data){

    Element * newElem, * curPos = head;
    newElem->data = data;

    while(curPos){
        if(curPos == elem){
            newElem->next = curPos->next;
            curPos->next = newElem;
            return true;
        }
        curPos = curPos->Next;
    }
    return false;
}

虽然我正在学习的教科书中指定了上述内容,但我尝试提出一个不使用任何迭代的解决方案:

bool insertAfter(Element * elem, int data){
    Element * newElem;
    newElem->next = elem->next
    newElem->data = data
    elem->next = newElem;
    return true;
}

但是,由于它看起来过于简单,我感觉它可能不起作用,但不知道为什么。我需要一些关于为什么这可能会或可能不会起作用的技术细节,谢谢。

【问题讨论】:

  • newElem 未初始化。
  • 您在不使用 head 的情况下插入链表。您可以使用递归而不是迭代。
  • 迭代是必要的,因为您需要元素的链接,之后您要添加新元素。您的程序在开头添加元素,甚至没有重新定位头指针。因此它是无用的.
  • insertAfter 的第一个版本在继续插入之前会检查 elem 是否确实在列表中,而你的没有......但你的设计更好
  • 请注明书本以及可以找到该 sn-p 的位置:因为它给出了不初始化 newElem 的示例,所以它可能是一本避免使用的书。

标签: c algorithm linked-list singly-linked-list


【解决方案1】:

两个版本都存在使用newElem 的错误,就好像它是一个有效的指针一样。它不是。它未初始化为指向有效对象。

您可以通过在使用之前为对象分配内存来纠正此问题:

Element * newElem = malloc(sizeof(*newElem));

两个版本之间的区别在于,如果由于某种原因无法从head 访问elem,或者它是NULL,则第一个版本不会对现有列表执行任何操作。第二个版本不处理这两种情况。它假定elem 在列表中并且它不是NULL。

【讨论】:

    【解决方案2】:

    您的解决方案非常正确。示例中的迭代几乎完全没用。

    示例函数的作用是:给定一个要插入新数据的元素,它会查看以head 开头的列表以找到相同的元素,然后插入数据 - 做找到 headelem 后什么都没有。由于循环所做的只是“找到”一个您已经有指针指向的元素,因此它实际上什么也没做,而且毫无用处。

    唯一可能的用途是将插入函数限制为仅在整个程序中全局范围内以head 开头的一个列表上工作。这是一个如此奇怪的设计决策,除非有理由相信,否则人们可能会认为这是一个错误(动态数据结构被限制在单个实例中是一种不寻常的模式;更重要的是,整个观点链表是 O(1) 插入,示例函数通过添加这个无用的循环来中断)。 head 除了强制执行此约束之外,不需要任何其他原因,如果需要此 ,则将其作为参数传递会更有意义,以便函数能够每个程序可用于多个列表。 (或者,根本不执行检查:链表的另一种用途是您可以传递并在节点之后插入 而无需 担心头元素。)

    正如其他人所指出的,您没有实际分配newElem,但教科书也是如此。总的来说,这是一个垃圾例子。作者不仅在分配方面犯了错误,而且他们似乎没有理解使用链表的基本优势。你绝对应该怀疑这本教科书。

    【讨论】:

      【解决方案3】:

      您的逻辑将起作用,因为您只需要一个指向要插入节点的节点的指针。如果您已经有了这样的指针,则无需迭代和搜索节点。

      但是,如果手头没有要插入新节点的节点指针,则搜索(迭代)将是相关的。示例:假设节点具有唯一键,并且您没有键所在的节点指针,并且您想在找到包含特定键的节点后插入,那么您需要找到正确的节点指针并进行插入(然后函数应该将 key 作为参数)。

      但是在您的代码中(两种情况),您还没有为新节点分配内存。您需要为新节点执行malloc,然后继续插入。

      【讨论】:

        【解决方案4】:

        这不起作用,因为您不知道您的newElem。在链表中,您了解一个头部,每个元素都会为您提供在哪里可以找到下一个元素的信息:

        head -> e1 -> e2 -> ...
        

        所以你需要迭代直到你找到你关心的元素。但您也可以使用递归进行迭代。

        【讨论】:

          猜你喜欢
          • 2016-01-03
          • 1970-01-01
          • 2020-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多