Adding and sorting a linked list in C

我的未来我决定 提交于 2019-12-23 22:52:27

问题


In my assignment, I have to write a function that takes as arguments a pointer to a "LNode" structure and an integer argument. Then, I have to not only add that integer into the linked list, but also put place it so that the list is in proper ascending order. I've tried several various attempts at this, and this is my code as of posting.

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"

When I run it, and try to insert say a 5 and then a 3, the 5 gets inserted, but then the while loop runs once and I get a segmentation fault.

Also I cannot change the arguments as it's part of a skeletal code for this project. Thanks to anyone who can help.

If it helps this is what the structure looks like

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

} LNode;

回答1:


In your loop

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;

you check whether the uninitialised ptr->next is (not) NULL. That is not sensible and may cause havoc if perchance the bit pattern in that part of ptr is not that of a NULL pointer, because you have an || in the condition, then the loop condition is always true and you run off the end of your list.

The || is wrong anyway, you need a &&, both conditions must hold, something is not NULL and a relation among the values must hold.

And, since you want the list in ascending order, you must traverse the list while the value in the list is smaller than the to-be-inserted value.

But you must stop before the pointed-to value becomes as large as or larger than the new value, because you must modify the next pointer of the node after which you insert the new value.

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 ??

But what pointer will you return? If the new Item is the first in the list, you return a pointer to the first node. If you also want to do that if the new item is inserted later, you need to keep (a copy of) the original headPtr and return that.




回答2:


Your while loop condition is wrong. You never set ptr->next but you use it to check ptr->next!=NULL which means headPtr=headPtr->next goes wild in the loop. So you should set: ptr->next=NULL once you set its value.

You can also take these lines out and put it at the top:

   ptr->value = newItem;
   ptr->next = headPtr;

Try this:

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"



回答3:


Your while loop goes until the end of your linked list, and your last element is null. Thus in your while condition you are dereferencing a null node (headPtr), this way getting the segmentation fault. I think you need to check whether your node is null or not like this:

while (headPtr != NULL && (headPtr->value > newItem || ptr->next != NULL))



回答4:


so true from all the above

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;
        }

You are not checking null Condition for headPtr inside While

at this point

headPtr = headPtr->next;

headPtr->next can be null which makes your program to crash

bit more

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;
    }

consider headPtr is not NULL, ptr is now pointing to some malloc heap ptr->next may or may not be NULL insuch case

while (headPtr->value > newItem || ptr->next != NULL)

will be un-predictable

may be you need to look at your logic a little more

see below for pseudo logic if you like

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;

}


来源:https://stackoverflow.com/questions/10050336/adding-and-sorting-a-linked-list-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!