在C中添加和排序链表

在C中添加和排序链表,c,pointers,linked-list,structure,C,Pointers,Linked List,Structure,在我的作业中,我必须编写一个函数,该函数以指向“LNode”结构的指针和整数参数作为参数。然后,我不仅要将该整数添加到链表中,还要将其放置在适当的升序中。我已经尝试了几种不同的尝试,这是我发帖时的代码 LNode* AddItem(LNode *headPtr, int newItem) { auto LNode *ptr = headPtr; ptr = malloc(sizeof(LNode)); if (headPtr == NULL)

在我的作业中,我必须编写一个函数,该函数以指向“LNode”结构的指针和整数参数作为参数。然后,我不仅要将该整数添加到链表中,还要将其放置在适当的升序中。我已经尝试了几种不同的尝试,这是我发帖时的代码

LNode*  AddItem(LNode  *headPtr, int  newItem)
{
    auto    LNode   *ptr = headPtr;

    ptr = malloc(sizeof(LNode));

    if (headPtr == NULL)
    {
        ptr->value = newItem;
        ptr->next = headPtr;
        return ptr;
    }
    else
    {

        while (headPtr->value > newItem || ptr->next != NULL)
        {
            printf("While\n"); // This is simply to let me know how many times the loop runs
            headPtr = headPtr->next;
        }
        ptr->value = newItem;
        ptr->next = headPtr;
        return ptr;
    }

}  // end of "AddItem"
当我运行它,尝试插入,比如说5,然后是3,5被插入,但是while循环运行一次,我得到了一个分段错误

此外,我无法更改参数,因为它是该项目框架代码的一部分。谢谢所有能帮忙的人

如果有帮助的话,这就是结构的样子

typedef struct  LNode
{
    int                 value;
    struct  LNode      *next;

} LNode;

您的while循环条件错误。您从未设置
ptr->next
,但您使用它来检查
ptr->next=NULL
这意味着
headPtr=headPtr->next
在循环中变得疯狂。因此,一旦设置了它的值,就应该设置:
ptr->next=NULL

您也可以将这些行取出并放在顶部:

   ptr->value = newItem;
   ptr->next = headPtr;
试试这个:

LNode*  AddItem(LNode  *headPtr, int  newItem)
{
    auto    LNode   *ptr, *temp, *orghead;
    orghead = headPtr;
    int fl=0;
    ptr = malloc(sizeof(LNode));
    ptr->value = newItem;
    ptr->next = NULL;
    temp = ptr;

    if (headPtr == NULL)
        return ptr;
    else
        {

        while(headPtr != NULL && headPtr->value < newItem)
            {
            printf("While\n");
            fl =1;
            temp = headPtr;
            headPtr = headPtr->next;
            }
        temp->next = ptr;
        ptr->next = headPtr;
        if(fl) return orghead;
        else return temp;
        }

}  // end of "AddItem"
LNode*AddItem(LNode*headPtr,int newItem)
{
自动节点*ptr,*temp,*orghead;
orghead=头PTR;
int fl=0;
ptr=malloc(sizeof(LNode));
ptr->value=newItem;
ptr->next=NULL;
温度=ptr;
如果(headPtr==NULL)
返回ptr;
其他的
{
while(headPtr!=NULL&&headPtr->valuenext;
}
温度->下一步=ptr;
ptr->next=headPtr;
如果(fl)返回原点;
否则返回温度;
}
}//附加项结束

while循环一直持续到链接列表的末尾,最后一个元素为null。因此,在while条件下,您将取消对空节点(headPtr)的引用,这样会导致分段错误。我认为您需要检查您的节点是否为空,如下所示:

while (headPtr != NULL && (headPtr->value > newItem || ptr->next != NULL))
在你的圈子里

while (headPtr->value > newItem || ptr->next != NULL)
    {
    printf("While\n"); // This is simply to let me know how many times the loop runs
    headPtr = headPtr->next;
检查未初始化的
ptr->next
是否为(非)
NULL
。这是不明智的,如果
ptr
的该部分中的位模式不是
NULL
指针的位模式,则可能会造成严重破坏,因为您在条件中有一个
|
,那么循环条件始终为真,并且您将从列表末尾运行

无论如何,
|
都是错误的,您需要一个
&&
,这两个条件都必须保持,有些东西不是
NULL,并且值之间的关系必须保持

而且,由于您希望列表按升序排列,因此必须在列表中的值小于要插入的值时遍历列表

但必须在指向的值变大或大于新值之前停止,因为必须修改节点的
next
指针,然后插入新值

if (headPtr->value >= newItem) {
    ptr->value = newItem;
    ptr->next = headPtr;
    return ptr;
}
while(headPtr->next != NULL && headPtr->next->value < newItem) {
    headPtr = headPtr->next;
}
// Now headPtr is the node behind which the new item is to be inserted
ptr->value = newItem;
ptr->next = headPtr->next;
headPtr->next = ptr;
return ??
if(headPtr->value>=newItem){
ptr->value=newItem;
ptr->next=headPtr;
返回ptr;
}
while(headPtr->next!=NULL&&headPtr->next->valuenext;
}
//现在,headPtr是要在其后面插入新项的节点
ptr->value=newItem;
ptr->next=头ptr->next;
headPtr->next=ptr;
返回??

但是你会返回什么指针呢?如果新项目是列表中的第一个,则返回指向第一个节点的指针。如果您还想在以后插入新项目时执行此操作,则需要保留(一份)原始
headPtr
,并将其返回。

以上所有内容都是如此

while (headPtr->value > newItem || ptr->next != NULL)
        {
            printf("While\n"); // This is simply to let me know how many times the loop runs
            headPtr = headPtr->next;
        }
您没有检查内部headPtr的空条件,而

此时

headPtr = headPtr->next;
headPtr->next可以为null,这会导致程序崩溃

多一点

LNode*  AddItem(LNode  *headPtr, int  newItem)
{

auto    LNode   *ptr = headPtr; ?

    ptr = malloc(sizeof(LNode));

    if (headPtr == NULL)
    {
        ptr->value = newItem;
        ptr->next = headPtr;
        return ptr;
    }
假设headPtr不为NULL,ptr现在指向某个malloc堆 ptr->next可能为空,也可能不为空

while (headPtr->value > newItem || ptr->next != NULL)
将是不可预测的

也许你需要多看看你的逻辑

如果您愿意,请参阅下面的伪逻辑

LNode* add_time(LNode *headptr , data){

    LNode   *ptr =  headptr, *temp;        

    temp = malloc(sizeof(LNode));

    if(!temp) 
      return ptr;

    temp->next = NULL;
    temp->value= data;

    if(ptr == NULL){ 
        /** There is no list**/
        ptr = temp;
        return ptr;
     }

    /* go to last node*/
    while(ptr->next)
        ptr = ptr->next;

    ptr->next = temp;

    return ptr;

}

丹尼尔·菲舍尔有一个更好的答案还在做那件事。我试着画一幅记忆位置的图,试着去理解它。显示函数只是通过链表,所以我怀疑它是否与此相关,即使是这样,我也无法更改该函数。你有使用gdb的经验吗?当程序运行时,一步一步地检查程序并观察所有变量都在做什么是很有指导意义的。headPtr是您的head节点还是ptr新节点?