C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) OBJETIVOS Explicar la estructura dinámica lista circular. Implementar el TAD lista circular. Utilizar el TAD lista circular para resolver problemas. 4 Msc. Walter Fernandez Toglio. LISTAS ENLAZADAS CIRCULARES 1 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) TEMAS Listas circulares Listas circulares doblemente enlazadas Ejemplos de listas circulares SOFTWARE NECESARIO Dev-C++ 4.9.9.2 http://sourceforge.net/projects/dev-cpp/files/Binaries/ NetBeans IDE C/C++ http://netbeans.org/features/cpp/ Code::Blocks http://www.codeblocks.org/downloads/26 Eclipse C++ http://www.eclipse.org/downloads/packages/eclipse-ide-ccdevelopers-includes-incubating-components/indigosr1 Visual C++ http://www.microsoft.com/visualstudio/eng/products/visual-studioexpress-products Borland C++ http://edn.embarcadero.com/article/20633 Msc. Walter Fernandez Toglio. 2 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) LISTAS ENLAZADAS CIRCULARES (ORDENADAS) El campo de enlace del último nodo apunta al primer nodo de la lista, en lugar de tener el valor NIL No existe ni primer ni último nodo. Tenemos un anillo de elementos enlazados unos con otros EJEMPLO L 70 50 Primero 5 1 5 20 28 30 Es conveniente, aunque no necesario, tener un enlace (puntero o índice) al último nodo lógico de la lista. Así podemos acceder facilmente a ambos extremos de la misma Una lista circular vacía vendrá representada por un valor NIL o Nulo en primero Idealmente No tiene ni principio ni fin. Las Operaciones posibles son las mismas que en las otras listas. Msc. Walter Fernandez Toglio. 3 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) LISTAS ENLAZADAS CIRCULARES (ORDENADAS): DECLARACIÓN FORMAL class nodo { public: nodo(int v,nodo *sig=NULL) { valor=v; siguiente=sig; } private: int valor; L Primero nodo *siguiente; friend class ListaCircular; }; typedef nodo *pnodo; class ListaCircular { public: ListaCircular () { primero=actual=NULL; } ~ ListaCircular (); void Insertar(int v); void Borrar(int v); bool ListaVacia() { return primero==NULL; } void Mostrar(); void Siguiente(); void Primero(); void Ultimo(); bool Actual() { return actual!=NULL; } int ValorActual() { return actual->valor; } private: pnodo primero; pnodo actual; }; Msc. Walter Fernandez Toglio. L primero actual 4 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) LISTAS ENLAZADAS CIRCULARES (ORDENADAS): INSERCIÓN Parámetros: Lista (L) , elemento (e), posición (p) La posición debe ser válida (1 <= p <= (Long(L) + 1) Considerar: Inserción en primera posición, al final de la lista, en lista vacía Procedimiento: 1. Localizar la posición 2. Crear el nodo con el elemento 3. Actualizar los apuntadores involucrados EJEMPLO Dada la siguiente lista enlazada circular, se desea insertar un nodo cuyo valor es 72 EJEMPLO L 70 50 primero 5 20 1 5 28 30 SOLUCIÓN 1 Localizar la posición del nuevo nodo 1. Localizar la posición del nodo a insertar anterior=NULL; aux=primero; do { anterior EJEMPLO primero L anterior=aux; aux = aux->siguiente; }while(aux!=primero && aux->valor<=v); 70 5 Msc. Walter Fernandez Toglio. 1 5 50 20 28 30 5 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) 2. Crear nuevo nodo 72 2. Crear nuevo nodo new nodo(72, anterior->siguiente); 3. Actualizar apuntadores del nuevo nodo 3. Actualizar apuntadores del nuevo nodo anterior->siguiente = new nodo(v, anterior->siguiente); EJEMPLO 72 primero L anterior 70 5 Msc. Walter Fernandez Toglio. 1 5 50 20 28 30 6 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) void ListaCircular::Insertar(int v) { pnodo anterior,n,aux; if (primero==NULL ) { n=new nodo(v,NULL); n->siguiente=n; primero=n; return; } if (primero->valor > v) { anterior=NULL; aux=primero; do { anterior=aux; aux = aux->siguiente; }while(aux!=primero ); n=new nodo(v,primero); primero=n; anterior->siguiente=primero; } else { anterior=NULL; aux=primero; do { anterior=aux; aux = aux->siguiente; }while(aux!=primero && aux->valor<=v); anterior->siguiente = new nodo(v, anterior->siguiente); } } Msc. Walter Fernandez Toglio. 7 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) LISTAS ENLAZADAS CIRCULARES (ORDENADAS): ELIMINACIÓN Parámetros: Lista (L) , elemento (e), posición (p) La posición debe ser válida (1 <= p <= (Long(L)) Considerar: Eliminación en primera posición, al final de la lista Procedimiento: 1. Localizar la posición 2. Actualizar los apuntadores involucrados 3. Liberar el espacio ocupado por el nodo EJEMPLO Dada la siguiente lista enlazada circular, se desea eliminar el nodo cuyo valor es 70 EJEMPLO primero L 70 5 1 5 50 28 20 30 SOLUCIÓN 1. Localizar la posición del nodo a eliminar 1. Localizar la posición del nodo a eliminar EJEMPLO var primero L Msc. Walter Fernandez Toglio. primero ant 70 5 1 5 ant=NULL; var=primero; do { if (var->valor==v) break; ant=var; var=var->siguiente; }while(var!=primero); 50 20 28 30 8 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) 2. Actualizar apuntadores de los nodos EJEMPLO if(var && var->valor==v) { if (ant) ant->siguiente=var>siguiente; else primero=NULL; delete var; } 2. Actualizar apuntadores de los nodos involucrad os var primero L ant 70 5 1 5 50 28 20 30 3. Liberar espacio ocupado por el nodo 3. Liberar espacio ocupado por el EJEMPLO delete var; nodo var primero L ant 70 5 Msc. Walter Fernandez Toglio. 1 5 50 20 28 30 9 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) void ListaCircular::Borrar(int v) { pnodo var,ant; ant=NULL; var=primero; do { if (var->valor==v) break; ant=var; var=var->siguiente; }while(var!=primero); if(var && var->valor==v) { if (ant) ant->siguiente=var->siguiente; else primero=NULL; delete var; } else { if (var && var->valor!=v) { cout<<endl<<"No existe"<<endl; } } } Msc. Walter Fernandez Toglio. 10 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) EJEMPLO: LISTAS ENLAZADAS CIRCULARES Nodo.h #include <stdio.h> class nodo { public: nodo(int v,nodo *sig=NULL) { valor=v; siguiente=sig; } private: int valor; nodo *siguiente; friend class ListaCircular; }; ListaCircular.h #include <iostream> #include "Nodo.h" using namespace std; class ListaCircular { public: ListaCircular() { primero=actual=NULL; } ~ListaCircular(); void Insertar(int v); void Borrar(int v); bool ListaVacia() { return primero==NULL; } void Mostrar(); void Siguiente(); void Primero(); void Ultimo(); bool Actual() { return actual!=NULL; } int ValorActual() { return actual->valor; } private: nodo *primero; nodo *actual; }; ListaCircular::~ListaCircular() Msc. Walter Fernandez Toglio. 11 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) { nodo *aux,*var; aux=primero; aux=aux->siguiente; while(aux!=primero) { var=aux; aux=aux->siguiente; delete var; } delete aux; primero=NULL; } void ListaCircular::Insertar(int v) { nodo *anterior,*n,*aux; if (primero==NULL ) { n=new nodo(v,NULL); n->siguiente=n; primero=n; return; } if (primero->valor > v) { anterior=NULL; aux=primero; do { anterior=aux; aux = aux->siguiente; }while(aux!=primero ); n=new nodo(v,primero); primero=n; anterior->siguiente=primero; } else { anterior=NULL; aux=primero; do { anterior=aux; aux = aux->siguiente; }while(aux!=primero && aux->valor<=v); anterior->siguiente = new nodo(v, anterior->siguiente); } } void ListaCircular::Mostrar() { nodo *aux; aux=primero; do { cout<<aux->valor<<"->"; aux = aux->siguiente; Msc. Walter Fernandez Toglio. 12 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) }while(aux!=primero); cout<<endl; } void ListaCircular::Borrar(int v) { nodo *var,*ant; ant=NULL; var=primero; do { if (var->valor==v) break; ant=var; var=var->siguiente; }while(var!=primero); if(var && var->valor==v) { if (ant) ant->siguiente=var->siguiente; else primero=NULL; delete var; } } Principal.cpp #include <iostream> #include "ListaCircular.h" int main(char *arg) { ListaCircular ObjLista; ObjLista.Insertar(20); ObjLista.Insertar(10); ObjLista.Insertar(45); ObjLista.Insertar(30); ObjLista.Insertar(40); ObjLista.Mostrar(); ObjLista.Borrar(45); cout<<"Borrar 45: "<<endl; ObjLista.Mostrar(); cout<<endl; ObjLista.Insertar(5); cout<<"Insertar 5: "<<endl; ObjLista.Mostrar(); cout<<endl; ObjLista.Insertar(60); cout<<"Insertar 60: "<<endl; ObjLista.Mostrar(); cout<<'\n'; Msc. Walter Fernandez Toglio. 13 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) ObjLista.Borrar(30); cout<<"Borrar 30: "<<endl; ObjLista.Mostrar(); cout<<endl; cout<<"Borrar 45: "<<endl; ObjLista.Borrar(45); ObjLista.Mostrar(); cout<<endl; system("PAUSE"); return 0; } Presione F5 o haga clic en PROPUESTOS Modificar el programa de listas circulares ordenadas para que muestre 3 veces el contenido de la lista circular dentro del método Mostrar. Msc. Walter Fernandez Toglio. 14 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) IV ACTIVIDADES Analizar los siguientes ejemplos. EJEMPLO 1 Agregar un método a la clase lista enlazada para que dadas dos listas enlazadas, realice la concatenación de la primera lista con la segunda, creando una nueva lista. SOLUCIÓN lista* lista::Concatenar(lista *lst) { lista *lstCont=new lista();; nodo *var; var=primero; while(var!=NULL ) { lstCont->Insertar(var->valor); var = var->siguiente; } var=lst->primero; while(var!=NULL ) { lstCont->Insertar(var->valor); var = var->siguiente; } return lstCont; } Principal.cpp #include "ListaEO.h" void main(void) { lista ObjLista1,ObjLista2,*ObjLista3; ObjLista1.Insertar(20); ObjLista1.Insertar(10); ObjLista1.Insertar(45); ObjLista1.Insertar(30); ObjLista1.Insertar(40); ObjLista1.Mostrar(); ObjLista2.Insertar(60); ObjLista2.Insertar(70); ObjLista2.Insertar(80); ObjLista2.Mostrar(); ObjLista3=ObjLista1.Concatenar(&ObjLista2); ObjLista3->Mostrar(); cout<<'\n'; system("pause"); } Msc. Walter Fernandez Toglio. 15 C CE EN NTTR RO OS SU UP PE ER RIIO OR RS SU UP PE ER RIIO OR RD DE EA ALLTTA A E S P E C I A L I Z A C I Ó N Y A S E S O R Í A ESPECIALIZACIÓN Y ASESORÍA http://www.cfape.com P PR RO OG GR RA AM MA AC CIIÓ ÓN NE EN N LLA AP PLLA ATTA AFFO OR RM MA AW WIIN ND DO OW WS S http://www.cfape.com/ E E S T R U C T U R A D E D A T O S N E A E S E N C C C U R S O O N N E ES ST TR RU UC CT TU UR RA AD DE ED DA AT TO OS S LLLIIIN NE EA ALLLE ES SE EN NC C///C C++++++ (((C CU UR RS SO OO ON N---LLLIIIN NE E))) EJEMPLO 2 Agregar un método a la clase lista enlazada para que dadas dos listas enlazadas que se encuentran ordenadas ascendentemente, realice la mezcla de ambas listas de manera que la lista resultante también se encuentre ordenada. SOLUCIÓN EJEMPLO 3 Agregar un método a la clase lista enlazada que vuelque el contenido de un fichero de texto en una lista enlazada. Nota: No usar la función fopen(). SOLUCIÓN EJEMPLO 4 Agregar un método a la clase lista enlazada que invierta una lista, es decir, el primer nodo pasará a ser el último, el segundo pasará a ser el penúltimo… y el último pasará a ser el primero. SOLUCIÓN Msc. Walter Fernandez Toglio. 16