【问题标题】:c - Adding new item to a listc - 将新项目添加到列表中
【发布时间】:2013-05-30 20:19:43
【问题描述】:

此函数获取指向列表中“虚拟”项(第一项)的指针和一个struct 键入的“节点”以添加...

但它进入了一个无限循环......怎么了???

void listAdd(Node* dummy, Node tmpNode) {

    Node* toAdd = (Node*)malloc(sizeof(Node));
    *toAdd = tmpNode;
    Node *tmp1,*tmp2;
    tmp1 = dummy;
    tmp2 = (*dummy).next;

    while (tmp1 != NULL){

            if ( ((*tmp1).info.id < (*toAdd).info.id && (*tmp2).info.id > (*toAdd).info.id ) || (tmp2==NULL) ) {
                    (*toAdd).next = (*tmp1).next;
                    (*tmp1).next = toAdd;
                    return;
            }

            tmp1 = (*tmp1).next;
            tmp2 = (*tmp2).next;   
    }
}

【问题讨论】:

  • 为什么要遍历整个列表以将tmpNode 添加到列表中?通常,当您有一个链表并且想要向其中添加一个节点时,您可以将它添加到前面。这样更有效率。顺便说一句,dummy 不是一个好名字。像head 这样的东西会更好。
  • 可读性提升:(*tmp1).infotmp1-&gt;info
  • 然后为您解答。我正在通过其 ID 字段将节点添加到他的位置 - 它需要以这种方式排序。
  • 您是否只使用listAdd 将元素添加到列表中?如果是这样,您如何创建初始空列表?

标签: c list


【解决方案1】:

编辑: 我对此有点不知所措(这是工作缓慢的一天),所以我重写了函数以使用(恕我直言)更清晰的变量名称,更少的冗余变量,并添加了基本的错误处理。下面的示例支持插入,而前面的示例假设简单地附加到列表的末尾,这是未正确阅读问题的结果(如果您好奇,请参阅编辑)。

void listAdd(Node* currentNode, Node toAdd)
{
    Node * newNode = malloc(sizeof(Node));
    if(!newNode){
        //ERROR HANDLING
    }
    * newNode = toAdd;
    newNode->next = NULL;
    while (currentNode)
    {
        if(!currentNode->next) 
        //We've got to the end of the list without finding a place to insert the node.
        //NULL pointer always evaluates to false in C regardless of the underlying value.
        {
            currentNode->next = newNode;
            return;
        }
        //Test each member of the list to find out whether to insert or skip.
        if((newNode->info.id > currentNode->info.id) && (newNode->info.id <= currentNode->next->info.id) ){
            newNode->next = currentNode->next;
            currentNode->next = newNode; 
            return;
        }
        else currentNode = currentNode->next;
    }
}

正如之前的帖子中提到的那样。取消引用指向结构成员的指针使用相当漂亮的-&gt; 表示法,它具有相当好的图像。另请注意,NULL 将始终评估为假,除非您希望发生一些不好的事情(最好是段错误,最坏的情况是某些接管您的机器),您需要确保写入正确的内存区域,因此您必须始终检查 malloc 是否返回 !NULL

注意:在 C 中,切勿强制转换 malloc() 调用的返回值,因为这会掩盖奇怪和危险的行为。在 C++ 中,您必须转换结果,因此如果您希望您的程序编译为有效的 C 和 C++,您需要考虑会冒犯谁。详情请见Do I cast the result of malloc?

【讨论】:

  • 最好将 tmp2 == NULL 上的测试移动到 if 的开头,并在您的修复中将其作为单独的案例。如果元素插入到中间,那么他对toAdd-&gt;next 的赋值是正确的。我实际上不确定您的解决方法。注意tmp2 == tmp1-&gt;next.
  • @BryanOlivier 好点。我没有考虑在列表的中间添加,只是在末尾。现在会解决这个问题。
  • thenx 为您解答 - 但代码假设将项目添加到列表的中间部分,因此“toAdd”的“下一个”字段假设是下面项目的“下一个”字段他。如果我的评论不够清楚,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多