brian69 Posted July 9, 2014 Report Share Posted July 9, 2014 (edited) Hola gente recurro a uds porque tengo la siguiente duda, estoy escribiendo en C un programa para crear lista enlazada, ingresar nodos en base a lo que uno decida, mostrar los nodos, eliminar alguno a eleccion y salir. Codigo: #include <stdio.h> #include <stdlib.h> #include <lista.h> ingresa_nodo (Lista *p) { int cant, num, i; printf("Cuantos nodos quiere ingresar?\n"); scanf("%d", &cant); for (i=1; i<=cant; ++i) { printf ("Ingrese nodos: \n"); scanf("%d",&num); p=insertar_nodo_lista(p, num); } return (p); } void mostrar_lista (Lista *p) { while (p !=NULL) { printf ("%d",p->info); p = p->prox; } } int main(int argc, char *argv[]) { int op; Lista *pl; pl=NULL; while(op!=4) { printf("\n\n_____________________________\n\n"); printf("1.- Ingresar Nodos\n"); printf("2.- Visualizar Contenido Lista\n"); printf("3.- Eliminar Nodo\n"); printf("4.- Salir\n"); printf("_____________________________\n"); printf("Elegir Opcion: "); scanf("%d", &op); switch(op) { case 1: { pl=ingresa_nodo (pl); break; } case 2: { mostrar_lista (pl); break; } case 3: { break; } case 4: break; } } return 0; } Consejos del codigo, ojala para eliminar nodo a eleccion, osea para poder hacer uso del auxiliar y cambiar los punteros. Codigo Fuente: #include <stdio.h> #include <stdlib.h> //--------------------- Lista enlazada simple -------------------------- struct nodo_lista { int info; struct nodo_lista *prox; }; #define lista struct nodo_lista #define Lista struct nodo_lista lista *insertar_nodo_lista (lista *p, int dato) { lista *paux; // Inicio: paux = NULL; paux = (lista *) malloc (sizeof (lista)); if (paux!=NULL) { paux->info = dato; paux->prox = NULL; if (p == NULL) p = paux; else { paux->prox = p; p = paux; } paux = NULL; } else printf ("No hay memoria...\n\n"); return (p); } // Elimina complemente una lista enlazada lista *eliminar_lista (lista *p) { lista *paux; // Inicio: while (p != NULL) { paux = p; p = p->prox; free (paux); } paux= NULL; return (p); } // Muestra el contenido de una lista enlazada void listar_lista (lista *p) { // Inicio: printf ("\n"); while (p != NULL) { printf ("%d, ",p->info); p = p->prox; } printf ("\n"); } // ------------Fin de lista enlazada -----------------------------------------// // ------------ Lista Circular ----------------------------------------------// lista *insertar_nodo_circular (lista *pc, int dato) { lista *paux; // inicio: paux = NULL; paux = (lista *) malloc (sizeof (lista)); if (paux!=NULL) { paux->info = dato; paux->prox = paux; if (pc == NULL) pc = paux; else { // insertar: paux->prox = pc->prox; pc->prox = paux; } paux = NULL; } else printf ("No hay memoria...\n\n"); return (pc); } lista *eliminar_circular (lista *p) { lista *paux; // Inicio: if (p != NULL) { paux = p; p = p->prox; paux->prox = NULL; p = eliminar_lista (p); } return (p); } // ------------Fin de lista circular -----------------------------------------// De antemano gracias por leer. PD: Algunas funciones estan integradas en el include lista.h si es necesario puedo subirlo. Edited July 10, 2014 by brian69 Link to comment Share on other sites More sharing options...
susodicho Posted July 10, 2014 Report Share Posted July 10, 2014 (edited) :mmm: Hay varios problemas:No subiste el código fuente de lista.h :huasonto: ...y soy terriblemente malo para adivinarLas funciones que no devuelven ningún valor tienes que declararlas como void. En C, si no especificas un tipo de dato para un identificador, se asume que éste es int, o sea, implícitamente se declara como int. Así que deberías arreglar las funciones ingresa_nodo y mostrar_lista (así como están actualmente, están devolviendo un entero)La función ingresa_nodo está mal implementada. Estás ingresando nodos dentro de la función, pero al salir de ésta, todo queda igual (la lista queda igual como estaba antes de entrar a la función) . Tienes que hacer que la función devuelva la nueva lista (un puntero al comienzo de ésta) ;), o sea, sería la misma idea de la función insertar_nodo_lista (suponiendo que esté bien implementada... )Se supone que la lista se inicializa en NULL (indicando que está vacía) al comienzo del programa, tú la inicializas en NULL cada vez que entras a la función ingresa_nodo, pero esto ni siquiera importa porque, como dije antes, esta función deja la lista tal cual como estaba antes de entrar a la función.Como la variable pl que está en el main no está inicializada, contiene basura, o sea, apunta a cualquier parte, por eso te ocurre un error (estás tratando de acceder a una dirección de memoria a la que el programa no tiene permiso para acceder)Como no subiste el codigo fuente de lista.h, no puedo estar seguro si la definición del tipo Lista es correcta y, como dije antes, soy malazo para adivinar Sobre el tercer punto, la función ingresa_nodo no altera la lista porque los parámetros de funciones se comportan igual que variables locales, así que da lo mismo qué le asignes al parámetro p dentro de la función porque es una variable local. Por ejemplo, podrías agregar una función que supuestamente asignaría NULL a una lista y, por lo tanto, la destruiría (haría que todos los nodos que tenga quedaran inaccesibles), la función sería así: void anular(Lista *p) { p = NULL; }como dije, esto no funciona. La lista quedaría tal cual porque el parámetro p tiene validez dentro de la función. Por esta misma razón, en la función mostrar_lista no necesitas usar una variable auxiliar para recorrer la lista :huasonto: (haz la prueba ;) ) Edited July 10, 2014 by susodicho 1 Link to comment Share on other sites More sharing options...
brian69 Posted July 10, 2014 Author Report Share Posted July 10, 2014 :mmm: Hay varios problemas:No subiste el código fuente de lista.h :huasonto: ...y soy terriblemente malo para adivinarLas funciones que no devuelven ningún valor tienes que declararlas como void. En C, si no especificas un tipo de dato para un identificador, se asume que éste es int, o sea, implícitamente se declara como int. Así que deberías arreglar las funciones ingresa_nodo y mostrar_lista (así como están actualmente, están devolviendo un entero)La función ingresa_nodo está mal implementada. Estás ingresando nodos dentro de la función, pero al salir de ésta, todo queda igual (la lista queda igual como estaba antes de entrar a la función) . Tienes que hacer que la función devuelva la nueva lista (un puntero al comienzo de ésta) ;), o sea, sería la misma idea de la función insertar_nodo_lista (suponiendo que esté bien implementada... )Se supone que la lista se inicializa en NULL (indicando que está vacía) al comienzo del programa, tú la inicializas en NULL cada vez que entras a la función ingresa_nodo, pero esto ni siquiera importa porque, como dije antes, esta función deja la lista tal cual como estaba antes de entrar a la función.Como la variable pl que está en el main no está inicializada, contiene basura, o sea, apunta a cualquier parte, por eso te ocurre un error (estás tratando de acceder a una dirección de memoria a la que el programa no tiene permiso para acceder)Como no subiste el codigo fuente de lista.h, no puedo estar seguro si la definición del tipo Lista es correcta y, como dije antes, soy malazo para adivinar Sobre el tercer punto, la función ingresa_nodo no altera la lista porque los parámetros de funciones se comportan igual que variables locales, así que da lo mismo qué le asignes al parámetro p dentro de la función porque es una variable local. Por ejemplo, podrías agregar una función que supuestamente asignaría NULL a una lista y, por lo tanto, la destruiría (haría que todos los nodos que tenga quedaran inaccesibles), la función sería así: void anular(Lista *p) { p = NULL; }como dije, esto no funciona. La lista quedaría tal cual porque el parámetro p tiene validez dentro de la función. Por esta misma razón, en la función mostrar_lista no necesitas usar una variable auxiliar para recorrer la lista :huasonto: (haz la prueba ;) ) Gracias compa, de hecho durante la tarde corregi varios errores los cuales mencionas, anoche empeze a escribirlo tipo 23hrs asi qe tampoco tava muy "concentrado" xd Dejare el codigo como esta ahora y agregare el codigo fuente. Me podrias ayudar con un modulo para eliminar a eleccion? en estos momento yo ingreso la cantidad de nodos, elijo 3 a ingresar, luego me muestra los nodos en este orden : "321" y por ejemplo quiero eliminar el 2, ahi creo necesario tirar un auxiliar y cambiar donde apunta. Gracias por pasar, leer y aportar Link to comment Share on other sites More sharing options...
susodicho Posted July 10, 2014 Report Share Posted July 10, 2014 (edited) No arreglaste bien la función ingresa_nodo... :huasonto: :mmm: Para eliminar un nodo, tienes que saber cuál es el nodo anterior al que vas a eliminar, para enlazarlo con el que viene después. Por ejemplo, si tienes esta lista:A -> B -> C -> D -> E -> F -> G -> H -> I -> Jy quieres eliminar el nodo G, entonces tienes que enlazar el nodo F con el nodo H, una vez enlazados puedes eliminar el nodo G. Creo que la función eliminar_nodo sería más o menos así (pseudocódigo):Lista *eliminar_nodo(Lista *p, cual) anterior = NULL inicio = p while (p <> NULL) and (no es el nodo que ando buscando) anterior = p avanzar(p) if p = NULL then // ERROR: ese nodo no existe elseif anterior = NULL then // hacer que 'inicio' apunte al nodo que viene después de 'p' // borrar 'p' else // enlazar nodo 'anterior' con el que viene después de 'p' // borrar 'p' return inicio endOjalá que se entienda. Ten cuidado de no confundir las comparaciones y asignaciones en el pseudocódigo y en el lenguaje C ;)Al salir del while hay que verificar lo siguiente:si se encontró el nodo que se quiere eliminarsi se va a eliminar el primer nodosi no se encontró el nodo que se quiere eliminar entonces p será NULL (se recorrió la lista completa o estaba vacía); si anterior es NULL significa que no se entró al ciclo while y, por lo tanto, se va a eliminar el primer nodo; en caso contrario se va a eliminar algún otro nodo (del segundo en adelante). Ojo, el hecho que no se encuentre el nodo que se quiere eliminar, no significa haya que tirar error o hacer algo, quizás no haya que hacer nada; eso queda a criterio tuyo (si no hay que hacer nada, tendrías que reestructurar los if...tú sabrás cómo ;) ) Por último, parece que no es necesario usar una variable auxiliar a la hora de borrar el nodo. Edited July 12, 2014 by susodicho Link to comment Share on other sites More sharing options...
shagof Posted July 16, 2014 Report Share Posted July 16, 2014 les dejo mi biblioteca personal de listas enlazadas simples xD #ifndef LISTA_H_INCLUDED #define LISTA_H_INCLUDED #include <stdio.h> #include <stdlib.h> /* Definicion de la lista. */ struct nodo{ int n; struct nodo *sgte; }; /* Prototipos */ struct nodo* crear(struct nodo* l) void printLista(struct nodo *inicio); int length(struct nodo *inicio); struct nodo* insertarOrdenAscendente(struct nodo *inicio, int val); struct nodo* insertarInicio(struct nodo *inicio, int val); struct nodo* insertarFinal(struct nodo *inicio, int val); struct nodo *buscarValor(struct nodo *inicio, int val); struct nodo *delete(struct nodo *inicio, int val); /* Crea una lista vacia */ struct nodo* crear(struct nodo* l){ return l = NULL; } /* Imprime una lista desde el primer elemento */ void printLista(struct nodo *inicio){ struct nodo *p; printf("Lista: "); p = inicio; while (p!=NULL){ printf("%d ", p->n); p = p->sgte; } printf("\n"); } int length(struct nodo *inicio){ struct nodo *p; int len; len = 0; p = inicio; while (p!=NULL){ len++; p = p->sgte; } return len; } /* inserta un nuevo nodo manteniendo la lista ordenada de forma ascendente */ struct nodo* insertarOrdenAscendente(struct nodo *inicio, int val){ struct nodo *p, *new; new = (struct nodo*)malloc(sizeof(struct nodo)); new->n = val; /* Lista vacia */ if (inicio==NULL){ inicio = new; inicio->sgte = NULL; } /* Lista con elementos */ else{ /* Caso especial (se debe insertar como primer elemento) */ if (val < inicio->n){ new->sgte = inicio; inicio = new; } /* Caso general */ else{ p = inicio; while (p->sgte!=NULL && (p->sgte)->n < val) p = p->sgte; new->sgte = p->sgte; p->sgte = new; } } return inicio; } /* inserta un nuevo nodo al inicio de la lista, desplazando el resto de los nodos */ struct nodo* insertarInicio(struct nodo *inicio, int val){ struct nodo *new; new = (struct nodo*)malloc(sizeof(struct nodo)); new->n = val; new->sgte = inicio; return new; } /* inserta un nuevo nodo al final de la lista */ struct nodo* insertarFinal(struct nodo *inicio, int val){ struct nodo *p, *new; new = (struct nodo*)malloc(sizeof(struct nodo)); new->n = val; new->sgte = NULL; /* Lista vacia */ if(inicio == NULL){ inicio = new; } else{ p = inicio; while (p->sgte != NULL) p = p->sgte; p->sgte = new; } return inicio; } /* busca un valor en una lista, retorna el puntero al primer nodo que contenga dicho valor */ struct nodo *buscarValor(struct nodo *inicio, int val){ struct nodo *p; p = inicio; while (p!=NULL && p->n!=val) p = p->sgte; return p; } /* borra un nodo de la lista liberando la memoria usada por este */ struct nodo *delete(struct nodo *inicio, int val){ struct nodo *p, *aux; if(inicio != NULL){ /* Caso especial (se debe borrar el primer nodo) */ if (inicio->n == val){ aux = inicio; inicio = aux->sgte; free(aux); } else{ /* Se busca el nodo a borrar */ p = inicio; while (p->sgte!=NULL && (p->sgte)->n!=val) p = p->sgte; /* se borra en nodo */ if (p->sgte != NULL){ aux = p->sgte; p->sgte = aux->sgte; free(aux); } } } return inicio; } #endif // LISTA_H_INCLUDED Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now