It is very possible. I came up with a solution that is probably not optimal, but shows that this can be done. First, break it into two tasks: flip the following pointers and change the random pointers.
Change the following pointers:
node* last = NULL; node* current = head; node* next = head->next; while (current != NULL) { current->next = last; last = current; current = next; if (current != NULL) next = current->next; } head = last
Reversing a random list is a bit more complicated because we donβt have a list of all the chapters in the chain of random pointers, but we can find their ends (nodes will have a NULL random pointer). To do this, we need several auxiliary functions. The first is a random list. We basically copy the code from above. Note that we assign the end of the chain to a special value. This stops us from re-reversing the list. See Discussion in the comments for an explanation.
node* chainTail = malloc(1); //mallocing here to get a unique pointer void reverseRandom(node* rhead) { node* last = chainTail; node* current = rhead; node* next = rhead->random; while (current != NULL) { current->random = last; last = current; current = next; if (current != NULL) next = current->random; } }
We also need a helper function to find the parent element of the node (or return NULL if it is not). We will do a mute linear search:
node* findParent(node* target) { node* candidate = head; while ((candidate != NULL) && (candidate->random != target)) candidate = candidate->next; return candidate; }
Now we just go through the list, find any nodes that have a random NULL value (our chain tails), find their chain heads and reverse the chains:
node* current = head; //Current node in a linear walk looking for chain tails while (current != NULL) { if (NULL == current->random) { //current is the tail of a random chain, lets find the head node* curr = current; //Current node in the search for the chain hean node* parent = findParent(curr); while (parent != NULL) { curr = parent; parent = findParent(curr); } //At this point, curr is the head of the random chain, so reverse it reverseRandom(curr); } current = current->next; } //Clean up chainTail pointers node* current; for (current = head; current != NULL; current = current->next) { if (current->random == chainTail) { current->random = NULL; } } free(chainTail); //Stop a memory leak if this is not a global
Standard disclaimer: I do not run this code. He may have errors. I started to sleep near the end, so I may have made a logical mistake, but it seems to me that I'm working.
Also, if you want to put it into production, don't do it. This code works somewhere around O (n ^ 3). This is most likely not the fastest solution. It uses constant space (although even this can probably be reduced by lining and aggressive exchange of variables).