Given I have a linked list, and I want to move a given node to the end of the list, is there a more elegant way of doing this, than what I've done here?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
} node_t;
void insert(node_t **head, int val)
{
node_t *new_node = malloc(sizeof(node_t));
node_t *tmp;
new_node->val = val;
new_node->next = NULL;
// Empty list?
if(*head == NULL) {
*head = new_node;
return;
}
tmp = *head;
while(tmp->next != NULL)
tmp = tmp->next;
tmp->next = new_node;
}
void movetoend(node_t **head, int val)
{
node_t *curr;
node_t *tmp = NULL;
node_t *old = NULL;
// Find val in list
for(curr = *head; curr != NULL; old = curr, curr = curr->next) {
if(curr->val == val) {
// Matched node is the only one in the list, don't do anything
if(curr->next == NULL)
return;
// Matched node is first, set next to jump over
if(old == NULL)
*head = curr->next;
// Matched node is in the middle, set next to jump over
else
old->next = curr->next;
// Set a pointer to matched node for later use
tmp = curr;
// Loop through the rest of the list
// "old" will have the pointer to last node
}
}
// No matches?
if(tmp == NULL)
return;
// Terminate list
tmp->next = NULL;
// Append matched node
old->next = tmp;
}
void print(node_t *head)
{
while(head) {
printf("%d\n", head->val);
head = head->next;
}
}
int main()
{
node_t *head = NULL;
insert(&head, 10);
insert(&head, 20);
insert(&head, 30);
movetoend(&head, 10);
print(head);
return 0;
}
EDIT: Added comments, modified movetoend function a bit slimmer.