elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Eliminar datos de lista enlazada
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Eliminar datos de lista enlazada  (Leído 16,714 veces)
erickgracia

Desconectado Desconectado

Mensajes: 17


Ver Perfil
Eliminar datos de lista enlazada
« en: 15 Abril 2014, 00:19 am »

Hola, soy nuevo en este foro , tengo un problema al intentar hacer un codigo que borre los datos de una lista enlazada:

lo que intente fue que al declarar apuntadores de los nodos llamados anterior, actual y siguiente, dados que apuntaran a 3 nodos diferentes de la lista mientras se va recorriendo dentro del    "while(recorre != NULL){}"   y que si encontraba el valor de llave , el apuntador del nodo anterior , apunte a "siguiente" , y y "eliminar" el nodo "actual" mediante el comando free();


El problema es que al ejecutar el programa entero y entra en la funcion de eliminarLista();  se detiene el programa despues de pedir el valor del entero a eliminar (o tal vez esta teniendo un loop el ciclo, la verdad no estoy seguro) estaria muy agradecido si me ayudaran con este problema, ya que es una base para un trabajo de la universidad del cual me basarè.


he aqui el codigo, o por lo menos la parte que de eliminar datos, tambien pongo la estructura con la que anda trabajando el codigo.

Código:

typedef struct nodo{
int llave;
struct nodo * sig; /* auto referencia */
}nodoLista;



void eliminarLista(){
nodoLista* anterior;
nodoLista* actual;
nodoLista* siguiente;
nodoLista* recorre=primero;

int op;
printf("Cual es el entero a eliminar?");
scanf("%d", &op);

anterior=primero;
actual=primero;
siguiente=primero->sig;

while(recorre != NULL){

if(recorre->llave == op){
anterior->sig=siguiente;
free(actual);
}
else{}
anterior=recorre;
recorre = recorre->sig;
actual=recorre;
if(recorre != NULL){siguiente = recorre->sig;}
}
}












y por si acaso, aqui va el codigo entero(tomen en cuenta que es un archivo sencillo para practicar  ;D ) :

Código:
#include <stdio.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE 1

typedef int boolean;

boolean estaVacia();

typedef struct nodo{
int llave;
struct nodo * sig; /* auto referencia */
}nodoLista;

nodoLista * primero = NULL;
nodoLista * ultimo = NULL;

void insertarInicio();
void insertarFinal();
void mostrarLista();
void eliminarLista();

int main(void) {
setvbuf(stdout, NULL, _IONBF, 0);
int opcion;
do{
printf("\n\nMENU");
printf("\n0.- Salir");
printf("\n1.- Agregar un nodo al inicio");
printf("\n2.- Mostrar los valores de la lista");
printf("\n3.- Agregar un nodo al final");
printf("\n4.- Eliminar un elemento");

printf("\n\nDame tu opci�n");
scanf("%d", &opcion);

switch(opcion){
case 0:
break;
case 1:
insertarInicio();
break;
case 2:
mostrarLista();
break;
case 3:
insertarFinal();
break;
case 4:
eliminarLista();
break;
}

} while (opcion != 0);


return EXIT_SUCCESS;
}

void insertarInicio(){
nodoLista * nuevo;
nuevo = (nodoLista *)malloc(sizeof(nodoLista));

printf("\n\nDame el valor de la llave");
scanf("%d", &nuevo->llave);
nuevo->sig = primero;
primero = nuevo;

if(primero->sig == NULL)
ultimo = primero;
}

void insertarFinal(){
if (estaVacia()){
insertarInicio();
return;
}

nodoLista * nuevo;
nuevo = (nodoLista *)malloc(sizeof(nodoLista));

printf("\n\nDame el valor de la llave");
scanf("%d", &nuevo->llave);
nuevo->sig = NULL;
ultimo->sig = nuevo;
ultimo = nuevo;
}

void mostrarLista(){
if (estaVacia()){
printf("\n\nLa lista est� vac�a");
return;
}
nodoLista * recorre = primero;
while (recorre != NULL){
printf("%d  ", recorre->llave);
recorre = recorre->sig;
}
}

void eliminarLista(){
nodoLista* anterior;
nodoLista* actual;
nodoLista* siguiente;
nodoLista* recorre=primero;

int op;
printf("Cual es el entero a eliminar?");
scanf("%d", &op);

anterior=primero;
actual=primero;
siguiente=primero->sig;

while(recorre != NULL){

if(recorre->llave == op){
anterior->sig=siguiente;
free(actual);
}
else{}
anterior=recorre;
recorre = recorre->sig;
actual=recorre;
if(recorre != NULL){siguiente = recorre->sig;}
}
}

boolean estaVacia(){
if (primero == NULL)
return TRUE;
else
return FALSE;
}


En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Eliminar datos de lista enlazada
« Respuesta #1 en: 15 Abril 2014, 09:55 am »


El problema es que al ejecutar el programa entero y entra en la funcion de eliminarLista();  se detiene el programa despues de pedir el valor del entero a eliminar (o tal vez esta teniendo un loop el ciclo, la verdad no estoy seguro)

Saber lo que está pasando es tan sencillo como usar un depurador... que no te den miedo... te vas a hartar a usarlos si en algún momento te vas a dedicar a programar. Es una buena idea familiarizarse con su uso.

Para eliminar un elemento de una lista enlazada únicamente necesitas dos punteros... "anterior" y "actual":

En tu caso, el problema es que al eliminar un nodo cualquiera desplazas "anterior". Si tu eliminas un nodo no puedes actualizar "anterior". Puedes comprobarlo si dibujas el proceso sobre un papel.

Código
  1. void eliminarLista()
  2. {
  3.  nodoLista* anterior = NULL;
  4.  nodoLista* actual = primero;
  5.  
  6.  int op;
  7.  printf("Cual es el entero a eliminar?");
  8.  scanf("%d", &op );
  9.  
  10.  while( actual != NULL )
  11.  {
  12.    if( actual->llave == op )
  13.    {
  14.      // Si eliminamos el primer elemento de la lista hay que operar de forma diferente
  15.      if ( anterior == NULL )
  16.        primero = actual->sig;
  17.      else
  18.        anterior->sig = actual->sig;
  19.  
  20.      free( actual );
  21.      actual = anterior->sig;
  22.      break; // Este break solo tiene sentido si la lista no admite duplicados
  23.    }
  24.    else
  25.    {
  26.      anterior = actual;
  27.      actual = actual->sig;
  28.    }
  29.  }
  30. }

En tu caso, "actual" y "recorre" apuntan al mismo sitio... no tiene sentido porque te obliga a tener sincronizados dos punteros sin ninguna necesidad.

Además:

Código
  1. if ( recorre != NULL){siguiente = recorre->sig;

esto para que?? la siguiente línea que se ejecuta es la condición del while, que dice que si recorre es NULL sales del while.

Además, no entiendo por qué razón guardas el puntero "ultimo". En una lista enlazada, el "sig" del último elemento apunta a NULL, luego saber si has llegado al final de la lista es tan sencillo como comprobar el "sig" de cada elemento.

También, mi consejo, es que tiendas a reutilizar código... no tiene sentido que tengas dos funciones para añadir elementos a la lista ( una para añadir al principio y otra para añadir al final ). Tiene más sentido que haya una función única y que sea ésta la que sepa añadir un elemento en cualquier posición... así cuando uses tu librería no tendrás que preocuparte por la posición concreta del elemento a insertar.

También te recomiendo no usar variables globales. Es mejor pasar estas variables como argumentos de las funciones.

Un saludo.


En línea

nolasco281


Desconectado Desconectado

Mensajes: 319


Ver Perfil
Re: Eliminar datos de lista enlazada
« Respuesta #2 en: 15 Abril 2014, 16:50 pm »

Hola

veo que mencionas depuradores quisiera saber a que se refiere y si me puedes dar algun ejemplo, ya que tambien lo he leido en otras partes pero pensaba que esto lo realizaba el IDE al momenton de compilar el programa.

Encuanto al programa

realize las modificaciones que apunta eferion y el tiempo de ejecucion se redujo notablemente
por lo menos en mi caso de 3.61 a el rango de 0.50

ha gracias por la explicacion la entendi muy bien : ).

aca la prueba


Saludos y gracias.
« Última modificación: 15 Abril 2014, 17:11 pm por nolasco281 » En línea

Lo que se puede imaginar... se puede programar.
eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Eliminar datos de lista enlazada
« Respuesta #3 en: 15 Abril 2014, 17:02 pm »

Hola

veo que mencionas depuradores quisiera saber a que se refiere y si me puedes dar algun ejemplo, ya que tambien lo he leido en otras partes pero pensaba que esto lo realizaba el IDE al mometon de compilar el programa.

Saludos.

Un depurador es un programa que, dado un programa compilado en modo debug y su correspondiente código fuente es capaz de presentar al usuario una interfaz que le permite seguir la traza de ejecución del código.

Los IDEs no son más que "fachadas" con un catálogo de utilidades que facilita el proceso de programación... pero lo dicho, no son más que fachadas. Al igual que un IDE se vale de un compilador independiente para compilar los programas, para depurar se vale de un depurador.

¿Se puede depurar una aplicación que no está compilada en modo debug? SI, solo que debido a las optimizaciones que hace el compilador y a la inexistencia de información de depuración, tienes que bajar forzosamente a nivel ensamblador... esto se usa, por ejemplo, en ingeniería inversa.

Depuradores los hay a patadas... cada uno con sus características y sus limitaciones. Puedes encontrar mucha información al respecto navegando por internet.

En línea

nolasco281


Desconectado Desconectado

Mensajes: 319


Ver Perfil
Re: Eliminar datos de lista enlazada
« Respuesta #4 en: 15 Abril 2014, 17:17 pm »

Gracias se entendio perfectamente.

Puedes encontrar mucha información al respecto navegando por internet.

solo que no sabia pensaba, que la depuracion se realizaba en la compilacion por eso no me habia dado a la tarea de investigar.

pero muchas gracias por la aclaracion.

Saludos y muchas gracias.
En línea

Lo que se puede imaginar... se puede programar.
Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.969


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: Eliminar datos de lista enlazada
« Respuesta #5 en: 15 Abril 2014, 17:32 pm »

Los depuradores trabajan con o sin el codigo fuente, obviamente es mucho mas comodo hacerlo con el codigo y si generas la informacion de depuracion, como los simbolos PDB de Microsoft, tambien podes depurar con codigo en modo release. Igual tarde o temprano vas a terminar depurando en ensamblador si te dedicas a esto profesionalmente ...
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
erickgracia

Desconectado Desconectado

Mensajes: 17


Ver Perfil
Re: Eliminar datos de lista enlazada
« Respuesta #6 en: 16 Abril 2014, 00:04 am »

Saber lo que está pasando es tan sencillo como usar un depurador... que no te den miedo... te vas a hartar a usarlos si en algún momento te vas a dedicar a programar. Es una buena idea familiarizarse con su uso.

Para eliminar un elemento de una lista enlazada únicamente necesitas dos punteros... "anterior" y "actual":

En tu caso, el problema es que al eliminar un nodo cualquiera desplazas "anterior". Si tu eliminas un nodo no puedes actualizar "anterior". Puedes comprobarlo si dibujas el proceso sobre un papel.

Código
  1. void eliminarLista()
  2. {
  3.  nodoLista* anterior = NULL;
  4.  nodoLista* actual = primero;
  5.  
  6.  int op;
  7.  printf("Cual es el entero a eliminar?");
  8.  scanf("%d", &op );
  9.  
  10.  while( actual != NULL )
  11.  {
  12.    if( actual->llave == op )
  13.    {
  14.      // Si eliminamos el primer elemento de la lista hay que operar de forma diferente
  15.      if ( anterior == NULL )
  16.        primero = actual->sig;
  17.      else
  18.        anterior->sig = actual->sig;
  19.  
  20.      free( actual );
  21.      actual = anterior->sig;
  22.      break; // Este break solo tiene sentido si la lista no admite duplicados
  23.    }
  24.    else
  25.    {
  26.      anterior = actual;
  27.      actual = actual->sig;
  28.    }
  29.  }
  30. }

En tu caso, "actual" y "recorre" apuntan al mismo sitio... no tiene sentido porque te obliga a tener sincronizados dos punteros sin ninguna necesidad.

Además:

Código
  1. if ( recorre != NULL){siguiente = recorre->sig;

esto para que?? la siguiente línea que se ejecuta es la condición del while, que dice que si recorre es NULL sales del while.

Además, no entiendo por qué razón guardas el puntero "ultimo". En una lista enlazada, el "sig" del último elemento apunta a NULL, luego saber si has llegado al final de la lista es tan sencillo como comprobar el "sig" de cada elemento.

También, mi consejo, es que tiendas a reutilizar código... no tiene sentido que tengas dos funciones para añadir elementos a la lista ( una para añadir al principio y otra para añadir al final ). Tiene más sentido que haya una función única y que sea ésta la que sepa añadir un elemento en cualquier posición... así cuando uses tu librería no tendrás que preocuparte por la posición concreta del elemento a insertar.

También te recomiendo no usar variables globales. Es mejor pasar estas variables como argumentos de las funciones.

Un saludo.





Gracias por la respuesta, muy completa y me funcionò, gracias ademàs por los consejos intentarè aplicarlos lo mas que pueda, tomando que soy algo nuevo en esto de la programaciòn me viene util cada cosa comentada por aqui :)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
insertar datos nom apell rut en lista enlazada
Java
Futuro_Ingeniero 0 2,500 Último mensaje 15 Abril 2013, 23:57 pm
por Futuro_Ingeniero
Estructura de datos : Pila con lista enlazada en Java
Java
CarlosvAlencia 4 3,695 Último mensaje 6 Abril 2014, 16:29 pm
por CarlosvAlencia
guardar datos Lista enlazada
Programación C/C++
erickgracia 1 3,856 Último mensaje 17 Abril 2014, 14:30 pm
por ivancea96
[Solucionado]Lista enlazada guardar y cargar datos
Programación C/C++
erickgracia 2 11,942 Último mensaje 7 Mayo 2014, 18:34 pm
por erickgracia
Eliminar ultimo elemento de la lista enlazada C++
Programación C/C++
nurnain 2 6,134 Último mensaje 21 Marzo 2020, 01:48 am
por dijsktra
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines