[C con Clase] Ayuda con Listas simplemente ligadas

Fernando Cervera fernandogcervera en gmail.com
Mie Sep 19 00:02:58 CEST 2012


Te estás olvidando de asignar el parámetro *NodoLugar* lugaresVisita*

void InsertarRecorrido(NodoRecorrido** lista , char* guia, int numPersonas,
NodoLugar* lugaresVisita)
{
    ...
    // Introducir la información en el nuevo nodo
    // strcpy(destino,fuente)
    strcpy(nuevoNodo->guia, guia);
    nuevoNodo->numPersonas = numPersonas;
-   nuevoNodo->lugaresVisita = NULL;
+   nuevoNodo->lugaresVisita =  lugaresVisita;
    ...
}

2012/9/18 Elois@ Guevara <elo_mentemaestra en hotmail.com>

> Hola, tengo un problema. Es una tarea de la unversidad. Me piden hacer un
> programa con listas ligadas que permita agregar información de Recorridos y
> lugares, debe existir una lista de lugares y una lista de recorridos, todo
> esto lo implementé con nodos.
> Despues cada recorrido debe visitar por lo menos un lugar (o más) esto
> debe poder agregarlo el usuario y visualizar en un menú. Solo que no se
> como insertar una referencia a cada lugar de la lista en el nodo del
> recorrido (será con puteros dobles?). Tengo prohibido usar arreglos, todo
> debe hacerse con memoria dinámica. Gracias de antemano por leer esto.
>  Este es mi código:
>
> #include <iostream>
> #include <cstdlib>
> #include <cstring>
> #include <windows.h>
> using namespace std;
>
> typedef int tipoDato;
>
> // Estructura principal para Lugares
> typedef struct NodoLugar
> {
>     char* nombre;
>     char* ubicacion;
>     struct NodoLugar* siguiente;     // Referencia al siguiente elemento
>
> }NodoLugar;
>
> NodoLugar* inicioL;
>
> // Estructura para guardar la información de los recorridos
> typedef struct NodoRecorrido{
>     char* guia;
>     int numPersonas;
>     NodoLugar* lugaresVisita;
>     struct NodoRecorrido* siguiente;
>
> }NodoRecorrido;
>
>
> NodoRecorrido* inicioR;
>
> // Función para mostrar el menu principal de opciones
> int Menu();
> //
> int SubMenu();
> // Función para hacer una pausa en la pantalla
> void Pausa();
>
> //********** Funciones para lugares **************************
>
> // Función para insertar un nuevo Lugar en la lista de lugares
> void InsertarLugar(NodoLugar**, char*, char*);
> // Función para eliminar un Lugar de la lista de lugares
> bool EliminarLugar(NodoLugar**, char*);
> // Función para mostrar la lista de Lugares
> void MostrarLugar(NodoLugar**);
> // Función para verificar si la lista de lugares está vacía
> bool ListaVacia(NodoLugar**);
> //
> bool BuscarLugar(NodoLugar**, char*);
>
> //********** Funciones para recorridos **************************
>
> // Función para insertar un nuevo Recorrido en la lista de recorridos
> void InsertarRecorrido(NodoRecorrido**, char*, int, NodoLugar*
> lugaresVisita);
> // Función para eliminar un Recorrido de la lista de recorridos
> bool EliminarRecorrido(NodoRecorrido**, char*);
> // Función para mostrar la lista de recorridos
> void MostrarRecorrido(NodoRecorrido**);
> // Función para verificar si la lista de recorridos está vacía
> bool ListaRecVacia(NodoRecorrido**);
>
> // ***************** Función main ******************
> int main()
> {
>     int opc=0, o=0;
>
>     // Datos de lugar
>     char* nombre;
>     char* ubicacion;
>
>     // Datos de recorrido
>     char* guia;
>     int numPersonas;
>     NodoLugar* lugaresVisita;
>
>     // Es necesario inicializar el "inicio" de ambas listas en NULL ya que
> al comienzo del programa están vacías
>     inicioL=NULL;
>     inicioR=NULL;
>
>     do
>     {
>
>         opc=Menu();
>
>         switch(opc)
>         {
>             case 1:
>                 do{
>                     o=SubMenu();
>                     }while(o < 1 || o > 2);
>                 if(o == 1)
>                 {
>                 cout << "   Nombre del lugar: ";
>                 nombre=(char*)malloc(sizeof(char)*20);
>                 fflush(stdin);
>                 gets(nombre);
>                 cout << "   Ubicacion del lugar: ";
>                 ubicacion=(char*)malloc(sizeof(char)*50);
>                 fflush(stdin);
>                 gets(ubicacion);
>                 InsertarLugar(&inicioL, nombre, ubicacion);
>                 }
>
>                 else
>                 {
>                     if(!&inicioL)
>                     {
>                         cout<<"\n   Lista de lugares vacia, para agregar
> un recorrido\ndebe existir por lo menos un lugar en la lista...\n";
>                         break;
>                     }
>                 cout << "   Nombre del guia: ";
>                 guia=(char*)malloc(sizeof(char)*30);
>                 fflush(stdin);
>                 gets(guia);
>                 cout << "   Numero de personas: ";
>                 cin >> numPersonas;
>                 InsertarRecorrido(&inicioR, guia, numPersonas, inicioL);
>                 }
>                 break;
>
>             case 2:
>                 do{
>                     o=SubMenu();
>                     }while(o < 1 || o > 2);
>                 if(o == 1)
>                 {
>                     cout << "   Nombre del lugar: ";
>                     nombre=(char*)malloc(sizeof(char)*20);
>                     fflush(stdin);
>                     gets(nombre);
>                     EliminarLugar(&inicioL, nombre);
>                 }
>
>                 else
>                 {
>                     cout << "   Nombre del guia: ";
>                     guia=(char*)malloc(sizeof(char)*30);
>                     fflush(stdin);
>                     gets(guia);
>                     cout << "   Numero de personas: ";
>                     cin >> numPersonas;
>                     EliminarRecorrido(&inicioR, guia);
>                 }
>                 break;
>
>             case 3:
>                 do{
>                     o=SubMenu();
>                     }while(o < 1 || o > 2);
>                 if(o == 1)
>                 {
>                     cout<<"\n   Lista de lugares: \n";
>                     MostrarLugar(&inicioL); Pausa();
>                 }
>
>                 else
>                 {
>                     cout<<"\n   Lista de recorridos: \n";
>                     MostrarRecorrido(&inicioR); Pausa();
>                 }
>                 break;
>
>             case 5:
>                 break;
>
>             case 0:
>                 exit(0);
>                 break;
>
>             default:
>                 cout << "\a\n   Opcion invalida!...";
>                 Sleep(800);
>                 break;
>         }
>
>     }while(opc != 0);
>
>     return 0;
> }
>
> // Menu de opciones
> int Menu()
> {
>     int opcion;
>     system("cls"); system("COLOR 4F");
>     cout << "\n     === Recorridos ===\n\n";
>     cout << "   1. Insertar\n";
>     cout << "   2. Eliminar\n";
>     cout << "   3. Mostrar\n";
>     cout << "   4. Buscar\n";
>     cout << "   5. Instrucciones\n";
>     cout << "\t\tOpcion o presione 0 para salir: ";
>     /*
>     Especificaciones que faltan
>     Insertar lugares si repetir (Crear funcion que busque lugar por nombre
> *)
>     Modificar numero de personas (Funcion que muestre la lista con # y
> pregunte el numero de nodo
>     Modificar nombre del guia (Funcion que muestre la lista con # y
> pregunte el numero de nodo busque ese nodo y cambie
>     Buscar los recorridos que van a un mismo lugar
>     Buscar los lugares de un recorrido
>     */
>     cin >> opcion;
>     system("cls");
>     return opcion;
> }
>
> int SubMenu()
> {
>     int opc;
>     system("CLS");
>     cout << "\n  1. Lugar\n";
>     cout << "  2. Recorrido\n";
>     cout << "\tOpcion: ";
>     cin >> opc;
>     system("CLS");
>     return opc;
> }
>
> void Pausa()
> {
>     cout << "\a\n   Presione una tecla para continuar...";
>     fflush(stdin);
>     getchar();
> }
>
> bool ListaVacia(NodoLugar** nodo)
> {
>     if(nodo == NULL)
>         return true;
>     return false;
> }
>
> void InsertarLugar(NodoLugar** lista , char* nombre, char* ubicacion)
> {
>     // Reservar memoria para insertar el nuevo nodo
>     NodoLugar* nuevoNodo=(NodoLugar*)malloc(sizeof(NodoLugar));
>
>     //Si la memoria no es suficiente, salir de la función
>     if(nuevoNodo == NULL)
>         return;
>
>     // Reservar memoria para la nueva informacion
>     nuevoNodo->nombre=(char*)malloc(sizeof(char)*20);
>     nuevoNodo->ubicacion=(char*)malloc(sizeof(char)*30);
>
>     // Introducir la información en el nuevo nodo
>     // strcpy(destino,fuente)
>
>     strcpy(nuevoNodo->nombre, nombre);
>     strcpy(nuevoNodo->ubicacion, ubicacion);
>
>     //Verificar cuando la lista está vacía
>     if(ListaVacia(lista) == true)
>         // Si está vacía, el nuevo nodo apunta al inicio
>         nuevoNodo->siguiente = (*lista);
>
>     else
>         // Si no, hacer que el nuevo nodo apunte al siguiente elemento de
> la lista
>         nuevoNodo->siguiente= (*lista);
>
>     // Finalmente, el apuntador al ultimo elemento insertado es el nuevo
> nodo
>     (*lista) = nuevoNodo;
>     cout<< "\n   El dato ha sido insertado correctamente..."; Sleep(800);
>
> }
>
> bool EliminarLugar(NodoLugar** inicioLista, char* nombre)
> {
>     // * Caso 1: Si la lista está vacía, salir de la función
>     if(ListaVacia(inicioLista)==true)
>         return false;
>
>     // Variable auxiliar tipo apuntador a Nodo, requiere recibir la
> posición del primer elemento de la lista
>     NodoLugar* auxEliminar=(*inicioLista);
>
>     // * Caso 2: Comparar si el dato insertado por el usuario es igual al
> primer dato de la lista
>     if(strcmp(auxEliminar->nombre, nombre) == 0)
>     {
>         // Si es verdadero, recorrer el apuntador al inicio de la lista al
> siguiente elemento
>         (*inicioLista)=(*inicioLista)->siguiente;
>
>         // Liberar la memoria del auxiliar
>         free(auxEliminar);
>
>         // Retornar verdadero porque el nodo se eliminó correctamente
>         return true;
>     }
>
>     // * Caso 3: Si sólo hay un dato en la lista y no está el dato buscado
>     if (auxEliminar->siguiente == NULL)
>         return false;
>
>     // * Caso 4: El elemento puede estar en el resto de la lista
>
>     // Variable auxiliar tipo apuntador a Nodo, para guardar la posición
> anterior al nodo que se va a eliminar
>     NodoLugar* anterior= (*inicioLista);
>
>     // Recorrer el apuntador auxEliminar a la siguiente posición
>     auxEliminar=(*inicioLista)->siguiente;
>
>     // Buscar en el resto de la lista mientras no se encuentre el elemento
> y la lista no se acabe
>     while(strcmp(auxEliminar->nombre, nombre) != 0 && auxEliminar != NULL)
>     {
>         // Si ya no hay más nodos, asignar NULL al auxEliminar
>         if(auxEliminar->siguiente == NULL)
>             auxEliminar = NULL;
>         // Si aun hay nodos, recorrer el auxiliar al siguiente nodo
>         else
>             auxEliminar = auxEliminar->siguiente;
>
>         // Recorrer el auxiliar que guarda la posición anterior al nodo
> que se va a eliminar al siguiente nodo
>         anterior = anterior->siguiente;
>     }
>
>     // Si auxEliminar no es nulo, se encontró el dato
>     if(auxEliminar != NULL)
>     {
>         // Si el dato es el último de la lista, asignar NULL al siguiente
> nodo
>         if(auxEliminar->siguiente == NULL)
>             anterior->siguiente = NULL;
>         // Si no, el dato no es el ultimo,
>         else
>             anterior->siguiente = auxEliminar->siguiente;
>
>         // Liberar memoria de auxEliminar, se pierde la referencia
>         free(auxEliminar);
>
>         // Retornar verdadero ya que el dato se eliminó correctamente
>         return true;
>     }
>
>     // Retornar falso ya que auxEliminar es NULL, entonces el dato no está
> en la lista
>     return false;
> }
>
>
> void MostrarLugar(NodoLugar** inicioLista)
> {
>     // Indice para contar los elementos de la lista que se han mostrado
>     int i=0;
>
>     // Variable tipo apuntador auxiliar a Nodo para recorrer la lista
>     NodoLugar* auxVer=(*inicioLista);
>
>     // Si la lista está vacía muestra un mensaje.
>     if(auxVer==NULL)
>         cout << "\n\t\aLista vacia!...\n";
>
>     // Mientras la lista no esté vacía
>     while( auxVer != NULL)
>     {
>         // Incrementa el contador
>         i++;
>
>         // Muestra los datos
>         cout<<"\t"<<i<<".- Nombre: "<<auxVer->nombre;
>         cout<<"\tUbicacion: "<<auxVer->ubicacion<<endl;
>         // Si la lista está vacía, asignar nulo al auxiliar para cerrar el
> ciclo while
>         if(auxVer == NULL)
>             auxVer = NULL;
>         // Si no, recorrer el apuntador auxiliar a la posición del
> siguiente elemento para continuar mostrando
>         else
>             auxVer = auxVer->siguiente;
>     }
>
>      cout<<"\n\t\aFin de registros...\n"<<"\tTotal: "<<i<<endl;
> }
>
> bool BuscarLugar(NodoLugar** inicioLista, char* nombre)
> {
>
>
>     int i=0;
>     NodoLugar* anterior;
>     NodoLugar* auxBusca=(*inicioLista);
>
>     if(auxBusca==NULL)
>     {
>     cout<<"\a\n   Lista vacia!...\n"; Sleep(700);
>     return false;
>     }
>
>     while(auxBusca != NULL )
>     {
>         i++;
>         if( strcmp(auxBusca->nombre,nombre)==0)
>         {
>             cout<<"\n   El lugar buscado se encuentra en el nodo
> "<<i<<endl;
>             return true;
>         }
>         else
>         {
>         anterior=auxBusca;
>         if(auxBusca == NULL)
>             auxBusca=NULL;
>         else
>             auxBusca=auxBusca->siguiente;
>         }
>
>     }
>
>     cout<<"\n\n\a   El lugar no se encuentra en la lista...\n";
>  Sleep(800);
>     return false;
> }
>
>
>  ////////////////////////////////////////////////
>
>
>  bool ListaRecVacia(NodoRecorrido** nodoR)
> {
>     if(nodoR == NULL)
>         return true;
>     return false;
> }
>
> void InsertarRecorrido(NodoRecorrido** lista , char* guia, int
> numPersonas, NodoLugar* lugaresVisita)
> {
>     // Reservar memoria para insertar el nuevo nodo
>     NodoRecorrido* nuevoNodo=(NodoRecorrido*)malloc(sizeof(NodoRecorrido));
>
>     //Si la memoria no es suficiente, salir de la función
>     if(nuevoNodo == NULL)
>         return;
>
>     nuevoNodo->guia= (char*)malloc(sizeof(char)*30);
>
>     // Introducir la información en el nuevo nodo
>     // strcpy(destino,fuente)
>     strcpy(nuevoNodo->guia, guia);
>     nuevoNodo->numPersonas = numPersonas;
>     nuevoNodo->lugaresVisita = NULL;
>
>     //Verificar cuando la lista está vacía
>     if(ListaRecVacia(lista) == true)
>         // Si está vacía, el nuevo nodo apunta al inicio
>         nuevoNodo->siguiente = (*lista);
>
>     else
>         // Si no, hacer que el nuevo nodo apunte al siguiente elemento de
> la lista
>         nuevoNodo->siguiente= (*lista);
>
>     // Finalmente, el apuntador al ultimo elemento insertado es el nuevo
> nodo
>     (*lista) = nuevoNodo;
>     cout<< "\n   El dato ha sido insertado correctamente..."; Sleep(800);
>
> }
>
> bool EliminarRecorrido(NodoRecorrido** inicioLista, char* guia)
> {
>     // * Caso 1: Si la lista está vacía, salir de la función
>     if(ListaRecVacia(inicioLista)==true)
>         return false;
>
>     // Variable auxiliar tipo apuntador a Nodo, requiere recibir la
> posición del primer elemento de la lista
>     NodoRecorrido* auxEliminar=(*inicioLista);
>
>     // * Caso 2: Comparar si el dato insertado por el usuario es igual al
> primer dato de la lista
>     if(strcmp(auxEliminar->guia, guia) == 0)
>     {
>         // Si es verdadero, recorrer el apuntador al inicio de la lista al
> siguiente elemento
>         (*inicioLista)=(*inicioLista)->siguiente;
>
>         // Liberar la memoria del auxiliar
>         free(auxEliminar);
>
>         // Retornar verdadero porque el nodo se eliminó correctamente
>         return true;
>     }
>
>     // * Caso 3: Si sólo hay un dato en la lista y no está el dato buscado
>     if (auxEliminar->siguiente == NULL)
>         return false;
>
>     // * Caso 4: El elemento puede estar en el resto de la lista
>
>     // Variable auxiliar tipo apuntador a Nodo, para guardar la posición
> anterior al nodo que se va a eliminar
>     NodoRecorrido* anterior= (*inicioLista);
>
>     // Recorrer el apuntador auxEliminar a la siguiente posición
>     auxEliminar=(*inicioLista)->siguiente;
>
>     // Buscar en el resto de la lista mientras no se encuentre el elemento
> y la lista no se acabe
>     while(strcmp(auxEliminar->guia, guia) != 0 && auxEliminar != NULL)
>     {
>         // Si ya no hay más nodos, asignar NULL al auxEliminar
>         if(auxEliminar->siguiente == NULL)
>             auxEliminar = NULL;
>         // Si aun hay nodos, recorrer el auxiliar al siguiente nodo
>         else
>             auxEliminar = auxEliminar->siguiente;
>
>         // Recorrer el auxiliar que guarda la posición anterior al nodo
> que se va a eliminar al siguiente nodo
>         anterior = anterior->siguiente;
>     }
>
>     // Si auxEliminar no es nulo, se encontró el dato
>     if(auxEliminar != NULL)
>     {
>         // Si el dato es el último de la lista, asignar NULL al siguiente
> nodo
>         if(auxEliminar->siguiente == NULL)
>             anterior->siguiente = NULL;
>         // Si no, el dato no es el ultimo,
>         else
>             anterior->siguiente = auxEliminar->siguiente;
>
>         // Liberar memoria de auxEliminar, se pierde la referencia
>         free(auxEliminar);
>
>         // Retornar verdadero ya que el dato se eliminó correctamente
>         return true;
>     }
>
>     // Retornar falso ya que auxEliminar es NULL, entonces el dato no está
> en la lista
>     return false;
> }
>
>
> void MostrarRecorrido(NodoRecorrido** inicioLista)
> {
>     // Indice para contar los elementos de la lista que se han mostrado
>     int i=0;
>
>     // Variable tipo apuntador auxiliar a Nodo para recorrer la lista
>     NodoRecorrido* auxVer=(*inicioLista);
>
>     // Si la lista está vacía muestra un mensaje.
>     if(auxVer==NULL)
>         cout << "\n\t\aLista vacia!...\n";
>
>     // Mientras la lista no esté vacía
>     while( auxVer != NULL)
>     {
>         // Incrementa el contador
>         i++;
>
>         // Muestra los datos
>         cout<<"\t"<<i<<".- Nombre del guia: "<<auxVer->guia;
>         cout<<"\tNumero de personas: "<<auxVer->numPersonas<<endl;
>         // Si la lista está vacía, asignar nulo al auxiliar para cerrar el
> ciclo while
>         if(auxVer == NULL)
>             auxVer = NULL;
>         // Si no, recorrer el apuntador auxiliar a la posición del
> siguiente elemento para continuar mostrando
>         else
>             auxVer = auxVer->siguiente;
>     }
>
>      cout<<"\n\t\aFin de registros...\n"<<"\tTotal: "<<i<<endl;
> }
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20120918/b8482be4/attachment.html>


Más información sobre la lista de distribución Cconclase