Seguimos buscando a Arshak. Ayudanos compartiendo!
Encuesta no oficial de docentes
Resultados de la encuesta no oficial de docentes
Probaste el SIGA Helper?

Donar $100 Donar $200 Donar $500 Donar mensualmente


Enviar respuesta 
 
Calificación:
  • 0 votos - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Buscar en el tema
[Ayuda] Ejercicio integrador [Info I]
Autor Mensaje
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #1
Question [Ayuda] Ejercicio integrador [Info I] Dudas y recomendaciones Informática I (Electrónica)
Hola gente,

Necesito de algún alma caritativa que me ayude a resolver un problemita del siguiente programa. El error (me tira fallo de segmentación) está en las últimas líneas dentro de la función RecuperarLista ( struct nodo** Cabeza). Lo que hace (o debería hacer) esta función es recuperar la lista de datos al abrir el programa. Es decir, abro el programa por primera vez e ingreso una serie de datos que forman una lista. Guardo esa lista en un archivo. Luego cierro el programa. Al abrirlo la función se encarga de abrir dicho archivo y recuperar la lista. Fijense que si ponen la línea 38 como lectura el programa funciona a la perfección. Muchas gracias de antemano.

Lista doblemente enlazada + manejo de archivo.

Saludos!
Otros adjuntos en este tema
.pdf  enunciados_de_finales.pdf ( 45,27 KB / 19) por matyary
.doc  Final 2-12-10.doc ( 23 KB / 8) por matyary
.jpg  Practica17-12.jpg ( 152,21 KB / 886) por matyary
.jpg  Teoria17-12.jpg ( 119,96 KB / 878) por matyary

\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
20-03-2012 12:08
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #2
RE: [Ayuda] Ejercicio integrador [Info I]

//Preparación para final de Informática I.
//Lista Doblemente Enlazada.

//Librerías.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NOMBRE 10

//Estructura.
struct nodo {
char nombre[NOMBRE];
int inventario;
int stock;
struct nodo *Siguiente;
struct nodo *Anterior;
};

//Prototipos de las Funciones.
void ImprimirLista ( struct nodo * );
struct nodo * BuscarNodo ( struct nodo * );
void ModificarNodo ( struct nodo * );
void InsertarNodoEsp ( struct nodo * );
void InsertarNodoIzq ( struct nodo ** );
void BorrarNodo ( struct nodo ** );
void Menu ( );
struct nodo * CrearNodo ( );
void GuardarLista ( struct nodo * );
struct nodo * RecuperarLista ( struct nodo ** );

//Main.
int main ( void )
{
int opcion;
struct nodo *Cabeza=NULL; //Inicialmente la lista se encuentra vacia.

Cabeza = RecuperarLista ( &Cabeza ); //Si esta línea va como lectura el
//programa funciona correctamente,
//omitiendo la función que recupera
//la lista
Menu ( );

do
{
printf("\nOpción: ");scanf("%d",&opcion);

switch(opcion)
{
case 1:
InsertarNodoIzq ( &Cabeza );
break;
case 2:
InsertarNodoEsp ( Cabeza );
break;
case 3:
BuscarNodo ( Cabeza );
break;
case 4:
ModificarNodo ( Cabeza );
break;
case 5:
BorrarNodo ( &Cabeza );
break;
case 6:
ImprimirLista ( Cabeza );
break;
case 7:
GuardarLista ( Cabeza );
break;
case 8:
printf("\n...:::FIN DEL PROGRAMA:::...\n\n");
exit (-1);
break;
default:
system("clear");
printf("\n...:::OPCION NO VALIDA:::...\n");
break;
} //Fin del switch.
Menu ( );
} //Fin del do.
while(opcion!=8);

return 0;
}

//Función que inserta un nodo a izquierda del primer nodo. Es decir, el último nodo
//ingresado va a ser la cola izquierda de nuestra lista y el primer nodo ingresado
//será su cola derecha.
void InsertarNodoIzq ( struct nodo **Enlace )
{
struct nodo *Nuevo; //Puntero a la estructura nodo.

Nuevo = CrearNodo ( ); //Se crea un espacio de memoria.

if ( Nuevo == NULL ) //No se pudo reservar memoria.
{
printf("\nNo se pudo asignar memoria\n");
return;
}
//Doble enlace.
Nuevo -> Siguiente = *Enlace; //El nodo creado ahora apunta al nodo que anteriormente
//era el primer nodo de la lista.
if ( *Enlace != NULL ) //Existen otros nodos.
(*Enlace) -> Anterior = Nuevo; //El nodo nuevo apuntará al primer nodo existente.
*Enlace = Nuevo; //El puntero enlace ( cabeza ) ahora apunta al nuevo nodo creado.
}//Fin de la función

//Esta función también inserta un nodo pero lo hace después del nodo elegido por el
//usuario (buscado a partir del nombre del cliente).
void InsertarNodoEsp ( struct nodo *P )
{
struct nodo *Nuevo;

if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacia\n");
return;
}

BuscarNodo ( P );

if( P == NULL )
printf ("\nEl elemento buscado no se encuentra en la lista.\n");
else{
printf("\nIngrese los campos del nodo a insertar\n");
Nuevo = CrearNodo ( );

if( Nuevo == NULL ) //No se pudo reservar memoria.
printf("\nNo se pudo asignar memoria\n");
else{ //Se creo el nuevo nodo, por ende realizamos el doble enlace.
//Cuatro nodos a modificar.
Nuevo -> Siguiente = P -> Siguiente; //El nuevo nodo apunta al nodo de su derecha.
if ( P -> Siguiente != NULL) //No se inserta al final de la lista.
P -> Siguiente -> Anterior = Nuevo; //El nodo que está a la derecha ahora apunta
//al nuevo nodo (que está a su izquierda).
P -> Siguiente = Nuevo; //El nodo que está a la izquierda apunta al nuevo nodo
//(que está a su derecha).
Nuevo -> Anterior = P; //El nuevo nodo apunta al nodo a su izquierda.
} //Fin del else interno.
} //Fin del else externo.
} //Fin de la función.

//Busca un nodo a partir del nombre ingresado por el usuario.
struct nodo * BuscarNodo ( struct nodo * P )
{
char name[NOMBRE];

printf("\nIngrese el elemento que desea buscar:\n");
printf("\nNombre: "); scanf("%s",name);

//Búsqueda del nodo correspondiente al nombre ingresado.
while( ( P != NULL ) && ( strcmp ( name , P -> nombre ) != 0 ) )
P = P -> Siguiente;

return P;
}

void ModificarNodo ( struct nodo * P )
{
if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía. No hay nodos para modificar\n");
return;
}

P = BuscarNodo ( P );

if ( P == NULL )
printf("\nEl nombre no se encuentra en la lista\n");
else
{
printf("\nModifique los campos del nodo.\n");
printf ("\nStock: "); scanf ("%d" , &P->stock );
}
}

void BorrarNodo ( struct nodo ** Cabeza )
{
struct nodo *Actual;

if ( *Cabeza == NULL ) //Lista vacía.
{
printf("\nLista vacía. No hay nodos para borrar\n");
return;
}

Actual = BuscarNodo ( *Cabeza );

if ( Actual == NULL ) //El nombre seleccionado no se encuentra en la lista.
printf("\nEl elemento no se encuentra en la lista\n");
else{
if ( Actual == *Cabeza ){ //El nodo a borrar es la cabeza.
*Cabeza = Actual -> Siguiente;
if( Actual -> Siguiente != NULL )
Actual -> Siguiente -> Anterior = NULL;
}
else if ( Actual -> Siguiente != NULL ){
Actual -> Anterior -> Siguiente = Actual -> Siguiente;
Actual -> Siguiente -> Anterior = Actual -> Anterior;
}
else
Actual -> Anterior -> Siguiente = NULL;
free ( Actual ); //Libero el espacio de memoria del nodo borrado.
printf("\nNodo borrado\n");
} //Fin del else externo.
} //Fin de la función.

//Crea un nuevo nodo.
struct nodo *CrearNodo ( void )
{
struct nodo *Crear;
Crear = ( struct nodo * ) malloc ( sizeof ( struct nodo ) ); //Creo el nuevo nodo.

if ( Crear == NULL ) //No se pudo almacenar memoria para el nuevo nodo.
return NULL;

//Se ingresan los campos del nodo.
printf ("\nIngrese nombre: "); scanf ("%s", Crear -> nombre );
printf ("\nIngrese numero de inventario: "); scanf("%d",&Crear->inventario);
printf ("Ingrese Stock: "); scanf ("%d",&Crear->stock);
//Doble enlace.
Crear -> Siguiente = NULL;
Crear -> Anterior = NULL;

return Crear; //Retorna el nodo creado.
}

//Menú.
void Menu(void)
{
printf ("\n...:::MENU PRINCIPAL:::...\n");
printf ("1 - Agregar nodo a izquierda del nodo cabeza.\n");
printf ("2 - Agregar nodo en un lugar específico.\n");
printf ("3 - Buscar nodo\n");
printf ("4 - Modificar nodo\n");
printf ("5 - Borrar nodo.\n");
printf ("6 - Mostrar lista.\n");
printf ("7 - Guardar lista.\n");
printf ("8 - Salir\n");
}

//Imprime lista.
void ImprimirLista ( struct nodo *PAD )
{
if ( PAD == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía.\n");
return;
}
//Existe la lista.
struct nodo *PAT;

printf("\n...:::LISTA:::...\n\n");
printf("\nHacia adelante\n");
while ( PAD != NULL ){ //Imprime la lista.
printf("Nombre: %s ", PAD -> nombre );
printf("Inventario: %d ", PAD -> inventario);
printf("Stock: %d --> ", PAD -> stock);
PAT = PAD;
PAD = PAD -> Siguiente;
} //Fin del while.
printf("NULL\n\n");

printf("Hacia atras\n");
while ( PAT != NULL ){ //Imprime la lista al revés.
printf("Nombre: %s ", PAT -> nombre );
printf("Inventario: %d ", PAT -> inventario );
printf("Stock: %d --> ", PAT -> stock );
PAT = PAT -> Anterior;
} //Fin del while.
printf("NULL\n\n");
}

//La siguiente función guarda la lista en un archivo con formato .txt.
void GuardarLista ( struct nodo * Actual )
{
FILE *fd;

fd = fopen ("practicando.txt","wb+");

if ( fd == NULL ){ //No se pudo abrir el archivo.
printf ("\nFallo al abrir el archivo.\n");
return;
}

while ( Actual != NULL ){
//Transcribe los datos de cada nodo en el archivo.
fwrite ( Actual , sizeof (struct nodo) , 1 , fd );
Actual = Actual -> Siguiente; //Nos movemos al siguiente nodo.
}
fclose ( fd ); //Cierra el archivo.
printf ("\nLista guardada en el archivo.\n");
}

//Recupera la lista a partir del archivo.
struct nodo * RecuperarLista ( struct nodo **Cabeza ) //Acá está el error... pero no sé cual es Jaja
{
FILE *Lee;
struct nodo *Actual;

Actual = (struct nodo * ) malloc ( sizeof ( struct nodo * ) );

if ( Actual == NULL ){ //No se reservo memoria.
printf ("\nNo se pudo reservar memoria.\n");
return NULL;
}

Actual -> Siguiente = NULL;
Actual -> Anterior = NULL;

//Abre el archivo para lectura.
Lee = fopen ("practicando.txt","rb");

if( Lee == NULL ){
printf("\nNo se pudo abrir el archivo.\n");
return;
}

fread ( Actual , sizeof ( struct nodo) , 1 , Lee );
*Cabeza = Actual;

if ( Actual == NULL)
return NULL;

while ( !feof ( Lee ) ) //Mientras no llegue al final del archivo...
{
fread ( Actual , sizeof ( struct nodo) , 1 , Lee );
Actual = Actual -> Siguiente;
}
fclose (Lee);

return Actual;
}


\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
20-03-2012 16:10
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] matyary recibio 1 Gracias por este post
Feer (14-10-2012)
pablo.m Sin conexión
Campeon del cubo Rubik
Sin estado :(
****

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 141
Agradecimientos dados: 13
Agradecimientos: 47 en 23 posts
Registro en: Apr 2011
Mensaje: #3
RE: [Ayuda] Ejercicio integrador [Info I]
Hola, veo dos problemas en principio. En la línea 302 en vez de sizeof(struct nodo*) debería decir sizeof(struct nodo), porque es el tamaño de la estructura y no del puntero.

El segundo problema es un poco más difícil de solucionar. Cuando vos leés los registros del archivo (línea 326) estás leyendo también los punteros Siguiente y Anterior, y esto no tiene sentido porque cada vez que corras el programa el malloc te va a dar una dirección distinta, así que no sirve guardar esa dirección en el archivo. Además estás haciendo un sólo malloc y leyendo varios registros, saltando entre nodos con el puntero siguiente que leíste del archivo, que apunta a andá saber dónde. La solución sería redefinir el nodo:



struct info
{
char nombre[NOMBRE];
int inventario;
int stock;
}

struct nodo {
struct info datos;
struct nodo *Siguiente;
struct nodo *Anterior;
};



Después al guardar la lista en el archivo lo único que guardas son los struct info de cada nodo, y cuando levantás el archivo pedís memoria para cada nodo y lo rellenás con la struct info correspondiente.

Un saludo.
(Este mensaje fue modificado por última vez en: 20-03-2012 18:09 por pablo.m.)
20-03-2012 18:08
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #4
RE: [Ayuda] Ejercicio integrador [Info I]
Pablo, muchas gracias por contestar!

El primer problema ya lo resolví, un despiste Jaja

En cuanto al segundo problema, hice unas modificaciones tomando como parámetro lo que me dijiste (ahora malloqueo todos los nodos). Con este cambio, que voy a poner a continuación, logro ejecutar perfectamente el programa por primera vez (cuando el archivo aún no posee nada). Al ejecutarlo nuevamente (con información dentro del archivo) vuelvo a lo mismo: el bendito fallo de segmentación.


//Recupera la lista a partir del archivo.
struct nodo * RecuperarLista ( struct nodo **Cabeza )
{
FILE *Lee;
struct nodo *Actual;

Actual = (struct nodo * ) malloc ( sizeof ( struct nodo ) );

if ( Actual == NULL ){ //No se reservo memoria.
printf ("\nNo se pudo reservar memoria.\n");
return NULL;
}

Actual -> Siguiente = NULL;
Actual -> Anterior = NULL;

//Abre el archivo para lectura.
Lee = fopen ("practicando.txt","rb");

if( Lee == NULL ){
printf("\nNo se pudo abrir el archivo.\n");
return NULL;
}

fread ( Actual , sizeof ( struct nodo) , 1 , Lee );
*Cabeza = Actual;

if ( Actual == NULL)
return NULL;

while ( !feof ( Lee ) ) //Mientras no llegue al final del archivo...
{
fread ( Actual , sizeof ( struct nodo) , 1 , Lee );

Actual = (struct nodo * ) malloc ( sizeof ( struct nodo ) ); //Malloqueo TODOS los nodos.
if ( Actual == NULL ){ //No se reservo memoria.
printf ("\nNo se pudo reservar memoria.\n");
return NULL;
}

Actual = Actual -> Siguiente;
}

fclose (Lee); //Cierro el programa.

return *Cabeza;
}


Eso es lo que pude hacer por ahora, lo que no entiendo (no es porque lo hayas explicado mal, sino porque me cuesta un montón) es el porqué del armado de dos estructuras... qué se logra con eso?

Evidentemente, por lo que le sucede al porgrama con el cambio efectuado recientemente, es un porblema de direcciones como vos bien dijiste.

\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
20-03-2012 19:33
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
pablo.m Sin conexión
Campeon del cubo Rubik
Sin estado :(
****

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 141
Agradecimientos dados: 13
Agradecimientos: 47 en 23 posts
Registro en: Apr 2011
Mensaje: #5
RE: [Ayuda] Ejercicio integrador [Info I]
El tema del armado de las estructuras es porque no tiene sentido guardar la lista en un archivo tal cual está en memoria, porque las direcciones de memoria dinámica siempre son distintas. O sea vos estarías guardando un puntero que apunta a, suponete, la dirección 0xff487a26, después volvés a correr tu programa y ese puntero apunta a una zona que ya no está más reservada para tu programa. Entonces como lo que realmente importa y querés que se guarde es el nombre, el inventario y el stock, entonces hacés una estructura que contenga a esos 3 elementos, que va a ser lo que en definitiva guardes en el archivo. El resto del nodo se genera durante la ejecución- En la línea 289 del programa original te quedaría, entonces: fwrite ( Actual->datos , sizeof (struct info) , 1 , fd );

Para levantar la lista tenés que, para cada registro del archivo, pedir memoria para un nodo, leer la struct info del archivo, copiarla en el campo "datos" del nodo (según mi post anterior), y setear el puntero al siguiente y al anterior. Fijate que para conocer el siguiente y el anterior de un cierto nodo vas a tener que guardar un puntero auxiliar que apunte al nodo anterior (igual que cuando insertás un nodo en el medio de una lista ya armada).
21-03-2012 01:47
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #6
RE: [Ayuda] Ejercicio integrador [Info I]
Claro, el struct info datos tiene todo el contenido de la estructura info. Por eso lo que guardás en el archivo son esos datos y no las direcciones de cada nodo como hacía yo.
Te entendí perfecto, muchas gracias.
Una vez que salga le agrego socketss y creo tener todos los temas en un mismo programa para el final Jaja

\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
21-03-2012 08:57
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #7
RE: [Ayuda] Ejercicio integrador [Info I]
Bueno, acá subo el programa. Lo pude hacer de otra forma. Agregué una nueva función que borra al archivo si el usuario lo desea (OJO! Uso recursividad Jaja).


//Preparación para final de Informática I.
//Lista Doblemente Enlazada.

//Librerías.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NOMBRE 10

//Estructura.
struct nodo {
char nombre[NOMBRE];
int inventario;
int stock;
struct nodo *Siguiente;
struct nodo *Anterior;
};

//Prototipos de las Funciones.
void ImprimirLista ( struct nodo * );
struct nodo * BuscarNodo ( struct nodo * );
void ModificarNodo ( struct nodo * );
void InsertarNodoEsp ( struct nodo * );
void InsertarNodoIzq ( struct nodo ** );
void BorrarNodo ( struct nodo ** );
void Menu ( );
struct nodo * CrearNodo ( );
struct nodo *Registrar ( struct nodo *);
void GuardarLista ( struct nodo * );
void Lista( struct nodo **, struct nodo * );
void RecuperarLista ( struct nodo ** );
int BorrarArchivo ( void );

//Main.
int main ( void )
{
int opcion;
struct nodo *Cabeza=NULL; //Inicialmente la lista se encuentra vacia.

RecuperarLista ( &Cabeza );
Menu ( );

do
{
printf("\nOpción: ");scanf("%d",&opcion);

switch(opcion)
{
case 1:
InsertarNodoIzq ( &Cabeza );
break;
case 2:
InsertarNodoEsp ( Cabeza );
break;
case 3:
BuscarNodo ( Cabeza );
break;
case 4:
ModificarNodo ( Cabeza );
break;
case 5:
BorrarNodo ( &Cabeza );
break;
case 6:
ImprimirLista ( Cabeza );
break;
case 7:
GuardarLista ( Cabeza );
break;
case 8:
printf("\n...:::FIN DEL PROGRAMA:::...\n\n");
exit (-1);
break;
default:
system("clear");
printf("\n...:::OPCION NO VALIDA:::...\n");
break;
} //Fin del switch.
Menu ( );
} //Fin del do.
while(opcion!=8);

return 0;
}

//Función que inserta un nodo a izquierda del primer nodo. Es decir, el último nodo
//ingresado va a ser la cola izquierda de nuestra lista y el primer nodo ingresado
//será su cola derecha.
void InsertarNodoIzq ( struct nodo **Enlace )
{
struct nodo *Nuevo; //Puntero a la estructura nodo.

Nuevo = Registrar ( CrearNodo ( ) ); //Se crea un espacio de memoria.

if ( Nuevo == NULL ) //No se pudo reservar memoria.
{
printf("\nNo se pudo asignar memoria\n");
return;
}
//Doble enlace.
Nuevo -> Siguiente = *Enlace; //El nodo creado ahora apunta al nodo que anteriormente
//era el primer nodo de la lista.
if ( *Enlace != NULL ) //Existen otros nodos.
(*Enlace) -> Anterior = Nuevo; //El nodo nuevo apuntará al primer nodo existente.
*Enlace = Nuevo; //El puntero enlace ( cabeza ) ahora apunta al nuevo nodo creado.
}//Fin de la función

//Esta función también inserta un nodo pero lo hace después del nodo elegido por el
//usuario (buscado a partir del nombre del cliente).
void InsertarNodoEsp ( struct nodo *P )
{
struct nodo *Nuevo;

if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacia\n");
return;
}

BuscarNodo ( P );

if( P == NULL )
printf ("\nEl elemento buscado no se encuentra en la lista.\n");
else{
printf("\nIngrese los campos del nodo a insertar\n");
Nuevo = Registrar ( CrearNodo ( ) );;

if( Nuevo == NULL ) //No se pudo reservar memoria.
printf("\nNo se pudo asignar memoria\n");
else{ //Se creo el nuevo nodo, por ende realizamos el doble enlace.
//Cuatro nodos a modificar.
Nuevo -> Siguiente = P -> Siguiente; //El nuevo nodo apunta al nodo de su derecha.
if ( P -> Siguiente != NULL) //No se inserta al final de la lista.
P -> Siguiente -> Anterior = Nuevo; //El nodo que está a la derecha ahora apunta
//al nuevo nodo (que está a su izquierda).
P -> Siguiente = Nuevo; //El nodo que está a la izquierda apunta al nuevo nodo
//(que está a su derecha).
Nuevo -> Anterior = P; //El nuevo nodo apunta al nodo a su izquierda.
} //Fin del else interno.
} //Fin del else externo.
} //Fin de la función.

//Busca un nodo a partir del nombre ingresado por el usuario.
struct nodo * BuscarNodo ( struct nodo * P )
{
char name[NOMBRE];

printf("\nIngrese el elemento que desea buscar:\n");
printf("\nNombre: "); scanf("%s",name);

//Búsqueda del nodo correspondiente al nombre ingresado.
while( ( P != NULL ) && ( strcmp ( name , P -> nombre ) != 0 ) )
P = P -> Siguiente;

return P;
}

void ModificarNodo ( struct nodo * P )
{
if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía. No hay nodos para modificar\n");
return;
}

P = BuscarNodo ( P );

if ( P == NULL )
printf("\nEl nombre no se encuentra en la lista\n");
else
{
printf("\nModifique los campos del nodo.\n");
printf ("\nStock: "); scanf ("%d" , &P->stock );
}
}

void BorrarNodo ( struct nodo ** Cabeza )
{
struct nodo *Actual;

if ( *Cabeza == NULL ) //Lista vacía.
{
printf("\nLista vacía. No hay nodos para borrar\n");
return;
}

Actual = BuscarNodo ( *Cabeza );

if ( Actual == NULL ) //El nombre seleccionado no se encuentra en la lista.
printf("\nEl elemento no se encuentra en la lista\n");
else{
if ( Actual == *Cabeza ){ //El nodo a borrar es la cabeza.
*Cabeza = Actual -> Siguiente;
if( Actual -> Siguiente != NULL )
Actual -> Siguiente -> Anterior = NULL;
}
else if ( Actual -> Siguiente != NULL ){
Actual -> Anterior -> Siguiente = Actual -> Siguiente;
Actual -> Siguiente -> Anterior = Actual -> Anterior;
}
else
Actual -> Anterior -> Siguiente = NULL;
free ( Actual ); //Libero el espacio de memoria del nodo borrado.
printf("\nNodo borrado\n");
} //Fin del else externo.
} //Fin de la función.

//Crea un nuevo nodo.
struct nodo *CrearNodo ( void )
{
struct nodo *Crear;
Crear = ( struct nodo * ) malloc ( sizeof ( struct nodo ) ); //Creo el nuevo nodo.

if ( Crear == NULL ) //No se pudo almacenar memoria para el nuevo nodo.
return NULL;

//Doble enlace.
Crear -> Siguiente = NULL;
Crear -> Anterior = NULL;

return Crear; //Retorna el nodo creado.
}

struct nodo *Registrar ( struct nodo *Reg )
{
//Se ingresan los campos del nodo.
printf ("\nIngrese nombre: "); scanf ("%s", Reg -> nombre );
printf ("\nIngrese numero de inventario: "); scanf("%d",&Reg->inventario);
printf ("Ingrese Stock: "); scanf ("%d",&Reg->stock);

return Reg;
}

//Menú.
void Menu(void)
{
printf ("\n...:::MENU PRINCIPAL:::...\n");
printf ("1 - Agregar nodo a izquierda del nodo cabeza.\n");
printf ("2 - Agregar nodo en un lugar específico.\n");
printf ("3 - Buscar nodo\n");
printf ("4 - Modificar nodo\n");
printf ("5 - Borrar nodo.\n");
printf ("6 - Mostrar lista.\n");
printf ("7 - Guardar lista.\n");
printf ("8 - Salir\n");
}

//Imprime lista.
void ImprimirLista ( struct nodo *PAD )
{
if ( PAD == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía.\n");
return;
}
//Existe la lista.
struct nodo *PAT;

printf("\n...:::LISTA:::...\n\n");
printf("\nHacia adelante\n");
while ( PAD != NULL ){ //Imprime la lista.
printf("Nombre: %s ", PAD -> nombre );
printf("Inventario: %d ", PAD -> inventario);
printf("Stock: %d --> ", PAD -> stock);
PAT = PAD;
PAD = PAD -> Siguiente;
} //Fin del while.


printf("\nHacia atras\n");
while ( PAT != NULL ){ //Imprime la lista al revés.
printf("Nombre: %s ", PAT -> nombre );
printf("Inventario: %d ", PAT -> inventario );
printf("Stock: %d --> ", PAT -> stock );
PAT = PAT -> Anterior;
} //Fin del while.
}

//La siguiente función guarda la lista en un archivo con formato .txt.
void GuardarLista ( struct nodo * Actual )
{
FILE *fd;

fd = fopen ("practicando.txt","wb+");

if ( fd == NULL ){ //No se pudo abrir el archivo.
printf ("\nFallo al abrir el archivo.\n");
return;
}

while ( Actual != NULL ){
//Transcribe los datos de cada nodo en el archivo.
fwrite ( Actual , sizeof (struct nodo) , 1 , fd );
Actual = Actual -> Siguiente; //Nos movemos al siguiente nodo.
}
fclose ( fd ); //Cierra el archivo.
printf ("\nLista guardada en el archivo.\n");
}

//Crea lista.
void Lista( struct nodo **Cabeza, struct nodo *Actual )
{
struct nodo *Nuevo;
Nuevo = CrearNodo ( );

Nuevo -> inventario = Actual -> inventario;
strcpy ( Nuevo->nombre , Actual -> nombre );
Nuevo -> stock = Actual -> stock;

Nuevo -> Siguiente = *Cabeza;
*Cabeza = Nuevo;
}

//Recupera la lista a partir del archivo.
void RecuperarLista ( struct nodo **Cabeza )
{
FILE *Lee;
struct nodo datos;
int ba;

ba = BorrarArchivo ( );

if ( ba == 2) {
//Abre el archivo para lectura.
Lee = fopen ("practicando.txt","rb");

if( Lee == NULL )
printf("\nNo se pudo abrir el archivo.\n");

else {
fread ( &datos , sizeof ( struct nodo) , 1 , Lee );
while ( !feof ( Lee ) ) //Mientras no llegue al final del archivo...
{
Lista ( Cabeza, &datos );
fread ( &datos , sizeof ( struct nodo) , 1 , Lee );
}

fclose (Lee);
}
}
}

//Borra o no el archivo practicando.txt
int BorrarArchivo ( void )
{
int opcion;

printf ("\nIndique que desea hacer:\n1- Borrar archivo.\n2- Continuar con los datos cargados.\n");
printf ("\nOpción:\t"); scanf ("%d", &opcion);

if ( opcion == 1 )
remove ("practicando.txt");
else if ( opcion == 2 )
printf ("\nDatos recuperados.\n");
else BorrarArchivo ( ); //Recursividad.

return opcion;
}


En cuanto pueda agregarle algo de sockets subo la nueva versión. Saludos!

\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
21-03-2012 11:51
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
JulianD Sin conexión
Colaborador
~`☼`~
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 2.431
Agradecimientos dados: 271
Agradecimientos: 912 en 109 posts
Registro en: Feb 2011
Mensaje: #8
RE: [Ayuda] Ejercicio integrador [Info I]
Le podes agregar una funcion de swap y usarla para aplicar algun metodo de ordenamiento..
Aunque debo decir que yo practique de esta misma manera para el segundo parcial y no me sirvio.
El metodo que mejores resultados me dio (por no decir el unico que me dio resultados buenos) fue programar en papel y despues pasarlo a la pc a ver si funca o no.

[Imagen: 2r27ldw.jpg]
21-03-2012 14:52
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #9
RE: [Ayuda] Ejercicio integrador [Info I]
Lo del ordenamiento es buena idea, sí.
Y respecto a lo que decís acerca del manuscrito, yo suelo dibujar los nodos en un borrador para armar mejor la lista. Pero de ahí a escribir todo el programa, eso ni en pedo Jaja Aparte que diferencia hay entre hacerlo en papel y hacerlo directo en pc? No me lo bajé de ningún sitio para programadores, lo hice yo. La práctica es la misma a mi entender. A menos que te queden mejor las cosas escribiendo, eso podría ser. Y la verdad que muchas ganas de programar no tengo, pero de hacer algo bastante completo me lo estudiaría de memoria para el final como me dijeron varias personas.

\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
21-03-2012 16:06
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Feer Sin conexión
Presidente del CEIT
Ing. Electrónico
**********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 4.672
Agradecimientos dados: 601
Agradecimientos: 2.976 en 451 posts
Registro en: Apr 2010
Mensaje: #10
RE: [Ayuda] Ejercicio integrador [Info I]
Che tomaran doble enlazada en mayo?
Hay algunos finales que son regaladisimos y otros raros pero en mayo deberían tirar algo safable xd

[Imagen: digitalizartransparent.png]
21-03-2012 20:48
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #11
RE: [Ayuda] Ejercicio integrador [Info I]
No tengo ni puta idea, ojalá supiera. Ahora me fijo en campusviertual, quizás encuentre algún final. Pienso igual, en mayo la van a hacer bastante aprobable, no fácil Jaja
Acá dejo lo poco que encontré... me metí a creo que todos los cursos de Info I. Seguramente todo lo que subo lo tengan porque si mal no recuerdo la bajé de acá, excepto el archivo que dice "enunciados_de_finales". Eso lo bajé del campus de mi curso. No tiene fecha, es un mini compilado de teóricos y prácticos tomados recientemente en finales.


Archivo(s) adjuntos Imagen(es)
       

.pdf  enunciados_de_finales.pdf (Tamaño: 45,27 KB / Descargas: 19)
.doc  Final 2-12-10.doc (Tamaño: 23 KB / Descargas: 8)

\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
(Este mensaje fue modificado por última vez en: 21-03-2012 22:07 por matyary.)
21-03-2012 21:46
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Feer Sin conexión
Presidente del CEIT
Ing. Electrónico
**********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 4.672
Agradecimientos dados: 601
Agradecimientos: 2.976 en 451 posts
Registro en: Apr 2010
Mensaje: #12
RE: [Ayuda] Ejercicio integrador [Info I]
Che lo de los puertos y bits no me lo explicaron, lo siguen tomando?

[Imagen: digitalizartransparent.png]
21-03-2012 22:12
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #13
RE: [Ayuda] Ejercicio integrador [Info I]
No sé, espero que no. A mí tampoco me lo explicaron. Alguien sabe si lo toman o no?

\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
21-03-2012 22:14
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
matyary Sin conexión
Presidente del CEIT
SORPRENDEME!
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 1.809
Agradecimientos dados: 68
Agradecimientos: 343 en 83 posts
Registro en: Mar 2011
Mensaje: #14
RE: [Ayuda] Ejercicio integrador [Info I]
Bueno ya que estamos, subo un programa recién sacado del horno... todavía tengo que solucionar el ordenamiento. Lo demás funciona perfecto.


//Este programa fue realizado por el mejor programador de todos los tiempos, yo.
//Después de largas horas de duro trabajo y tras llegar a un colapso neuronal, pude terminarlo.
//Si bien tengo un pequeño inconveniente en una función, el laburo es magnífico.
//Tres Hip Hip Hurra para mí: "Hip Hip Hurra, Hip Hip Hurra, Hip Hip Hurra."
//Preparación para final de Informática I.
//Lista Simplemente Enlazada + Manejo de Archivo + Ordenamiento.

//Librerías.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NOMBRE 10

//Estructura.
struct nodo {
char nombre[NOMBRE];
int inventario;
int stock;
struct nodo *Siguiente;
};

//Prototipos de las Funciones.
void ImprimirLista ( struct nodo * );
struct nodo * BuscarNodo ( struct nodo * );
void ModificarNodo ( struct nodo * );
void InsertarNodoEsp ( struct nodo * );
void InsertarNodoIzq ( struct nodo ** );
void BorrarNodo ( struct nodo ** );
void Menu ( );
struct nodo * CrearNodo ( );
struct nodo *Registrar ( struct nodo *);
void GuardarLista ( struct nodo * );
void Lista( struct nodo **, struct nodo * );
void RecuperarLista ( struct nodo ** );
int BorrarArchivo ( void );
void OrdenarLista ( struct nodo ** );

//Main.
int main ( void )
{
int opcion;
struct nodo *Cabeza=NULL; //Inicialmente la lista se encuentra vacia.

RecuperarLista ( &Cabeza );
Menu ( );

do
{
printf("\nOpción: ");scanf("%d",&opcion);

switch(opcion)
{
case 1:
InsertarNodoIzq ( &Cabeza );
break;
case 2:
InsertarNodoEsp ( Cabeza );
break;
case 3:
BuscarNodo ( Cabeza );
break;
case 4:
ModificarNodo ( Cabeza );
break;
case 5:
BorrarNodo ( &Cabeza );
break;
case 6:
ImprimirLista ( Cabeza );
break;
case 7:
GuardarLista ( Cabeza );
break;
case 8:
OrdenarLista ( &Cabeza );
break;
case 9:
printf("\n...:::FIN DEL PROGRAMA:::...\n\n");
exit (-1);
break;
default:
system("clear");
printf("\n...:::OPCION NO VALIDA:::...\n");
break;
} //Fin del switch.
Menu ( );
} //Fin del do.
while( opcion != 9 );

return 0;
}

//Función que inserta un nodo a izquierda del primer nodo. Es decir, el último nodo
//ingresado va a ser la cola izquierda de nuestra lista y el primer nodo ingresado
//será su cola derecha.
void InsertarNodoIzq ( struct nodo **Enlace )
{
struct nodo *Nuevo; //Puntero a la estructura nodo.

Nuevo = Registrar ( CrearNodo ( ) ); //Se crea un espacio de memoria.

if ( Nuevo == NULL ) //No se pudo reservar memoria.
{
printf("\nNo se pudo asignar memoria\n");
return;
}
//Doble enlace.
Nuevo -> Siguiente = *Enlace; //El nodo creado ahora apunta al nodo que anteriormente
//era el primer nodo de la lista.
*Enlace = Nuevo; //El puntero enlace ( cabeza ) ahora apunta al nuevo nodo creado.
}//Fin de la función

//Esta función también inserta un nodo pero lo hace después del nodo elegido por el
//usuario (buscado a partir del nombre del cliente).
void InsertarNodoEsp ( struct nodo *P )
{
struct nodo *Nuevo;

if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacia\n");
return;
}

BuscarNodo ( P );

if( P == NULL )
printf ("\nEl elemento buscado no se encuentra en la lista.\n");
else{
printf("\nIngrese los campos del nodo a insertar\n");
Nuevo = Registrar ( CrearNodo ( ) );;

if( Nuevo == NULL ) //No se pudo reservar memoria.
printf("\nNo se pudo asignar memoria\n");
else{ //Se creo el nuevo nodo, por ende realizamos el doble enlace.
//Cuatro nodos a modificar.
Nuevo -> Siguiente = P -> Siguiente; //El nuevo nodo apunta al nodo de su derecha.
P -> Siguiente = Nuevo; //El nodo que está a la izquierda apunta al nuevo nodo
//(que está a su derecha).
} //Fin del else interno.
} //Fin del else externo.
} //Fin de la función.

//Busca un nodo a partir del nombre ingresado por el usuario.
struct nodo * BuscarNodo ( struct nodo * P )
{
char name[NOMBRE];

printf("\nIngrese el elemento que desea buscar:\n");
printf("\nNombre: "); scanf("%s",name);

//Búsqueda del nodo correspondiente al nombre ingresado.
while( ( P != NULL ) && ( strcmp ( name , P -> nombre ) != 0 ) )
P = P -> Siguiente;

return P;
}

void ModificarNodo ( struct nodo * P )
{
if( P == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía. No hay nodos para modificar\n");
return;
}

P = BuscarNodo ( P );

if ( P == NULL )
printf("\nEl nombre no se encuentra en la lista\n");
else
{
printf("\nModifique los campos del nodo.\n");
printf ("\nStock: "); scanf ("%d" , &P->stock );
}
}

void BorrarNodo ( struct nodo ** Cabeza )
{
struct nodo *Actual, *Anterior;
char name[NOMBRE];

if ( *Cabeza == NULL ) //Lista vacía.
{
printf("\nLista vacía. No hay nodos para borrar\n");
return;
}

Actual = *Cabeza;

printf("\nIngrese el elemento que desea buscar:\n");
printf("\nNombre: "); scanf("%s",name);

while ( Actual != NULL && strcmp ( name , Actual -> nombre ) != 0 )
{
Anterior = Actual;
Actual = Actual -> Siguiente;
}

if ( Actual == NULL ) //El nombre seleccionado no se encuentra en la lista.
printf("\nEl elemento no se encuentra en la lista\n");
else{
if ( Actual == *Cabeza )
*Cabeza = Actual -> Siguiente;
else
Anterior -> Siguiente = Actual -> Siguiente;

free ( Actual ); //Libero el espacio de memoria del nodo borrado.
printf("Nodo borrado\n");
} //Fin del else externo.
} //Fin de la función.

//Crea un nuevo nodo.
struct nodo *CrearNodo ( void )
{
struct nodo *Crear;
Crear = ( struct nodo * ) malloc ( sizeof ( struct nodo ) ); //Creo el nuevo nodo.

if ( Crear == NULL ) //No se pudo almacenar memoria para el nuevo nodo.
return NULL;

//Doble enlace.
Crear -> Siguiente = NULL;

return Crear; //Retorna el nodo creado.
}

struct nodo *Registrar ( struct nodo *Reg )
{
//Se ingresan los campos del nodo.
printf ("\nIngrese nombre: "); scanf ("%s", Reg -> nombre );
printf ("\nIngrese numero de inventario: "); scanf("%d",&Reg->inventario);
printf ("Ingrese Stock: "); scanf ("%d",&Reg->stock);

return Reg;
}

//Menú.
void Menu(void)
{
printf ("\n...:::MENU PRINCIPAL:::...\n");
printf ("1 - Agregar nodo a izquierda del nodo cabeza.\n");
printf ("2 - Agregar nodo en un lugar específico.\n");
printf ("3 - Buscar nodo\n");
printf ("4 - Modificar nodo\n");
printf ("5 - Borrar nodo.\n");
printf ("6 - Mostrar lista.\n");
printf ("7 - Guardar lista.\n");
printf ("8 - Ordenar lista.\n");
printf ("9 - Salir\n");
}

//Imprime lista.
void ImprimirLista ( struct nodo *PAD )
{
if ( PAD == NULL ) //La lista se encuentra vacía.
{
printf("\nLista vacía.\n");
return;
}
//Existe la lista.

printf("\n...:::LISTA:::...\n\n");
while ( PAD != NULL ){ //Imprime la lista.
printf("Nombre: %s ", PAD -> nombre );
printf("Inventario: %d ", PAD -> inventario);
printf("Stock: %d --> ", PAD -> stock);
PAD = PAD -> Siguiente;
} //Fin del while.
}

//La siguiente función guarda la lista en un archivo con formato .txt.
void GuardarLista ( struct nodo * Actual )
{
FILE *fd;

fd = fopen ("practicando.txt","wb+");

if ( fd == NULL ){ //No se pudo abrir el archivo.
printf ("\nFallo al abrir el archivo.\n");
return;
}

while ( Actual != NULL ){
//Transcribe los datos de cada nodo en el archivo.
fwrite ( Actual , sizeof (struct nodo) , 1 , fd );
Actual = Actual -> Siguiente; //Nos movemos al siguiente nodo.
}
fclose ( fd ); //Cierra el archivo.
printf ("\nLista guardada en el archivo.\n");
}

//Crea lista.
void Lista( struct nodo **Cabeza, struct nodo *Actual )
{
struct nodo *Nuevo;
Nuevo = CrearNodo ( );

Nuevo -> inventario = Actual -> inventario;
strcpy ( Nuevo->nombre , Actual -> nombre );
Nuevo -> stock = Actual -> stock;

Nuevo -> Siguiente = *Cabeza;
*Cabeza = Nuevo;
}

//Recupera la lista a partir del archivo.
void RecuperarLista ( struct nodo **Cabeza )
{
FILE *Lee;
struct nodo datos;
int ba;

ba = BorrarArchivo ( );

if ( ba == 2) {
//Abre el archivo para lectura.
Lee = fopen ("practicando.txt","rb");

if( Lee == NULL )
printf("\nNo se pudo abrir el archivo.\n");

else {
fread ( &datos , sizeof ( struct nodo) , 1 , Lee );
while ( !feof ( Lee ) ) //Mientras no llegue al final del archivo...
{
Lista ( Cabeza, &datos );
fread ( &datos , sizeof ( struct nodo) , 1 , Lee );
}

fclose (Lee);
}
}
}

//Borra o no el archivo practicando.txt
int BorrarArchivo ( void )
{
int opcion;

printf ("\nIndique que desea hacer:\n1- Borrar archivo.\n2- Continuar con los datos cargados.\n");
printf ("\nOpción:\t"); scanf ("%d", &opcion);

if ( opcion == 1 )
remove ("practicando.txt");
else if ( opcion == 2 )
printf ("\nDatos recuperados.\n");
else BorrarArchivo ( ); //Recursividad.

return opcion;
}

//Ordena la lista según el nombre del cliente.
void OrdenarLista ( struct nodo **Cabeza )
{
struct nodo *Actual, *Anterior, *Aux;

Anterior = *Cabeza;
Actual = Anterior -> Siguiente;

while ( Actual != NULL ) {
if ( strcmp ( Actual -> nombre , Anterior -> nombre ) < 0 ){ //Si el nodo Actual es
//menor al nodo Anterior...
//Intercambio de nodos.
Aux = Actual; Actual = Anterior; Anterior = Aux;
//Generar Lista.
Lista ( &Actual , Anterior );
}
Actual = Actual -> Siguiente;
Anterior = Anterior -> Siguiente;
}
}



\[\sqrt{-1} \;\; 2^3 \;\; \sum \;\; \pi\]
... and it was good!


Mi web: Von Hexlein
23-03-2012 11:46
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
JulianD Sin conexión
Colaborador
~`☼`~
********

Ing. Electrónica
Facultad Regional Buenos Aires

Mensajes: 2.431
Agradecimientos dados: 271
Agradecimientos: 912 en 109 posts
Registro en: Feb 2011
Mensaje: #15
RE: [Ayuda] Ejercicio integrador [Info I]
Uh, ahora te falta la funcion de intercambio o swap que es alto bolonqui.
Hay que tener en cuenta si los nodos son consecutivos o no y un par de cosas mas..
Yo la tengo hecha para una lista simple, si te sirve te la paso.

[Imagen: 2r27ldw.jpg]
23-03-2012 15:19
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Buscar en el tema
Enviar respuesta 




Usuario(s) navegando en este tema: 3 invitado(s)