Home > OS >  C how to iterate and add a new node after a desired node in single Linked List
C how to iterate and add a new node after a desired node in single Linked List

Time:10-04

typedef struct ITEM {
  int value;
  struct ITEM *next;
}ITEM;

int add_after(ITEM *list, ITEM *c_item, int value)
{  
    ITEM *elem;

    //if head is NULL, it is an empty list
    if(c_item == NULL || list == NULL)
    {
        return -1;
    }

    //create a new node 
    elem = malloc(sizeof(ITEM));
    if(elem == NULL)
    {
      return -1;
    }
    elem->value = value;

    // iteration
    while(list != NULL)
    {
       if(list == c_item)
        {
          elem->next = list->next;
          c_item->next = elem;
          return 1;
        }
          list = list->value;
    }
    return 0;
}

What it should do: c_item should be equal to one of the exiting nodes in the list. After finding an equal, it should make a new node elem and put that node infront of c_item.

What my code does: list is HEAD value and compared with the c_item value and if its not the same then list goes to the next value in the list. After finding the equal, then it adds elem node to the list infront.

Problem: This only works with 1 existing node in the list. If there is 2 nodes then it gets stuck at list = list->value;.

// Linked List 10->20->30->NULL

//Input:
c_item = 20
elem = 100

//Output:
10->20->100->30->NULL

CodePudding user response:

StackOverflow is not a code-writing service. We do not undertake to do your homework for you. After all, "all of us once did it the hard way ... as must you."

CodePudding user response:

You seem to have the basics of most of what you want to do in place. Let's try to to reorganize your pieces, and perhaps you can get close to your desired solution.

I would first use comments to describe what I want to accomplish in the function.

int add_after (ITEM *list, ITEM *c_item, int value) {

    // Check c_item and list are not NULL
    // Check if c_item is in list
    // Create new elem with value
    // Add new elem after c_item

}

Then, I would write the code that accomplishes each of these things.

  • Check c_item and list are not NULL
    if (! (c_item && list)) return -1;
  • Check if c_item is in list
    if (! list_has_item(list, c_item)) return -1;
  • Create new elem with value
    ITEM *elem = create_item(value);
    if (elem == NULL) return -1;
  • Add new elem after c_item
    ITEM *old_after = c_item->next;
    c_item->next = elem;
    elem->next = old_after;

This last bit actually the specific question you ask about. The implementation remembers what used to be after the the c_item, makes the new element to be after it instead, then puts what used to be after c_item after the new element.

It is possible to make the same thing happen without the temporary. It is debatable what is more clear, but if you are curious, feel free to try to rewrite the three lines of above into two lines instead.

I think you already understand how to check if an item is in the list and how to create a new item, so I will leave those up to you to implement.

  • Related