Ejemplo de lista simple en C++

Page 1

Universidad Cooperativa de Colombia Facultad de ingeniería de Sistemas Estructuras de datos 1 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 Fecha: 30 de Abril de 2007 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; 1

2007 Ing. Esp. Hector Enrique Guerrero Conde® Todos los derechos reservados. http://clix.to/hegconde


Universidad Cooperativa de Colombia Facultad de ingeniería de Sistemas Estructuras de datos 1 char cNombre[LARGO], cSemestre[LARGO], cMsjFinal[LARGO]; int nCantidad, ni, nMatPer, nNumRegistro; //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 2

2007 Ing. Esp. Hector Enrique Guerrero Conde® Todos los derechos reservados. http://clix.to/hegconde


Universidad Cooperativa de Colombia Facultad de ingeniería de Sistemas Estructuras de datos 1 strcpy(cTmpConcepto,"Habilita"); nMatPer++; }//Final de if nTmpDef<3 else {strcpy(cTmpConcepto,"Aprueba");} //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. 3

2007 Ing. Esp. Hector Enrique Guerrero Conde® Todos los derechos reservados. http://clix.to/hegconde


Universidad Cooperativa de Colombia Facultad de ingeniería de Sistemas Estructuras de datos 1 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; 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; 4

2007 Ing. Esp. Hector Enrique Guerrero Conde® Todos los derechos reservados. http://clix.to/hegconde


Universidad Cooperativa de Colombia Facultad de ingeniería de Sistemas Estructuras de datos 1 //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 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 5

2007 Ing. Esp. Hector Enrique Guerrero Conde® Todos los derechos reservados. http://clix.to/hegconde


Universidad Cooperativa de Colombia Facultad de ingeniería de Sistemas Estructuras de datos 1 }//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) {//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 Ing. Esp. Hector Enrique Guerrero Conde® Todos los derechos reservados. http://clix.to/hegconde


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.