Soy nuevo en programación en C y estoy tomando un curso. Tengo problemas con una de las tareas que estoy practicando. Se supone que debo escribir un programa que cree una lista enlazada de 10 caracteres y luego cree una copia de la lista en orden inverso. He escrito (principalmente copiado) un código, pero solo invierte el contenido de mi lista vinculada, no los copia a una nueva lista vinculada en orden inverso. Tampoco funciona con letras aunque estoy usando el tipo de datos char. funciona bien con los números.
Aquí está mi código:
#include <stdio.h> #include <malloc.h> struct Node { char data; struct Node *next; }; static void reverse(struct Node **head_ref) { struct Node *previous = NULL; struct Node *current = *head_ref; struct Node *next; while (current != NULL) { next = current->next; current->next = previous; previous = current; current = next; } *head_ref = previous; } void push(struct Node **head_ref, char new_data) { struct Node *new_node = (struct Node *)malloc(sizeof(struct Node)); new_node->data = new_data; new_node->next = (*head_ref); (*head_ref) = new_node; } void printList(struct Node *head) { struct Node *temp = head; while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } } int main() { struct Node *head = NULL; char element = NULL; printf("Enter 10 characters:\n"); for (int i = 0; i <= 9; i++) { scanf_s("%d", &element); push(&head, element); } printf("Given linked list\n"); printList(head); reverse(&head); printf("\nReversed Linked list \n"); printList(head); getchar(); }Esto para bucle
for (int i = 0; i <= 9; i++) { scanf_s("%d", &element); push(&head, element); } invoca un comportamiento indefinido porque se usa un especificador de conversión incorrecto %d con un objeto del tipo char ,
tienes que escribir
for (int i = 0; i <= 9; i++) { scanf_s( " %c", &element, 1 ); push(&head, element); } Preste atención al espacio en blanco antes del especificador de conversión %c en la cadena de formato. Esto permite omitir los caracteres de espacio en blanco en el flujo de entrada.
En cuanto a la función, entonces se puede declarar y definir de la siguiente manera simple usando la función push que ya definiste
struct Node * reverse_copy( const struct Node *head ) { struct Node *new_head = NULL; for ( ; head != NULL; head = head->next ) { push( &new_head, head->data ); } return new_head; }Y en main puedes escribir algo como
struct Node *second_head = reverse_copy( head ); Tenga en cuenta que la push de la función sería más segura si procesara la situación cuando falló la asignación de memoria para un nodo.
Para crear una copia en orden inverso, cree una nueva lista con los mismos valores que la lista original, pero anteponga los nuevos nodos con la función de push .
Aquí hay una versión modificada:
#include <stdio.h> #include <stdlib.h> struct Node { char data; struct Node *next; }; void prepend(struct Node **head_ref, char new_data) { struct Node *new_node = (struct Node *)malloc(sizeof(struct Node)); new_node->data = new_data; new_node->next = (*head_ref); (*head_ref) = new_node; } void append(struct Node **head_ref, char new_data) { struct Node *new_node = (struct Node *)malloc(sizeof(struct Node)); struct Node *node = *head_ref; new_node->data = new_data; new_node->next = NULL; if (!node) { *head_ref = new_node; } else { while (node->next) node = node->next; node->next = new_node; } } void printList(const struct Node *head) { const struct Node *temp = head; while (temp != NULL) { printf("%c ", temp->data); temp = temp->next; } printf("\n"); } struct Node *copy_reverse(struct Node *list) { struct Node *new_list = NULL; while (list) { prepend(&new_list, list->data); list = list->next; } return new_list; } void freeList(struct Node *list) { while (list) { struct Node *node = list; list = list->next; free(node); } } int main() { struct Node *head = NULL; char element; printf("Enter 10 characters:\n"); for (int i = 0; i < 10; i++) { scanf_s("%c", &element); push(&head, element); } printf("Given linked list\n"); printList(head); struct Node *copy = copy_reverse(head); printf("\nReversed Linked list \n"); printList(copy); freeList(head); freeList(copy); getchar(); }Ya casi estás ahí. Todo lo que necesita es un ajuste. A reverse , debe crear una nueva copia del nodo current y usarla en su lugar. Además, dado que terminará con una segunda lista y no alterará la original, debe devolver la nueva lista desde reverse .
static struct Node* reverse(const struct Node* head_ref) { struct Node* previous = NULL; const struct Node* current = head_ref; struct Node* copy; while (current != NULL) { copy = malloc(sizeof(*copy)); if (copy == NULL) { // handle error } copy->data = current->data; copy->next = previous; previous = copy; current = current->next; } return previous; } También puede hacer que el bucle sea más bonito convirtiéndolo en un bucle for .
for (current = head_ref; current != NULL; current = current->next) { Finalmente, cuando imprime la lista, está usando %d en la cadena de formato printf . %d imprimirá el char como un número entero. Para imprimir el carácter real, use %c en su lugar.