将项目插入链表 - 是否需要迭代(C)?

时间:2015-12-29 05:23:34

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

我目前正在研究面试准备的链接列表,如果有人能够对此有所了解,我将不胜感激。假设C中的以下函数在某个元素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;
}

然而,由于它看起来过于简单化,我觉得它可能不起作用,但我不确定为什么。我需要一些关于为什么这可能有效或无效的技术细节的见解,谢谢。

4 个答案:

答案 0 :(得分:2)

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

您可以在使用之前为对象分配内存来纠正错误:

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

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

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

示例函数正在做的是:给定一个元素以插入新数据之后,它会查看以head开头的列表来查找相同的元素,然后插入数据 - 找到headelem后无效。因为所有循环都是"找到"

是一个你已经拥有指针的元素,它基本上什么也没做,也没用。

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

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