简体   繁体   中英

C: Removing a node from singly-LinkedList1 and inserting it at the head of singly-LinkedList2

I'm doing a computer science project that simulates an operating system's process scheduler. I have multiple singly-linked lists , and need to move nodes between them. I am trying to write a general function to accomplish this, but I think my weakness using pointers is holding me back.

How do I implement the desired function? So far I have the following:

typedef struct process_list_struct ProcessList;

struct process_list_struct
{
    Process proc;
    ProcessList* next;
};

void change_lists(ProcessList* node, ProcessList* newlist)
{
    ProcessList* temp = NULL;
    debug_printf("change_lists reached\n");
    temp = node;
    if(!node)
    {
        debug_printf("Error: change_lists failed!\n");
        return;
    }
    node = node->next;
    temp->next = newlist;
    newlist = temp;
    return;
}

The result is strange... I end up with the first list containing only the node I wanted to move and everything else missing (pretty much the opposite effect than what I wanted), and the newlist (tested as starting empty) remains empty.

I have looked up implementations of node swaps in single lists and have seen people use double pointers instead, but that's really confusing me. Can someone please show me how to apply them in this case? I tried using them, but them combined with referencing pointer elements of structs got really confusing.

Help very much appreciated!

You following four steps are wrong to shift node from one list to other list:

temp = node
node = node->next;
temp->next = newlist;
newlist = temp;

See below I shown with a diagram:

Suppose you have node in linked list-1:

    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |----->|    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^   ^
                             |   |
                             |  node 
    after temp=node        temp

What after: node = node->next; things becomes like:

    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |----->|    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^                        ^
                             |                        |
                             temp                    node            

after temp->next = newlist; this ?

    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |      |    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^       |                ^
                             |       |                |
                             temp    |                node     
                                     |
                                     |
                                     |    "head node"
                                     |   +---+----+----+   +---+----+---+
         "This is your list-2"       |-->|   FIVE      |-->|   SIX      |--
                                         +---+---+-----+   +---+----+---+ 
                                          newlist

your lats step newlist = temp; ?

                           newlist                    
                            |
                            ▼ "head node"
    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |      |    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^       |                ^
                             |       |                |
                             temp    |                node     
                                     |
                                     |    
                                     |   +---+----+----+   +---+----+---+
         "This is your list-2"       |-->|   FIVE      |-->|    SIX     |--
                                         +---+---+-----+   +---+----+---+

This is What you do. but it is not what you wants ?
you algorithm to shift node from one list to other list is wrong additionally you made technical mistake that, you are passing pointer by values (you need pointer to pointer to reflect changes at calling function)

because you wants to shift node from one list to other, and pass pointers of node in one list and head of other list, You need to pass pointer of pointer to reflect change in calling function, hence your declaration seems to me wrong:

void change_lists(ProcessList* node, ProcessList* newlist)

I think it should be:

void change_lists(ProcessList** node, ProcessList** newlist) 

Write your code to shift node with this prototype.

Edit : (suggestion)

The basic problem in your code is that to shift a node ( eg one ) in list one you do not change pointer to previous nodes ( zero node in diagram ), You need to makes

[zero] ---> [two]

Similar mistake made by @CodeRat in his list: Swap nodes in a singly-linked list

I given him an answer that I think will help you to implement you code.

old answer:

One mistake that I can find: Instead of

*temp = *node;

you should write

temp = node;

address not values

doing *temp = *node; is Undefined behavior because you don't allocates memory for temp, You need to assign address in temp. (temp points to NULL) because you wants to shift node from one list to other list thats why you need temp = node;

I believe your prototype is wrong, it's too simplistic.

You can't move a node of a singly-linked list without somehow having the ability to afterwards change which node is considered the start of the list.

Otherwise, what happens if you move the first node? The surrounding code would retain the pointer, but the node is now logically part of the destination list for the move, and all is brokened.

Also, the same applies for the destination list: what if it's empty before the move?

One thing that's clearly wrong in this code is doing *temp = *node; when temp = NULL . You cannot dereference a NULL pointer.

Also, if node belongs to a singly-linked list, you can't remove it from the list if you only have a pointer to node . To remove it, you need to change the node that points to node so it doesn't point to node anymore and instead points to NULL or to the node that follows node . If you used a doubly-linked list, you could find the neighbor nodes to node given only a pointer to node .

To remove a node from single linked list, its previous node is required. The previous node has to be linked to the next node.

If the previous node is available to the function, then fine, but if not, then one has to start looking from the head. Thus, the head is required.

The heads for both the lists are required. And since remove or add operations can change the head pointers, it is natural to pass them as pointer-to-pointers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM