在链表中插入一个项-这是迭代所必需的(C)



我目前正在研究面试准备的链接列表,如果有人能对此有所了解,我将不胜感激。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当作有效指针使用的错误。事实并非如此。它未初始化为指向有效对象。

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

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

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

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

示例函数所做的是:给定一个元素插入新数据,它会在以head开头的列表中查找同一个元素,然后插入数据-在找到它之后不使用headelem。由于循环所做的只是"查找"一个已经有指针的元素,所以它基本上什么都没做,也没有用。

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

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

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

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

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

这将不起作用,因为您不知道您的newElem。在链接列表中,你有关于头部的知识,每个元素都会为你提供下一个元素的信息:

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

因此,您需要进行迭代,直到找到您关心的元素为止。但您也可以使用递归进行迭代。

相关内容

  • 没有找到相关文章

最新更新