Estructuras con Punteros
Requisitos de finalización
8. Ejemplo 1
Vamos a mostrar una serie de ejemplos, en los cuales pordrán ver líneas comentadas.
Consigna:
Gestionar un lista enlazada simple. Desde un menú se invocan a distintas funciones. Una función da de alta UNA instancia por vez. . Otra función deben mostras todas las instancias. Otra función borrar de a una las instancias (la última) y otra función borrar todas las instancias juntas. Esto se logra mendiante el menú. Cada punto del menú invoca una función.
#include <iostream>
using namespace std;
struct lista{float x;lista *pt;};// estructura global.
//Prototipos.
void cargar(lista *&p);
void mostrar(lista *p);
void borrar_ultima(lista *p);
void borrar_todo(lista *&p);
char menu(void);
int main(int argc, char *argv[]) {
lista *p_inicio=NULL;//inicializo a null un puntero a lista
char opc;
do{
opc=menu();
switch(opc)
{
case '1':
cargar(p_inicio);
break;
case '2':
mostrar(p_inicio);
break;
case '3':
borrar_ultima(p_inicio);
break;
case '4':
borrar_todo(p_inicio);
break;
case 'f':
case 'F':
cout<<"Finalizando...";
break;
default:
cout<<"Opcion no valida..";
}}while(!(opc=='f'|| opc=='F'));
// borra(p);
return 0;
}
void cargar(lista *&p)//recibo puntero como argumento por referecia
{
if (p==NULL) //p es null=> primer instancia.
{
p=new lista;// Creo la primer instancia.
cout<<"Ingrese: ";cin>>p->x;
p->pt=NULL; //Cierro la lista enlazada con null
}
else // si p no es null=> no es la primer instancia.
{
lista *p_temp=p;// p_temp puntero local.
//creo una copia del p, para no perder el inicio.
//ver que como paso por referencia si cambio el valor de p se cambia el inicio.
while((p_temp->pt)!=NULL)//mientras p->pt no sea null no llegue al final
{
p_temp=p_temp->pt;
} //recorro hasta la ultima instancia.
p_temp->pt=new lista;// solicito espacio para una nueva instancia.
//reemplazando null por la nueva instancia (enlazando)
p_temp=p_temp->pt; //me traslado hasta la proxima instancia
cout<<"Ingrese valor de instancia:";
cin>>p_temp->x;
p_temp->pt=NULL;//cierro la lista.
/*Las lineas anteriores tambien se pueden escribir.
p_temp->pt=new lista;
cin<<p_temp->pt->x; //ser�a como cin<<(p_temp->pt)->x;
p_temp->pt->pt=NULL;
*/
}
}
void mostrar(lista *p)//p es una copia NO es por referencia
{ int contador=0;
if (p==NULL)cout<<"Nada que mostrar..no hay nada cargado"<<endl;
else
{while(p!=NULL)
{
contador++;//Solo con fines est�ticos para ver la cantidad de instancias
cout<<"Instancia "<<contador<<": "<<p->x<<endl;
p=p->pt;//paso a la proxima instancia.
}
}
}
void borrar_ultima(lista *p)// ver que p es local una copia,pasaje por valor.
{//borrar la ultima instancia...
lista *p_ant;//para salvar la direcci�n de una ante ultima instancia
if (p==NULL)cout<<"Nada que borrar..no hay nada cargado"<<endl;
else
{
while((p->pt)!=NULL){
p_ant=p;//guardo el puntero de la ante �tlima
p=p->pt;//paso a la siguiente
}// avanzo hasta la �ltima instancia
p_ant=p;//guardo el puntero de la ante �tlima
delete p; //borro la �ltima instancia
//aqui no van [] por que es una instancia.
p=p_ant;//me ubico en la ultima( la que seguia se elimino!)
p->pt=NULL;//dejo como NULL la nueva ultima instancia.
}
}
void borrar_todo(lista *&p)
{//Libera borrar Todas las instancias...
//por facilidad borro de la primera a la ultima.
lista *p_prox;
p_prox=p; //guardo una copia local p_temp
if (p==NULL)cout<<"Nada que borrar..no hay nada cargado"<<endl;
else
{while(p!=NULL)
{ p_prox=p->pt;
delete p; //aqui no van [] por que es una sola instancia.
p=p_prox;
}
}
}
char menu()
{
char opc;
cout<<"Menu:"<<endl;
cout<<"1-Cargar una instancia"<<endl;
cout<<"2-Mostrar instancias"<<endl;
cout<<"3-Borrar ultima instancia"<<endl;
cout<<"4-Borrar TODAS las instancias"<<endl;
cout<<"f o F Finaliza"<<endl;
cout<<"Ingrese su eleccion:";
cin>>opc;
return opc;
}
Este código, tiene una falla la cual se observa cuando se tiene cargada una sola instancia y se pretende usar la opcion 3 del menú, que borra la última instancia. Se deja al alumno buscar la solución.