LISTAS ESTRUCTURAS DE DATOS 2006 Prof.
UNIDAD II ESTRUCTURAS DE DATOS LISTAS Definición. Representación de Listas. Lista Lineal Simplemente Enlazada. Operaciones TAD LLSE. Implementación Dinámica. Otras Listas. Ejercicios.
LISTAS DEFINICIÓN Una LISTA es un conjunto ordenado de elementos homogéneos, en la que no hay restricciones de acceso, la introducción y borrado de elementos puede realizarse en cualquier posición de la misma.
LISTAS DEFINICIÓN Cuando hablamos de un conjunto ordenado, nos referimos a la disposición de sus elementos y no a su valor. Esto es que cada uno de ellos, salvo el primero y el último, tienen un anterior y un siguiente. Por otro lado, al decir que los elementos de la lista son homogéneos, queremos decir que son del mismo tipo base, aunque sin establecer ninguna limitación sobre este tipo. Se trata de una estructura dinámica, ya que su tamaño cambia a medida que se añaden y eliminan elementos de la misma.
LISTAS CARACTERÍSTICAS La cantidad reservada de almacenamiento para la pila o la cola es fija. Vimos pilas y colas alojadas en arreglos. Problemas al insertar o eliminar elementos. Una representación secuencial, refleja el orden lógico de los elementos fisicamente almacenados en la lista; el orden físico y lógico son los mismos.
LISTAS CARACTERÍSTICAS Solución a los problemas de movimiento de los datos que se ha encontrado al utilizar representaciones secuenciales. Con la representación no secuencial el orden lógico y físico de los elementos no es necesario que sea el mismo. el orden El orden lógico se representa de tal forma que cada elemento apunta al siguiente elemento, es decir, se encuentran ligados.
LISTA LINEAL SIMPLEMENTE ENLAZADA CARACTERÍSTICAS Lista Info sig Info sig Info sig Info sig Info sig Cada elemento se llama nodo. Se accesa a toda la lista a partir de un apuntador externo llamado Lista que apunta(contiene la dirección de) el primer nodo en la lista. Cada nodo tiene dos secciones: el contenido de datos (Info) y el campo del apuntador (sig). El campo Info(de información) contiene el elemento real en la lista. El campo sig(dirección siguiente) contiene la dirección del siguiente nodo en la lista. Tal dirección se conoce como apuntador. El último nodo tiene un apuntador nulo.
LISTA LINEAL SIMPLEMENTE ENLAZADA CARACTERÍSTICAS Lista Info sig Info sig Info sig Info sig Info sig Cada nodo es una estructura de datos de tipo registro. Los nodos enlazados no tienen que estar fisicamente adyacentes. Una lista vacía es aquella que no contiene nodos. Lista=NULL. Para remover un nodo, sólo es necesario cambiar el apuntador del nodo previo para que apunte al nodo siguiente. Para insertar un nuevo nodo, sólo es necesario cambiar el apuntador del nodo previo para que apunte al nodo nuevo, y el apuntador del nodo nuevo apunte al siguiente.
LISTA LINEAL SIMPLEMENTE ENLAZADA CARACTERÍSTICAS Operacionescon listas: Recorrido de la lista. Inserción de un elemento. Borrado de un elemento. Búsqueda de un elemento.
LISTA LINEAL SIMPLEMENTE ENLAZADA TAD:LISTAS Operaciones: CONSTRUCTORAS Crea una lista vacía. CrearLista: Lista
LISTA LINEAL SIMPLEMENTE ENLAZADA TAD:LISTAS MODIFICADORAS Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento al inicio de la lista. InsertarInicio: Lista x tipo_base Lista Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento al final de lista. InsertarFinal: Lista x tipo_base Lista
LISTA LINEAL SIMPLEMENTE ENLAZADA TAD:LISTAS MODIFICADORAS Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento en un nodo que sigue al nodo apuntado por p. InsertarDespues: Lista x tipo_base Lista Dada una lista, forma la lista resultante de eliminar el elemento situado al principio de la lista (primer elemento). ElimPrim: Lista Lista
LISTA LINEAL SIMPLEMENTE ENLAZADA TAD:LISTAS MODIFICADORAS Dada una lista, forma la lista resultante de eliminar el elemento situado al final de la lista (último elemento). ElimFinal: Lista Lista Dada una lista, forma la lista resultante de eliminar el nodo que sigue al nodo apuntado por p. ElimDespues: Lista Lista
LISTA LINEAL SIMPLEMENTE ENLAZADA TAD:LISTAS ANALIZADORAS Dada una lista, hace el recorrido por la lista mostrando el campo info. RecorrerList: Lista Lista Dada una lista, devuelve el valor verdadero si la lista está vacía y falso en caso contrario. ListaVacia: Lista lógico
LISTA LINEAL SIMPLEMENTE ENLAZADA TAD:LISTAS ANALIZADORAS Dada una lista, devuelve el número de elementos de la lista. LongLista: Lista tipo_base DESTRUCTORA Destruye la lista retornando toda la memoria ocupada. BorrarLista: Lista
LISTA LINEAL SIMPLEMENTE ENLAZADA DEFINICIÓN # define NULL 0 struct lista { tipo_base info; lista *prox; };
LISTA LINEAL SIMPLEMENTE ENLAZADA Con esta definición de Lista las operaciones asociadas especificadas en el TAD quedarían del siguiente modo: Crea una lista vacía int CrearLista(lista **p) { *p=null; };
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento al inicio de la lista. void InsertarInicio(lista **p, tipo_base dato) { lista *n; n=new lista; n->info=dato; n->prox=*p; *p=n; };
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento al final de lista. void InsertarFinal(lista **p, tipo_base dato) { lista *n,*m; }; m=*p; while(m->prox!=null) m=m->prox; n=new lista; n->info=dato; n->prox=null; m->prox=n;
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento en un nodo que sigue al nodo apuntado por p. void InsertarDespues(lista **p,tipo_base dato) {lista *q; if (p==null) { cout<<" Evite Inserción"; exit(1); } else { q=new lista; q->info=dato; q->prox=(*p)->prox; (*p)->prox=q; } };
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista, forma la lista resultante de eliminar el elemento situado al principio de la lista (primer elemento). void ElimPrim(lista**p) { lista *n; }; n=*p; *p=(*p)->prox; delete n;
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista, forma la lista resultante de eliminar el elemento situado al final de la lista (último elemento). void ElimFinal(lista **p) { lista *n,*m; }; if ((*p)->prox==null) { *p=null; delete *p; } else n=*p; while(n->prox!=null) { m=n; } n=n->prox; m->prox=null; delete n;
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista, forma la lista resultante de eliminar el nodo que sigue al nodo apuntado por p. void ElimDespues(lista **p) { lista *q; }; if (p==null) { cout<<" Evite Eliminar"; else } exit(1); } { q=(*p)->prox; if (q==null) else { cout<<" Nodo no existe "; exit(1); } { (*p)->prox=q->prox; delet (q); }
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista, hace el recorrido por la lista mostrando el campo info. void RecorrerList(lista **p) { lista *q; q=*p; while (q!=null) { cout<<q->info<<" "; } q=q->prox; };
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista, devuelve el valor verdadero si la lista está vacía y falso en caso contrario. int ListaVacia(lista **p) { if (p=null); return (1) else return (0); };
LISTA LINEAL SIMPLEMENTE ENLAZADA Dada una lista, devuelve el número de elementos de la lista. int LongLista(lista **p) { lista *q; int conta=0; }; q=*p; while (q!=null) { conta=conta+1; q=q->prox; } return (conta);
LISTA LINEAL SIMPLEMENTE ENLAZADA Destruye la lista retornando toda la memoria ocupada. void BorrarLista(lista **p) { while((*p)->prox!=0) *p=(*p)->prox; } delete *p;
LISTA LINEAL DOBLEMENTE ENLAZADA Uno de los problemas que plantea la implementación dinámica mediante enlace simple es el coste de insertar y borrar nuevos elementos en la lista. En varios casos es necesario recorrerla desde el principio para poder acceder al elemento anterior al dado como parámetro. Además, tan sólo es posible recorrer la lista así enlazada en una sola dirección. Para solucionar ambos problemas se puede utilizar una lista lineal doblementa enlazada.
LISTA LINEAL DOBLEMENTE ENLAZADA DEFINICIÓN Una lista doblemente enlazada es una colección de nodos, en la cual cada nodo contiene dos apuntadores uno a su antecesor y otro a su sucesor. Las listas doblemente enlazadas pueden ser lineales, circulares y pueden contener o no un nodo de encabezado. Los nodos de una lista doblemente enlazada contiene tres campos: un campo info que contiene la información almacenada en el nodo, y los campos izq y der que contienen apuntadores a nodos en alguno de los dos lados. Ver figura.
LISTA LINEAL DOBLEMENTE ENLAZADA DEFINICIÓN Izq info der Izq info der Izq info der Izq info der info : contiene la información almacenada en el nodo. izq y der : contienen apuntadores a nodos en alguno de los dos lados.
LISTA LINEAL DOBLEMENTE ENLAZADA DEFINICIÓN # define NULL 0 struct lista { lista *izq; tipo_base info; lista *der; };
LISTA LINEAL DOBLEMENTE ENLAZADA Crea una lista vacía int CrearListaD(lista **p) { *p=null; }
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento al inicio de la lista. void InsertPrincD(lista **p, tipo_base k) { lista *n; }; n=new lista; n->izq=null; n->info=k; n->der=*p; (*p)->izq=n; *p=n;
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento al final de la lista. void InsertUltD(lista **p, tipo_base k) { lista *n,*m; m=*p; while(m->der!=null) { m=m->der; } n=new lista; n->info=k; n->der=null; m->der=n; n->izq=m; };
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento a la izquierda del nodo apuntado por p. void InsertIzqD(lista **p, tipo_base k) { lista *n,*m,*q; q=*p; n=new lista; n->info=k; n->izq=q->izq; n->der=q; if (q->izq!=null) { m=q->izq; m->der=n; } else p=n; q->izq=n; };
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista y un valor e, del tipo base, forma una nueva lista al añadir el elemento a la derecha del nodo apuntado por p. void InsertDerD(lista **p, tipo_base k) { lista *n,*m,*q; q=*p; n=new lista; n->info=k; if (q==null) { n->izq=null; n->der=null; q=n; } else { m=q->der; if (m!=null) m->izq=n; n->der=m; n->izq=q; q->der=n; } };
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista, forma la lista resultante de eliminar el elemento situado al principio de la lista (primer elemento). void ElimPrimcD(lista **p) { lista *n; }; n=*p; *p=(*p)->der; (*p)->izq=null; delete n;
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista, forma la lista resultante de eliminar el elemento situado al final de la lista (último elemento). void ElimUltD(lista **p) { lista *n,*m; n=*p; while(n->der!=null) { n=n->der; } m=n->izq; m->der=null; delete n; };
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista, forma la lista resultante de eliminar el elemento situado a la derecha del nodo apuntado por p. void ElimDerD(lista**p) { lista *q,*n,*m; } q=*p; n=q->der; if (n==null) {cout << Evite eliminar ; exit(1); } else { q->der=n->der; m=n->der; m->izq=n->izq; delete n;}
LISTA LINEAL DOBLEMENTE ENLAZADA Dada una lista, forma la lista resultante de eliminar el elemento situado a la izquierda del nodo apuntado por p. void ElimIzqD(lista**p) { lista *q,*n,*m; q=*p; n=q->izq if (n == NULL) {cout << Evite eliminar ; exit(1); } else {q->izq=n->izq; m=n->izq; m->der=q; delete n; } }
LISTAS CIRCULARES La lista encadenada circular es una ligera variante de la lista encadenada lineal; se obtiene al considerar el primer nodo de la lista como el sucesor del último nodo, almacenando la dirección del primer elemento en el campo de dirección del último, en lugar de almacenar la dirección nula. Al realizar esta modificación se genera automáticamente un círculo, donde realmente ya no existe ni el primero ni un último elemento.
LISTAS CIRCULARES CARACTERÍSTICAS Es necesario mantener un apuntador general a la estructura (Lista), aunque ya no apunte obligatoriamente al primer elemento. La dirección nula no existe en la lista, excepto cuando la lista está vacía. Si la lista contiene un solo elemento, el campo de dirección apuntará a ese mismo nodo. Como la lista es un círculo, es posible llegar a cualquier nodo de la lista a partir de cualquiera de sus nodos.
LISTAS CIRCULARES CARACTERÍSTICAS Ver figura. Info sig Info sig Info sig Info sig Info sig Lista Circular Simplemente Enlazada
LISTA CIRCULAR SIMPLEMENTE ENLAZADA DEFINICIÓN # define NULL 0 struct ListaCirc { tipo_base info; ListaCirc *prox; };
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Crea una lista circular vacía int CrearListaCSE(lista **p) { *p=null; }
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Dada una lista circular y un valor e, del tipo base, forma una nueva lista circular al añadir el elemento al iniciar la lista. void InsertarLCSE(ListaCirc **p, int dato) { ListaCirc *q; q=new ListaCirc; q->info=dato; *p=q; q->prox=*p; }
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Dada una lista circular y un valor e, del tipo base, forma una nueva lista circular al añadir el elemento después del nodo apuntado por p. void InsertarDespLCSE(ListaCirc **p, int dato) { ListaCirc *n,*q; n=*p; } q=new ListaCirc; q->info=dato; q->prox=n->prox; n->prox=q; *p=q;
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Dada una lista circular, forma la lista circular resultante de eliminar el nodo que sigue al nodo apuntado por p. void EliminarDespLCSE(ListaCirc **p) { ListaCirc *q; } if ((*p)==null){ cout<< "Evitar Eliminar"; //exit(1); } else{ q=(*p)->prox; (*p)->prox=q->prox; delete(q); }
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Dada una lista circular, devuelve el valor verdadero si la lista circular está vacía y falso en caso contrario. int ListaVaciaCSE(lista **p) { if (p=null); return (1) else return (0); };
LISTA CIRCULAR SIMPLEMENTE ENLAZADA { Dada una lista circular, hace el recorrido por la lista circular mostrando el campo info. void ReccorrerListaCircSE (ListaCirc **p) ListaCirc *q,*z; z=*p; } q=z->prox; while (q!=z) { cout<< q->info <<" "; q=q->prox; } cout << q->info <<" ";
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Dada una lista circular, devuelve el número de elementos de la lista. int LongListaCirc (ListaCirc *p) { ListaCirc *r,*q; int cont; } cont=0; r=null; q=p->prox; while (q!=r) { if(r==null) r=q; cont=cont+1; q=q->prox; } return (cont);
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Destruye la lista circular retornando toda la memoria ocupada. void BorrarListaCSE (ListaCirc **p) { ListaCirc *q; } q=*p; q=q->prox; delete (q);
LISTA CIRCULAR SIMPLEMENTE ENLAZADA Imprime cada nodo de información de la lista circular. void ImprimirListaCSE(ListaCirc *L1) { ListaCirc *r,*p; r=null; p=l1->prox; } while (r!=p) { if (r==null) r=p; cout << p->info <<" "; p=p->prox; }
Función que concatena dos listas circulares simplemente enlazadas. ListaCirc *concatenarcse(listacirc **p, ListaCirc**q) { ListaCirc *n,*m,*r; n=*p; m=*q; if (n==null) n=m; } else if(m!=null) { r=n->prox; n->prox=m->prox; m->prox=r; n=m; } return n;
GRACIAS POR SU ATENCIÓN HASTA LA PRÓXIMA CLASE