Duplicate Nodes Multiple of 5 in C Singly Linked List

Computer science4.29 KB

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.

Download

PDF Word HTML