[C con Clase] Ayuda con Listas simplemente ligadas
Elois@ Guevara
elo_mentemaestra en hotmail.com
Mar Sep 18 07:06:32 CEST 2012
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;
}
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20120918/4a8894f8/attachment.html>
Más información sobre la lista de distribución Cconclase