Hola! Hice un codigo de insertar elementos ordenados en una lista enlazada, me funciono perfectamente solo que repetia la asignacion de la variable que iba a ingresar a la lista, asi:
num = 1;
agregar_lista (num);
num = 2; ,
agregar_lista (num); ... etc
ahora quise hacerlo con while, deje todo como estaba solamente modifique ese procedimiento, pero no se por que no funciona, no lee lo que hay dentro del while como tampoco lo que hay fuera, incluso intente mostrar en pantalla mensajes al iniciar el programa y tampoco sirve, a que se debe? Antes funcionaba sin ningun problema :(
#include <stdio.h>
#include <stdlib.h>
typedef struct rNodo {
int dato;
struct rNodo * siguiente;
}tNodo;
typedef struct rLista {
tNodo * primero;
tNodo * ultimo;
int longitud;
}tLista;
typedef tNodo * Nodo;
typedef tLista * Lista;
tLista * inicializar (Lista lista);
tNodo * crear_nodo (int nuevo_dato);
tLista * ins_de_orden_ascen (Lista lista, Nodo nuevo_nodo);
int main(void)
{
Lista lista = inicializar(lista);
int nuevo_dato;
int finalizar = 1;
do {
printf("ingrese un numero:");
scanf("%i", &nuevo_dato);
lista = ins_de_orden_ascen(lista, crear_nodo(nuevo_dato));
printf("Quiere ingresar otro numero? 1(si) o 0(no):");
scanf("%i", &finalizar);
} while (finalizar == 1);
return 0;
}
tLista * inicializar (Lista lista) {
Lista nueva_lista = (tLista*) malloc (sizeof (tLista));
nueva_lista->primero = NULL;
nueva_lista->ultimo = NULL;
nueva_lista->longitud = 0;
return nueva_lista;
}
tNodo * crear_nodo (int nuevo_dato) {
Nodo nuevo_elemento = (tNodo*) malloc (sizeof (tNodo));
nuevo_elemento->dato = nuevo_dato;
nuevo_elemento->siguiente = NULL;
return nuevo_elemento;
}
tLista * ins_de_orden_ascen (Lista lista, Nodo nuevo_nodo) {
if (lista->longitud == 0) { // Si la lista es vacia
nuevo_nodo->siguiente = lista->primero;
lista->primero = nuevo_nodo;
lista->ultimo = nuevo_nodo;
} else {
Nodo aux = lista->primero; // aux apunta al primer elemento
Nodo sig;
int encontro = 0;
while (encontro == 0) {
sig = aux->siguiente; // sig apunta al siguiente elemento de aux
if (aux->dato > nuevo_nodo->dato) { // Si el nuevo elemento es menor al elemento actual
nuevo_nodo->siguiente = aux;
lista->primero = nuevo_nodo;
encontro = 1;
} else
if ((aux->dato < nuevo_nodo->dato) && (sig == NULL)) { // Si el nuevo elemento es mayor al ultimo de la lista
nuevo_nodo->siguiente = aux->siguiente;
aux->siguiente = nuevo_nodo;
lista->ultimo = nuevo_nodo;
encontro = 1;
} else
if ((aux->dato < nuevo_nodo->dato) && (sig->dato > nuevo_nodo->dato)) { // Si se encuentra en el medio de la lista
nuevo_nodo->siguiente = aux->siguiente;
aux->siguiente = nuevo_nodo;
encontro = 1;
} else
aux = aux->siguiente;
}
}
lista->longitud++; // Aumenta la cantidad de elementos
return lista;
}
Me he tomado la libertad de modificar tu código y añadir unas cuantas cosas. De igual forma he comentado cambios y añadidos.
Espero que te sirva.
#include <stdio.h>
#include <stdlib.h>
typedef struct rNodo {
int dato;
struct rNodo * siguiente;
} tNodo;
typedef struct rLista {
tNodo * primero;
tNodo * ultimo;
int longitud;
} tLista;
typedef tNodo * Nodo;
typedef tLista * Lista;
tLista* inicializar();
tNodo* crear_nodo(int nuevo_dato);
void ins_de_orden_ascen(Lista lista, Nodo nuevo_nodo);
void mostrar(Lista lista);
void liberar(Lista lista);
int main(void) {
Lista lista = inicializar();
int nuevo_dato;
int continuar; // cambio el nombre de variable para hacerlo más coherente. No lo inicializo ya que en el bucle se debe hacer obligatoriamente.
do {
printf("ingrese un numero: ");
scanf("%i", &nuevo_dato);
ins_de_orden_ascen(lista, crear_nodo(nuevo_dato));
printf("Quiere ingresar otro numero? 1(si) o 0(no): ");
scanf("%i", &continuar);
} while (continuar);
mostrar(lista);
liberar(lista);
return 0;
}
tLista* inicializar() { // no tiene razón la existencia de un argumento, no se usaba
Lista nueva_lista = malloc(sizeof (tLista));
nueva_lista->primero = NULL;
nueva_lista->ultimo = NULL;
nueva_lista->longitud = 0;
return nueva_lista;
}
tNodo* crear_nodo(int nuevo_dato) {
Nodo nuevo_elemento = malloc(sizeof (tNodo));
nuevo_elemento->dato = nuevo_dato;
nuevo_elemento->siguiente = NULL;
return nuevo_elemento;
}
void ins_de_orden_ascen(Lista lista, Nodo nuevo_nodo) { // no tiene razón que se devuelva la lista, no se modifica su puntero
if (lista->longitud == 0) { // Si la lista es vacia
nuevo_nodo->siguiente = lista->primero;
lista->primero = nuevo_nodo;
lista->ultimo = nuevo_nodo;
} else {
Nodo aux = lista->primero; // aux apunta al primer elemento
Nodo ant = NULL;
while(aux && aux->dato < nuevo_nodo->dato) { // busco el nodo con un dato mayor al nuevo dato, también puede llegar al fin de la lista
ant = aux; // y me quedo con el nodo anterior
aux = aux->siguiente;
}
if(ant) { // si el nodo anterior existe
ant->siguiente = nuevo_nodo; // hago que su siguiente apunte al nuevo nodo
if(lista->ultimo == ant) { // si el nodo anterior era el último de la lista
lista->ultimo = nuevo_nodo; // ahora debe serlo el nuevo nodo
}
} else {
lista->primero = nuevo_nodo; // en caso contrario quiere decir que el nuevo nodo debe ser el primero
}
nuevo_nodo->siguiente = aux; // el siguiente del nodo nuevo debe ser el nodo que debía ser el siguiente, o NULL si había llegado al final de la lista
}
lista->longitud++; // Aumenta la cantidad de elementos
}
void mostrar(Lista lista) { // pinta la lista en pantalla
puts("--- Lista ---");
if(!lista) { // No existe lista
printf("Lista no inicializada");
return;
}
if(lista->longitud == 0) { // Lista vacía
printf("Lista vacía");
return;
}
for(Nodo n = lista->primero; n; n = n->siguiente) { // Muestra todos los nodos
printf("%d\n", n->dato);
}
}
void liberar(Lista lista) { // Desaloja la lista de la memoria
Nodo sig;
if(!lista) { // Si no existe lista no hay que liberar nada
return;
}
while(lista->primero) {
sig = lista->primero->siguiente;
free(lista->primero);
lista->primero = sig;
// lista->longitud--; // No hace falta esta línea ya que la lista se va a desalojar de la memoria
}
free(lista);
}
Cita de: MAFUS en 12 Agosto 2021, 02:00 AM
Me he tomado la libertad de modificar tu código y añadir unas cuantas cosas. De igual forma he comentado cambios y añadidos.
Espero que te sirva.
Me ha ayudado un monton los cambios, muchisimas gracias por el tiempo que te tomaste! ;D ;D ;D ;D