Anda di halaman 1dari 6

www.hectorconde.

ga
Resolución del problema: Sistematización de una libreta de calificaciones
Método de resolución: Lista simple
Lenguaje: Microsoft Visual C++ Versión 6.0

El siguiente ejemplo es una implementación de la libreta de calificaciones vista en clase en una estructura de
datos dinámica TADs (Tipos Abstractos de Datos), el tipo de estructura es una LISTA ABIERTA caracterizado
porque cada elemento de la lista (nodo), solo dispone de un puntero que apuntará al siguiente elemento de la
lista o valdrá NULL en caso de ser el último elemento.

#include <iostream>
#include <string>
using namespace std;

const LARGO=40;
//Creación del tipo de dato _nodo, el cual es una estructura que agrupa los datos (campos con los que
trabajará //nuestro programa, tiene en la última línea un campo o puntero autoreferencial, es decir un puntero
que
//apunta a objetos del mismo tipo nodo “struct _nodo *Siguiente”.
typedef struct _nodo
{
int nRegistro;
char cMateria[LARGO];
float nNotaP1;
float nP1;
float nNotaP2;
float nP2;
float nNotaP3;
float nP3;
float nDef;
char cConcepto[LARGO];
struct _nodo *Siguiente;
}TipoNodo;

//TipoNodo es el tipo para declarar nodos


//pNodo es el tipo para declarar punteros a un nodo
//Lista es el tipo para declarar punteros a un nodo

typedef TipoNodo *pNodo;


typedef TipoNodo *Lista;

//Definición de variables globales

char cTmpMateria[LARGO], cTmpConcepto[LARGO];


float nTmpNotaP1,nTmpNotaP2,nTmpNotaP3, nTmpP1,nTmpP2,nTmpP3,nTmpDef;
char cNombre[LARGO], cSemestre[LARGO], cMsjFinal[LARGO];
int nCantidad, ni, nMatPer, nNumRegistro;

1 2007 Hector Conde® Todos los derechos reservados.


www.hectorconde.ga
www.hectorconde.ga
//Definición de variables globales
void InsertarNodo(Lista *l, int nfRegistro, char *cfMateria, char *cfConcepto, float nfNotaP1, float nfNotaP2,
float nfNotaP3, float nfP1, float nfP2, float nfP3, float nfDef);
void BorrarNodo(Lista *l, int nfRegistro);

int ListaVacia(Lista l);


void BorrarLista(Lista *);
void MostrarLista(Lista l);
void Linea(void);

int main(void)
{//Inicio de la función principal
Lista lista=NULL;//Se crea el primer nodo de la lista y se hace igual a NULL, es decir la lista está vacia
//Ahora se hacen todos los procesos referentes al cálculo de la libreta de calificaciones
//----------------------------------------
nCantidad=0;ni=0,nMatPer=0;
cout<<"Nombre: ";
cin>>cNombre;
cout<<"Semestre: ";
cin>>cSemestre;
cout<<"Cantidad de materias: ";
cin>>nCantidad;
if((nCantidad>=3)&&(nCantidad<=10))
{//Inicio de if nCantidad >=3
for(ni=1;ni<=nCantidad;ni++)
{//Inicio for ni
//Lectura de información
cout<<"Materia: ";
cin>>cTmpMateria;
cout<<"Primer parcial: ";
cin>>nTmpNotaP1;
cout<<"Segundo parcial: ";
cin>>nTmpNotaP2;
cout<<"Tercer parcial: ";
cin>>nTmpNotaP3;
//Cálculo de datos
nTmpP1=nTmpNotaP1*0.35;
nTmpP2=nTmpNotaP2*0.35;
nTmpP3=nTmpNotaP3*0.30;
nTmpDef=nTmpP1+nTmpP2+nTmpP3;
if(nTmpDef<3)
{//Inicio de if nTmpDef<3
strcpy(cTmpConcepto,"Habilita");
nMatPer++;
}//Final de if nTmpDef<3
else
{strcpy(cTmpConcepto,"Aprueba");}

2 2007 Hector Conde® Todos los derechos reservados.


www.hectorconde.ga
www.hectorconde.ga
//Proceso de visualización en la pantalla del registro actual
Linea();
cout<<"Materia: "<<cTmpMateria<<" Definitiva: "<<nTmpDef<<" Concepto:
"<<cTmpConcepto<<endl;
//--------------------------------------------
//Una vez que se ha leído y procesado la información, se procede a la inserción
//de los datos en la lista nodo por nodo;
// |----------|----|
// | | |
// | INFO | O--------->
// | | |
// |----------|----|
//Se llama la función InsertarNodo a la cual se le pasa por referencia el nombre de la lista que al inicio del
programa se inicializo con NULL, el número de registro del nodo “ni”, más las variables de tipo temporal
que //contienen la información de la libreta
InsertarNodo(&lista,ni,cTmpMateria, cTmpConcepto,
nTmpNotaP1,nTmpNotaP2,nTmpNotaP3,nTmpP1,nTmpP2,nTmpP3,nTmpDef);

}//Final de for ni
//Una vez ha terminado el ciclo, se evalúa la cantidad de materias perdidas para asignar un mensaje a la variable
resultado
if (nMatPer==0){ strcpy(cMsjFinal,"Felcitaciones pasa en limpío");}
else
{if(nMatPer<=3){strcpy(cMsjFinal,"Habilita materias");}
else{strcpy(cMsjFinal,"Semestre especial");}
}
Linea();
cout<<"El resultado final es: "<<cMsjFinal<<endl;
Linea();
//Hasta aquí se el proceso de calculo de datos de la libreta y su inserción en la lista.
//Ahora se realizarán las principales operaciones con listas
cout<<"Operaciones con listas"<<endl;
Linea();
cout<<"Mostrar toda la lista"<<endl;
MostrarLista(lista); //Se llama la función que muestra toda la lista
Linea();
//El siguiente proceso se utiliza para borrar un nodo específico dentro de la lista, para ello se lee el número de
//registro que se quiere eliminar y se pasa por parámetro a la función BorrarNodo, recibe el nombre de la
lista //que valga la redundancia es el mismo que se inicializo en NULL al principio y el mismo que se paso
por //parámetro en la función InsertarNodo.
cout<<"Borrar un nodo de la lista"<<endl;
cout<<"Digite el número de registro que quiere eliminar:";
cin>>nNumRegistro;
BorrarNodo(&lista,nNumRegistro);
Linea();
//Una vez que se ha eliminado el nodo de la lista, se visualiza nuevamente la lista en pantalla.
cout<<"La lista ahora es:"<<endl;

3 2007 Hector Conde® Todos los derechos reservados.


www.hectorconde.ga
www.hectorconde.ga
MostrarLista(lista);
cin.get();
Linea();
//Proceso de eliminación de la lista completa
cout<<"Ahora se borrará toda la lista:"<<endl;
BorrarLista(&lista);
//Se llama de nuevo la función para mostrar la lista
cout<<"Mostrar la lista o lo que queda de ella"<<endl;
MostrarLista(lista);
cin.get();
}//Final de if nCantidad>=3
else
{//En caso que la cantidad de materias entradas sea errónea se despliega el mensaje de error
cout<<"Entrada de datos erronea!!"<<endl;
}
return 0; //Devuelve 0 al sistema
}//Final de la función principal

void InsertarNodo(Lista *lista, int nfRegistro, char *cfMateria, char *cfConcepto, float nfNotaP1, float
nfNotaP2, float nfNotaP3, float nfP1, float nfP2, float nfP3, float nfDef)
{//Inicio de la función InsertarNodo
pNodo nuevo, anterior; //Se declaran dos variables haciendo uso del tipo definido por el usuario pNodo

//Ya declaradas las variables, se crea un nuevo nodo, para ello se hace uso de la función MALLOC //
(Memory Allocation Asignación de Memoria) y la función SIZEOF (Tamaño de)
nuevo=(pNodo)malloc(sizeof(TipoNodo));//Separa la porción de memoria en la que va el nuevo nodo
nuevo->nRegistro=nfRegistro;
strcpy(nuevo->cMateria,cfMateria);
strcpy(nuevo->cConcepto,cfConcepto);
nuevo->nNotaP1=nfNotaP1;
nuevo->nNotaP2=nfNotaP2;
nuevo->nNotaP3=nfNotaP3;
nuevo->nDef=nfDef;
//Se verifica si la lista está vacia
if(ListaVacia(*lista)||(*lista)->nRegistro>nfRegistro)
{//Inicio de if lista vacia
//Se añade el contenido de la lista a continuación del nuevo nodo
nuevo->Siguiente=*lista;
//Ahora el comienzo de la lista es el nuevo nodo
*lista = nuevo;
}//Final de if Lista vacia
else
{//Inicio del else
//Busca el nodo de menor valor a nRegistro
anterior=*lista;
//Se avanza hasta el último elemento de la lista o hasta el siguiente que tenga un valor
//mayor que nRegistro

4 2007 Hector Conde® Todos los derechos reservados.


www.hectorconde.ga
www.hectorconde.ga
while (anterior->Siguiente && anterior->Siguiente->nRegistro<=nfRegistro)
anterior=anterior->Siguiente;
//Insertamos el nuevo nodo después del nodo anterior
nuevo->Siguiente=anterior->Siguiente;
anterior->Siguiente=nuevo;
}//Final del else
}//Final de la función Insertar Nodo

void BorrarNodo(Lista *lista, int nfRegistro)


{//Inicio de la función BorrarNodo
pNodo anterior, nodo;
nodo=*lista;
anterior=NULL;
//El siguiente ciclo hace un recorrido mientras que el nodo sea diferente de NULL y el campo
//nRegistro sea menor que el valor ingresado por el usuario a través de la variable nfRegistro, se usó la
//comparación “menor que” porque al momento de llenar la información en la lista se utilizó un ciclo for
//incremental, es decir el valor de nRegistro es secuencial e incremental porque fue asignado directamente de
la //variable que controlaba el ciclo. Si no se hubiera hecho esto, es decir; que el valor del registro no se
hubiera //fijado sino leído, sería más conveniente usar la comparación “==”.
while(nodo&&nodo->nRegistro<nfRegistro)
{//Inicio de while nodo
anterior=nodo;
nodo=nodo->Siguiente;
}//Final del while nodo
if(!nodo||nodo->nRegistro!=nfRegistro) return;//No encontró nada de nada
//si encontró el nodo, hacemos que nodo apunte al nodo que se quiere eliminar
else
{//Inicio de else
if (!anterior)//Si es el primer elemento
*lista=nodo->Siguiente;
else //Si es un nodo diferente al primero
//ahora asignamos como nodo siguiente del nodo anterior, el siguiente al que queremos eliminar
anterior->Siguiente=nodo->Siguiente;
//Por último se libera la memoria asociada al nodo que se va a eliminar
free(nodo);//Libera el espació en memoria asignado al nodo
}//Final de else
}//Final del la funcíón BorrarNodo

int ListaVacia(Lista lista)


{//Inicio de la función que verifica si la lista está vacía, para ello basta con comparar si la lista vale NULL
return(lista==NULL);
}//Final de la función lista vacia

void BorrarLista(Lista *lista)


{//Inicio de la función que borra el primer elemento sucesivamente mientras que la lista no este vacía
pNodo nodo;
while(*lista)

5 2007 Hector Conde® Todos los derechos reservados.


www.hectorconde.ga
www.hectorconde.ga
{//Inicio del While
nodo =*lista;
*lista=nodo->Siguiente;
free(nodo);//Bye bye mi querido nodo!!!
}//Final del while

}//Final de la función Borrar Lista

void MostrarLista(Lista lista)


{//Inicio de la función Mostrar lista
//Se declara un puntero auxiliar llamado nodo y se hace igual a lista con el fin de recorrerla
//Se destaca que solo hay un modo de moverse a través de una lista, hacia adelante
pNodo nodo=lista;//Se declara el puntero nodo y se copia lista, al ejecutar este proceso
automáticamente //se ubica en el primer elemento de la lista
if(ListaVacia(lista)){cout<<"La lista está vacia."<<endl;}
else
{//Inicio del else
while(nodo) //Mientras que el nodo sea verdadero, es decir diferente de NULL en cuyo caso sería
//el final de la lista, hace el recorrido mostrando la información de cada nodo de la lista
{//Inicio de while nodo
Linea();
cout<<"Registro No: "<<nodo->nRegistro<<endl;
cout<<"Materia: "<<nodo->cMateria<<endl;
cout<<"Definitiva: "<<nodo->nDef<<endl;
cout<<"Concepto: "<<nodo->cConcepto<<endl;
nodo=nodo->Siguiente;
}//Final del while nodo
}//Final del else
}//Final de la función Mostrar lista

void Linea(void){cout<<"------------------------------ * ------------------------------"<<endl;}

6 2007 Hector Conde® Todos los derechos reservados.


www.hectorconde.ga