Duplicate Nodes Multiple of 5 in C Singly Linked List
Duplicate Nodes Multiple of 5 in a Singly Linked List
Given a singly linked list whose nodes are defined as follows:
struct node {
int data;
struct node *next;
};
Perform a doubling-to-top: duplicate all nodes whose data are multiples of 5 and place those copies at the front of the list.
Example:
If the original list:
| -> | 2 | -> | 5 | -> | 3 | -> | 6 | -> | 10 | -> | 1 | -> | 5 | -> | X |
then the final list becomes:
| -> | 5 | -> | 10 | -> | 5 | -> | 2 | -> | 5 | -> | 3 | -> | 6 | -> | 10 | -> | 1 | -> | 5 | -> | X |
Fixed C implementation
The corrected and polished C implementation below initializes a list of N_NODOS nodes, prints the list, duplicates nodes whose values are multiples of 5 into a temporary list, then prepends that temporary list to the original list.
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <conio.h> /* for getch() on Windows */
#endif
#define N_NODOS 15 /* Number of nodes to create */
/* Definition of the node structure */
struct node {
int data;
struct node *next;
};
typedef struct node tNode;
typedef struct node *TList;
/* Initialize list with N_NODOS nodes (data = 0..N_NODOS-1) */
void inicializa_lista(TList *list) {
int i;
tNode *pNodo = NULL;
tNode *aux = NULL;
for (i = 0; i < N_NODOS; i++) {
pNodo = (tNode *) malloc(sizeof(tNode));
if (pNodo == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
pNodo->data = i; /* fill data */
pNodo->next = NULL;
if (*list == NULL) { /* List is empty */
*list = pNodo;
} else { /* List is not empty: append at end */
aux = *list;
while (aux->next != NULL)
aux = aux->next;
aux->next = pNodo;
}
}
}
/* Print the list to the screen */
void imprime_lista(TList list) {
tNode *aux = NULL;
printf("\n| ->");
aux = list;
while (aux != NULL) {
printf(" | %d | ->", aux->data);
aux = aux->next;
}
printf(" | X |\n");
}
/* Duplicate nodes whose data is multiple of 5 and prepend them */
void duplica_nodos(TList *list) {
TList lista_aux = NULL; /* temporary list with duplicates */
tNode *aux = NULL, *aux2 = NULL;
tNode *copy = NULL;
aux = *list;
while (aux != NULL) {
if (aux->data % 5 == 0) {
copy = (tNode *) malloc(sizeof(tNode));
if (copy == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
copy->data = aux->data;
copy->next = NULL;
if (lista_aux == NULL) { /* If temporary list is empty */
lista_aux = copy;
} else { /* Append to temporary list */
aux2 = lista_aux;
while (aux2->next != NULL)
aux2 = aux2->next;
aux2->next = copy;
}
}
aux = aux->next;
}
/* Finally attach the original list after the temporary list */
if (lista_aux != NULL) {
aux = lista_aux;
while (aux->next != NULL)
aux = aux->next;
aux->next = *list;
*list = lista_aux;
}
}
int main(void) {
TList list = NULL;
inicializa_lista(&list);
imprime_lista(list);
duplica_nodos(&list);
imprime_lista(list);
/* Pause at end: use getch() on Windows or getchar() otherwise */
#ifdef _WIN32
getch();
#else
getchar();
#endif
return 0;
}
Notes
- Behavior: The program collects copies of nodes whose data % 5 == 0, appends those copies to a temporary list in the same order found, then concatenates that temporary list in front of the original list.
- Memory: Each duplicate is allocated with malloc; in production code you should free the list nodes when done.
- Compatibility: getch() requires <conio.h> on Windows; the code uses getchar() on other platforms to pause.