Anda di halaman 1dari 26

Estrategias

de programacin y estructuras de datos


Grado en Ingeniera Inform8ca
Grado en Tecnologas de la Informacin

Departamento de Lenguajes y Sistemas inform6cos

Tipos abstractos de
datos lineales
Listas

Javier Vlez Reyes Jos Ignacio Mayorga Toledano


jvelez@lsi.uned.es
nmayorga@lsi.uned.es
Departamento de Lenguajes Y Sistemas InformDcos
UNED

Tipos abstractos de datos lineales. Listas


ndice

ndice

Tipos abstractos de datos lineales

El tipo abstracto de datos lista

Interfaz del tipo abstracto de datos lista

Implementaciones del tipo abstracto de datos lista

4-2

Introduccin

Implementacin dinmica

Implementacin esttica

Algoritmos sobre listas

Recorrido de los elementos de una lista

Bsqueda de un elemento sobre una lista

Ordenacin de los elementos de una lista

Ejercicios

Bibliografa

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Obje6vos generales

Obje8vos

Comprender que son los tipos abstractos de datos lineales

Conocer la interfaz del tipo abstracto de datos Lista

Aprender a implementar el TAD Lista mediante la interfaz ListIF

4-3

En versin esttica (con limitacin explcita de capacidad mxima)

En versin dinmica (sin limitacin explcita de capacidad mxima)

Conocer los principales problemas algortmicos sobre listas

Recorrido de los elementos de una lista

Bsqueda de un elemento sobre una lista

Ordenacin de los elementos de una lista

Practicar el diseo de funciones recursivas sobre listas

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Introduccin

Tipos abstractos de datos lineales


Los 6pos abstractos de datos lineales representan abstracciones en las que los datos son
organizados de forma secuencial. A con6nuacin se muestran los diferentes TADs que caen
dentro de esta categora y que se diferencian, esencialmente, en la forma en que ofrecen
acceso a sus datos
I. Listas
Tema 4

Tema 5

Tipos abstractos
de datos lineales

El tipo abstracto de datos Lista representa una estructuras de datos


donde los elementos se disponen de forma secuencial y las
operaciones de insercin y extraccin se aplican por el principio,
que puede moverse recursivamente haciendo referencia a otras
sublistas

Tema 6

II. Pilas
El tipo abstracto de dato Pila representa una estructuras de datos
donde los elementos se disponen de forma secuencial y las
operaciones de insercin y extraccin se aplican por el principio
segn la poltica de acceso ltimo en entrar, primero en salir

III. Colas
El tipo abstracto de dato Cola representa una estructuras de datos
donde los elementos se disponen de forma secuencial y las
operaciones de insercin y extraccin se aplican por el final y por el
principio respectivamente de acuerdo a la poltica de primero en
entrar, primero en salir

4-4

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Introduccin

El 8po abstracto de datos lista


Las listas son abstracciones de datos que organizan una coleccin de elementos de manera
secuencial, donde a cada elemento le sigue un nico elemento siguiente. La denicin del
6po es recursiva lo que condiciona su forma de acceso. Una lista de tamao n se dene
como un primer elemento accesible seguido de una lista de tamao n 1 tambin accesible
Una lista es un 6po abstractos de datos que organiza una coleccin de elementos
de forma secuencial. Su denicin recursiva dis6ngue una cabeza y un resto de
lista ambos accesibles. Las inserciones se realizan por delante de la cabeza
Resto
El resto de elementos son accesibles
a travs de la lista resto que es de
tamao un elemento menor

Primero
Toda lista no vaca
distingue un primer
elemento que
puede ser operado
directamente

2 3 4 5 6 7 8 9

Lista
La definicin de la lista como un par (primero, resto) induce un
acceso recursivo a la misma donde los elementos se acceden por
la cabeza (posicin del primero) y para llegar al elemento i-esimo
hay que recorrer los i-1 elementos anteriores

4-5

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Interfaz del 6po abstracto de datos Lista

La interfaz del 8po abstracto de datos Lista ListIF <T>


El interfaz de listas que u6lizaremos a lo largo de este
curso, ListIF esta compuesto por las operaciones que
describimos a con6nuacin
Primero y resto

1
1

2 3

Las operaciones primero y restos son los


principales mtodos de acceso recursivo a los
elementos de la lista. Se trata de operaciones
consultoras que no modifican el estado de tipo

Insertar

2 3

La operacin de insercin aade un elemento


delante de la cabeza de la lista. Junto con la
ordenacin, es la nica operacin modificadora

Est llena y est vaca


Los predicados lgicos isEmpty y isFull indican el estado de la lista
en relacin con el nmero de elementos que contiene. isEmpty
devuelve cierto si la lista no contiene elementos. En este caso
getFirst devuelve null y getTail devuelve la propia lista vaca. En
implementaciones con capacidad isFull devuelve cierto si el
numero de elemento ha llegado a la capacidad. En
implementaciones dinmicas siempre devuelve falso

4-6

public interface ListIF<T>


{
/**
* Devuelve la cabeza de una lista.
* @return la cabeza de una lista.
*/
public T getFirst ();

/**
* Devuelve la lista excluyendo la cabeza.
* @return la lista excluyendo la cabeza.
*/
public ListIF<T> getTail ();

/**
* Inserta un nuevo elemento a la lista.
* @param element El elemento a aadir.
* @return la lista incluyendo el elemento.
*/
public ListIF<T> insert (T element);

/**
* Devuelve cierto si la lista esta vacia.
* @return cierto si la lista esta vacia.
*/
public boolean isEmpty ();

/**
* Devuelve cierto si la lista esta llena.
* @return cierto si la lista esta llena.
*/
public boolean isFull();

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Interfaz del 6po abstracto de datos Lista

La interfaz del 8po abstracto de datos Lista ListIF <T>


El interfaz de listas que u6lizaremos a lo largo de este
curso, ListIF esta compuesto por las operaciones que
describimos a con6nuacin
/**

Longitud * Devuelve el numero de elementos de la lista.

* @return el numero de elementos de la lista.


*/
public int getLength ();


Recorrido /**
* Devuelve un iterador para la lista.
Devuelve un iterador que permite
* @return un iterador para la lista.
lista
recorrer los elementos de la lista en el */
orden en que aparecen. Esta operacin public IteratorIF<T> getIterator ();
no es modificadora del tipo

/**
* Devuelve cierto si la lista contiene el elemento.
Iterador de elementos
Con8ene * @param element El elemento buscado.
* @return cierto si la lista contiene el elemento.
El predicado contiene realiza una bsqueda sobre los elementos */
de la lista para comprobar si cierto dato pasado como parmetro public boolean contains (T element);
est incluido entre ellos

/**
Ordenar * Ordena los elementos de la lista.
* @param element El comparador de elementos.
Ordena los elementos de la lista de * @return la lista ordenada.
antes
a c u e r d o a l c r i t e r i o d e o r d e n */
implementado en el comparador. Es una public ListIF<T> sort (ComparatorIF<T> comparator);
despus
operacin modificadora


}

La longitud de la lista se refiere al nmero de elementos que


sta contiene. Este mtodo junto con los dos anteriores son las
herramientas necesarias para identificar los casos base en la
estructura recursiva

3 1 2

3 1 2
1 2 3

4-7

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Implementacin del 6po abstracto de datos Lista

Implementacin del 8po abstracto de datos Lista ListIF <T>


Existen varias estrategias para implementar listas que respondan al interfaz ListIF anterior.
En general, stas se dividen en implementaciones dinmicas, que ar6culan listas de
capacidad indenida e implementaciones est6cas, con una capacidad mxima limitada y
establecida como parmetro. Aqu presentamos un ejemplo de cada caso

Implementacin dinmica basada en primero y siguiente


Segn esta estrategia de implementacin, una lista est formada por un atributo que
representa la cabeza y otro que es una referencia a una lista que representa el resto de la
lista. De esta manera una lista es una coleccin encadenada de pares (primero, resto).
Lista

Primero y resto

Ul8mo, elemento fantasma

Cada objeto Lista contiene un atributo para


representar el elemento en cabeza de lista y un
atributo del tipo definido ListIF que representa
una referencia al resto de elementos tras la
cabeza

4-8

La lista es una secuencia


de pares (primero, resto)
acabada en un par
fantasma

Aunque en otras implementaciones la cabeza


del ltimo objeto se aprovecha para incluir un
ultimo elemento aqu el final se marca con un
objeto fantasma con ambos atributos a null.
Esto evita excepciones de puntero a null y
simplifica la algoritmia con la lista a un nico
caso base isEmpty ()

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Implementacin del 6po abstracto de datos Lista

Implementacin dinmica basada en primero y siguiente


Segn esta estrategia de implementacin, una lista esta formada por un atributo que
representa la cabeza y otro que es una referencia a una lista que representa el resto de la
lista. De esta manera una lista es una coleccin encadenada de pares (primero, resto).
public class ListDynamic<T> implements ListIF<T> *
{
private T first;
private ListIF<T> tail;

public ListDynamic ()
{
first = null;
tail = null;
}

public ListDynamic (ListIF<T> list)
{
this ();
if (list != null)
if (!list.isEmpty ())
{
first = list.getFirst ();
tail = new ListDynamic<T> (list.getTail ());
}
}

@Override
public T getFirst ()
{
return first;
}

@Override
public ListIF<T> getTail ()
{
if (isEmpty ()) return this;
return tail;
}

@Override
public ListIF<T> insert (T element)
{
if (element != null) {
ListDynamic<T> next = new ListDynamic<T>();
next.first = first;
next.tail = tail;
first = element;
tail = next;
}
return this;
}

@Override
public boolean isEmpty ()
{
return first == null &&
tail == null;
}

@Override
public boolean isFull () {
return false;
* Los comentarios
}

de las cabeceras se
han omitido por cuestiones de espacio

4-9

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Implementacin del 6po abstracto de datos Lista

Implementacin dinmica basada en primero y siguiente


Segn esta estrategia de implementacin, una lista esta formada por un atributo que
representa la cabeza y otro que es una referencia a una lista que representa el resto de la
lista. De esta manera una lista es una coleccin encadenada de pares (primero, resto).
@Override
public int getLength ()
{
if (isEmpty ()) return 0;
else return 1 + tail.getLength ();
}

@Override
public IteratorIF<T> getIterator ()
{
ListIF<T> handler = new ListDynamic<T> (this);
return new ListIterator<T> (handler);
}

@Override
public boolean contains (T element) {
...
}

@Override
public ListIF<T> sort (ComparatorIF<T> comparator) {
...
}

@Override
public int hashcode () {
return 31 * ((first == null) ? 0 : first.hashCode ())
+ ((tail == null) ? 0 : tail.hashCode ());
}

@Override
public boolean equals (Object o)
{
if (o == this) return true;
if (o == null) return false;

if (!(o instanceof ListDynamic)) return false;
else {
ListDynamic<T> l = (ListDynamic<T>) o;
return l.first.equals (first) &&
l.tail.equals (tail);
}
}

@Override
public String toString ()
{
StringBuffer buff = new StringBuffer ();
buff.append ("ListDynamic - [");

IteratorIF<T> listIt = getIterator ();
while (listIt.hasNext ()) {
T element = listIt.getNext ();
buff.append (element);
if (listIt.hasNext ())
buff.append (", ");
}

buff.append ("]");
return buff.toString ();
}

* Los comentarios de las cabeceras se


han omitido por cuestiones de espacio

4 - 10

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Implementacin del 6po abstracto de datos Lista

Implementacin del 8po abstracto de datos Lista ListIF <T>


Existen varias estrategias para implementar listas que respondan al interfaz ListIF anterior.
En general, stas se dividen en implementaciones dinmicas, que ar6culan listas de
capacidad innita e implementaciones est6cas, con una capacidad mxima limitada y
establecida como parmetro. Aqu presentamos un ejemplo de cada caso

Implementacin est8ca basada en array


Segn esta estrategia de implementacin, una lista est cons6tuida por un array de
capacidad limitada y especicada mediante parmetro y un ndice que apunta a la
cabeza de la lista. La lista empieza por el nal y crece hacia la primera posicin del array
Basura
El resto de elementos del
array que no pertenecen a la
lista es basura resultado del
trabajo con el tipo

0 0 0 0 3 7 1 2 3 4
Insertar

Las inserciones mueven la


cabeza una posicin hacia atrs
e insertan el elemento. Si
Primero llega a valer 0 la lista
est llena y no se puede insertar

4 - 11

Lista

Capacidad = 10

Primero
Este ndice apunta siempre
al elemento que se
encuentra en cabeza de la
lista. El ndice comienza en
0 y llega hasta capacidad1
para valores de la lista

La lista est formada por los


elementos que van desde la
posicin Primero hasta
Capacidad - 1

Resto
Acceder al resto mueve la cabeza una posicin
hacia delante con lo que sta pasa a ser el
primero del resto. Si Primero llega a valer la
capacidad indica que la lista es vaca. Para que
la operacin no sea modificadora esta
implementacin requiere la copia preliminar de
la estructura.

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Implementacin del 6po abstracto de datos Lista

Implementacin est8ca basada en array


Segn esta estrategia de implementacin, una lista est cons6tuida por un array de
capacidad limitada y especicada mediante parmetro y un ndice que apunta a la
cabeza de la lista. La lista empieza por el nal y crece hacia la primera posicin del array
public class ListStatic<T> implements ListIF<T> *
{
private Object[] elements;
private int capacity;
private int first;

public ListStatic (int capacity)
{
this.capacity = capacity;
this.first = capacity;
this.elements = new Object[capacity];
}

public ListStatic (ListIF<T> list)
{
if (list != null) {
this.capacity = list.getLength ();
this.first = this.capacity;
this.elements = new Object[this.capacity];

ListIF<T> aList = list;
for (int i = capacity-list.getLength (); i <
capacity ; i++) {
this.elements [i] = aList.getFirst ();
this.first = this.first - 1;
aList = aList.getTail ();
}
}
}

4 - 12

private ListIF<T> copy (ListStatic<T> list) {


ListStatic<T> l = new ListStatic<T> (capacity);
l.first = list.first;
l.elements = list.elements;
return l;
}

public T getFirst () {
if (isEmpty ()) return null;
return (T) elements [first];
}

public ListIF<T> getTail () {
if (!isEmpty ()) {
ListStatic<T> tail = (ListStatic<T>) copy (this);
tail.first = first + 1;
return tail;
}
return this;
}

public ListIF<T> insert (T element) {
if (!isFull ()) {
first = first - 1;
elements [first] = element;
}
return this;
}

* Los comentarios de las cabeceras se


han omitido por cuestiones de espacio

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Implementacin del 6po abstracto de datos Lista

Implementacin est8ca basada en array


Segn esta estrategia de implementacin, una lista est cons6tuida por un array de
capacidad limitada y especicada mediante parmetro y un ndice que apunta a la
cabeza de la lista. La lista empieza por el nal y crece hacia la primera posicin del array
@Override
public boolean isEmpty ()
{
return first == capacity;
}

@Override
public boolean isFull()
{
return first == 0;
}

@Override
public int getLength ()
{
return capacity - first;
}

@Override
public IteratorIF<T> getIterator ()
{
ListIF<T> handler = new ListStatic<T> (capacity, this);
return new ListIterator<T> (handler);
}

@Override
public boolean contains (T element) { ... }

@Override
public ListIF<T> sort (ComparatorIF<T> comparator) { ... }

4 - 13

@Override
public int hashCode () {
return 31 * 31 * ((elements == null) ? 0 : elements.hashCode ()) +
31 * capacity + first;
}

@SuppressWarnings("unchecked")
@Override
public boolean equals (Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass () != this.getClass ()) return false;
else { ListStatic<T> l = (ListStatic<T>) o;
return l.elements.equals (elements) &&
l.capacity == capacity &&
l.first == first; }
}

@Override
public String toString ()
{
StringBuffer buff = new StringBuffer ();
buff.append ("ListStatic - [");
IteratorIF<T> listIt = getIterator ();
while (listIt.hasNext ()) {
T element = listIt.getNext ();
buff.append (element);
if (listIt.hasNext ())
buff.append (", ");
}
* Los comentarios de las cabeceras se
buff.append ("]");
return buff.toString (); } } han omitido por cuestiones de espacio

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Algoritmos sobre listas


Estudiaremos 3 6pos de problemas recurrentes sobre la interfaz de listas ListIF: recorrido
de los elementos de una lista, bsqueda de un elemento entre los elementos de una lista y
ordenacin ascendente de los elementos de una lista. La denicin recursiva del 6po
condiciona las estrategias algortmicas que pueden u6lizarse.
I. Recorrido
El recorrido de los elementos de una lista devuelve un iterador que permite
procesarlos secuencialmente segn aparecen almacenados en la estructura.
Como la definicin es recursiva solo el recorrido directo ser estudiado. El
recorrido inverso es fcilmente implementable y se deja como ejercicio

Algoritmos
sobre listas

La bsqueda de un elemento sobre los elementos de una lista se realiza de


forma secuencial dada la definicin recursiva del tipo lo que imprime un coste
lineal al algoritmo. Se estudiar el predicado de contencin dejando como
ejercicio la bsqueda del mnimo y el mximo

III. Ordenacin
La ordenacin de los elementos de una lista, reorganiza sus elementos de
forma que se dispongan ascendentemente de acuerdo a cierto criterio de
comparacin que se recibe como parmetro. En este captulo estudiaremos
dos conocidos mtodos de ordenacin en listas: ordenacin por insercin
(insert sort) y ordenacin por mezcla (merge sort).La ordenacin
descendente es similar y se deja como ejercicio.

4 - 14

Independencia de la
implementacin

II. Bsqueda

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Recorrido de los elementos de una lista


Antes de pasar a discu6r las estrategias de recorrido de los elementos de una lista debemos
presentar el interfaz IteratorIF. Esta interfaz ser u6lizada a lo largo del curso para ar6cular
el recorrido de los elementos de los diferentes 6pos abstractos de datos que vayamos
estudiando

La Interfaz IteratorIF <T>


public interface IteratorIF<T>
{
/**
* Devuelve el siguiente elemento de la iteracion.
* @return el siguiente elemento de la iteracion.
*/
public T getNext ();

/**
* Indica si hay ms elemento en la iteracin.
* @return true si hay ms elemento en la iteracin
*/
public boolean hasNext ();

/**
* Restablece el iterador para volver al inicio.
*/
public void reset ();
}

4 - 15

getNext ()
Devuelve el siguiente elemento dentro de
la iteracin o null si el iterador alcanz el
final

hasNext ()
Este predicado indica si existen ms
elementos an sin visitar dentro de la
iteracin

reset ()
Este mtodo, incluido por razones de
eficiencia, permite resetear el iterador
para que vuelva al principio sin que sea
necesario construirlo de nuevo

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Recorrido de los elementos de una lista


Para ar6cular el recorrido secuencial de los elementos de una lista debe implementarse el
interfaz IteratorIF. Las implementaciones de ListIF anteriores construyen una copia de la
lista como manejador para garan6zar que la iteracin no modique el estado del 6po
class ListIterator<T> implements IteratorIF<T>
{
private ListIF<T> handler;
Iteracin con reset
private ListIF<T> restart;
Se mantienen 2 manejadores constantemente,

/**
uno para articular el recorrido de la lista. El otro
* Constructor para ListIterator.
siempre apunta a la cabeza de la lista y se utiliza
* @param handler el manejador de listas.
para implementar la operacin de reset del
*/
public ListIterator (ListIF<T> handler)
iterador
restart
{
this.handler = handler;
this.restart = handler;
}

/**
* Devuelve el siguiente elemento de la iteracion.
* @return el siguiente elemento de la iteracion.
*/
getNext()
@Override
handler
public T getNext ()
Avance
{
T next = handler.getFirst ();
La operacin de avance devuelve el elemento en
handler = handler.getTail ();
cabeza de la lista y actualiza el manejador de
return next;
recorrido para que apunte a la cabeza del resto
}

de la lista. Para invocar esta operacin con

1 2 3 4

seguridad hay que asegurarse de que el


manejador no apunta a la lista vaca

4 - 16

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Recorrido de los elementos de una lista


Para ar6cular el recorrido secuencial de los elementos de una lista debe implementarse el
interfaz IteratorIF. Las implementaciones de ListIF anteriores construyen una copia de la
lista como manejador para garan6zar que la iteracin no modique el estado del 6po
/**
* Devuelve cierto si existen mas elementos a iterar.
* @return cierto si existen mas elementos a iterar.
*/
@Override
public boolean hasNext ()
{
return !handler.isEmpty ();
}

/**
* Restablece el iterador para volver al inicio.
*/
@Override
public void reset ()
{
handler = restart;
}

@Override
public int hashCode () { ... }

@Override
public boolean equals (Object o) { ... }

@Override
public String toString () {...}
}

Hay siguiente
Para saber si el iterador contiene ms elementos y por
tanto puede volver a invocarse la operacin de avance o
no hay que preguntar si el manejador ha alcanzado el final
de la lista

Reset
Una vez que un iterador ha llegado a su fin slo se puede
construir otro iterador, lo cual es costoso ya que requiere
una nueva copia del tipo, o volverlo a colocar en su
posicin inicial, Gracias a la copia del manejador que
hicimos en el constructor del iterados, esta operacin tiene
un coste constante

restart

1 2 3 4
reset()
handler

4 - 17

handler

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Bsqueda de un elemento sobre una lista


La bsqueda de un dato sobre los elementos contenidos en una lista es un problema de
recorrido secuencial que termina cuando se encuentra una cabeza que corresponde con el
dato buscado. En este sen6do puede aplicarse un algoritmo recursivo o aprovechar el
iterador anterior para resolverlo itera6vamente mediante bsqueda con cen6nela

Bsqueda itera8va con cen8nela


En la bsqueda con cen6nela se itera sobre
la lista y se u6liza una guarda (cen6nela)
para indicar el momento en que se ha
encontrado el elemento y la bsqueda
puede parar
/**
* Devuelve cierto si la lista contiene el elemento.
* @param element El elemento buscado.
* @return cierto si la lista contiene el elemento.
*/
@Override
public boolean contains (T element)
{
IteratorIF<T> listIt = this.getIterator ();
boolean found = false;
while (!found && listIt.hasNext ()) {
T anElement = listIt.getNext ();
found = anElement.equals (element);
}
return found;
}

4 - 18

Bsqueda recursiva
En la bsqueda recursiva se comprueba si la
cabeza se corresponde con el elemento
buscado. Si es as el algoritmo termina
devolviendo cierto y si no, se recurre sobre
el resto de la lista para buscar el elemento
/**
* Devuelve cierto si la lista contiene el elemento.
* @param element El elemento buscado.
* @return cierto si la lista contiene el elemento.
*/
@Override
public boolean contains (T element)
{
if (isEmpty ()) return false;
return first.equals (element) ||
tail.contains (element);
}

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Ordenacin de los elementos de una lista


Antes de discu6r los algoritmos de ordenacin debemos presentar dos artefactos que sern
u6lizados a lo largo del curso en la ordenacin de 6pos abstractos de datos. Como los 6pos
son genricos es necesario proporcionar una implementacin del criterio de orden que
debe aplicarse entre dos elementos cualesquiera del mismo 6po

La Interfaz ComparatorIF <T>

4 - 19

/**
* Indica si un elemento es igual que otro.
* @param e1 el primer elemento.
* @param e2 el segundo elemento.
* @return true si un elemento es igual que otro.
*/
public boolean isEqual (T e1, T e2);

/**
* Indica si un elemento es mayor que otro.
* @param e1 el primer elemento.
* @param e2 el segundo elemento.
* @return true si un elemento es mayor que otro.
*/
public boolean isGreater (T e1, T e2);
}

public interface ComparatorIF<T>


{
public static int LESS = -1;
public static int EQUAL = 0;
public static int GREATER = 1;

/**
* Compara dos elementos para indicar si el primero es
* menor, igual o mayor que el segundo elemento.
* @param e1 el primer elemento.
* @param e2 el segundo elemento.
* @return el orden de los elementos.
*/
public int compare (T e1, T e2);

/**
* Indica si un elemento es menor que otro.
* @param e1 el primer elemento.
* @param e2 el segundo elemento.
* @return true si un elemento es menor que otro.
*/
public boolean isLess (T e1, T e2);

Tambin se utilizar una clase abstracta


ComparatorBase que implementa esta interfaz.
En ella, el primer mtodo es abstracto y el resto
se implementa delegando en ste.

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Ordenacin de los elementos de una lista


Los algoritmos de ordenacin que pueden aplicarse sobre listas, son rela6vamente pocos,
en comparacin con los que pueden aplicarse sobre estructuras de indexacin. En concreto
nosotros discu6remos en este captulo la ordenacin por insercin y la ordenacin por
mezcla

Ordenacin por insercin

Comparator

/**
Se proporciona un comparador cuya
* Ordena los elementos de la lista.
implementacin codifica el criterio de orden entre
* @param comparator El comparador de elementos.
dos elementos de la lista
* @return la lista ordenada.
*/
@Override
Ordenacin
public ListIF<T> sort (ComparatorIF<T> comparator)
{
Si la lista es vaca se devuelve sta. Sino, se
if (isEmpty ()) return this;
ordena el resto de la lista recursivamente y se
else return ((ListDynamic<T>) tail.sort (comparator))
.sortInsert (first, comparator);
inserta en ella el primer elemento en la posicin
}
adecuada segn el criterio de orden

/**
* Inserta un elemento en orden en una lista ordenada.
* @param element El elemento a insertar
* @param comparator El comparador de elementos.
* @return la lista ordenada.
*/
private ListIF<T> sortInsert (T element, ComparatorIF<T> comparator)
Insercin en orden
{
if (isEmpty ()) return this.insert (element);
Si la lista es vaca se devuelve. Si no, si el
else if (comparator.isLess (element, first))
elemento es menor que el primero, se inserta por
return this.insert(element);
el principio. Si no, se inserta en el resto el
else return ((ListDynamic<T>) tail)
.sortInsert (element, comparator).insert (first);
elemento a insertar
}

5 7 3 2

4 - 20

2 3

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Ordenacin de los elementos de una lista


Los algoritmos de ordenacin que pueden aplicarse sobre listas, son rela6vamente pocos,
en comparacin con los que pueden aplicarse sobre estructuras de indexacin. En concreto
nosotros discu6remos en este captulo la ordenacin por insercin y la ordenacin por
mezcla

Ordenacin por mezcla


/**
* Ordena los elementos de la lista.
* @param element El comparador de elementos.
* @return la lista ordenada.
*/
@Override
public ListIF<T> sort (ComparatorIF<T> comparator)
{
if (getLength () <= 1) return this;
else {
int middle = (int) (getLength () / 2);
int index = 0;
ListIF<T> lLeft = new ListDynamic<T> ();
ListIF<T> lRight = new ListDynamic<T> ();
IteratorIF<T> listIt = getIterator ();
while (listIt.hasNext ()) {
T element = listIt.getNext ();
if (index < middle) lLeft.insert (element);
if (index >= middle) lRight.insert (element);
index = index + 1;
}
lLeft = lLeft.sort (comparator);
lRight = lRight.sort (comparator);
return sortMerge (lLeft, lRight, comparator);
}
}

4 - 21

I. Fase de divisin
Durante la primera fase, el algoritmo divide
recursivamente el problema en subproblemas de
la mitad de tamao. Este proceso requiere
recorrer la lista y tiene un coste de complejidad
lineal

5 7 3 2
5 7
5

3 2
3

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Algoritmos sobre listas

Ordenacin de los elementos de una lista


Los algoritmos de ordenacin que pueden aplicarse sobre listas, son rela6vamente pocos,
en comparacin con los que pueden aplicarse sobre estructuras de indexacin. En concreto
nosotros discu6remos en este captulo la ordenacin por insercin y la ordenacin por
mezcla

Ordenacin por mezcla


private ListIF<T> sortMerge (ListIF<T> lLeft,
ListIF<T> lRight,
ComparatorIF<T> comparator)
{
ListDynamic<T> result = new ListDynamic<T> ();
while (lLeft.getLength () > 0 || lRight.getLength () > 0) {
if (lLeft.getLength () > 0 && lRight.getLength () > 0) {
T eLeft = lLeft.getFirst ();
T eRight = lRight.getFirst ();
if (comparator.isGreater (eLeft, eRight)) {
result.append (eLeft);
lLeft = lLeft.getTail ();
} else {
result.append (eRight);
lRight = lRight.getTail ();
}
} else if (lLeft.getLength () > 0) {
T eLeft = lLeft.getFirst ();
result.append (eLeft);
lLeft = lLeft.getTail ();
} else if (lRight.getLength () > 0) {
T eRight = lRight.getFirst ();
result.append (eRight);
lRight = lRight.getTail ();
}
}
return result;
}

4 - 22

II. Fase de mezcla


Una vez alcanzado elementos atmicos, la fase
de mezcla combina las soluciones ordenando
cada subproblema por combinacin de sus
elementos. De esta forma, se obtiene, al final, el
array completamente ordenado

5 7

2 3
2 3 5 7

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Ejercicios

Ejercicios
Dado el carcter recursivo de la denicin del 6po abstracto de datos ListIF, la mayora de
algoritmos sobre listan 6enen un planteamiento recursivo. A con6nuacin se presentan una
coleccin de problemas `picos sobre listas para que se resuelvan de esta manera
I. Longitud de una lista
Disee una funcin recursiva que
calcule el nmero de elementos que
con6ene una lista

IV. ltimo elemento

Disee una funcin recursiva que


compare lexicogrcamente 2 listas
de caracteres.

V. Insertar al final

Disee una funcin recursiva


devuelva el l6mo elemento de una
lista

VII. Lista inversa

Disee una funcin recursiva que


inserte un dato como l6mo
elemento de una lista

VIII. Borrado de un elemento

Disee una funcin recursiva que


devuelva una lista con los elementos
colocados de forma inversa a otra

X. Lista prefijo

Disee una funcin recursiva que


devuelva una lista que elimine la
primera aparicin de un elemento

XI. Lista sufijo

Disee una funcin recursiva que


devuelva una sublista prejo que
precede a un elemento dado

4 - 23

II. Comparar dos listas

Disee una funcin recursiva que


devuelva la lista sujo que sucede a
un elemento dado

III. Sublista
Disee una funcin que dada una
lista determine si una lista es sublista
de otra dada de mayor tamao

VI. Concatenar dos listas


Disee una funcin recursiva que
devuelve la lista resultante de
concatenar dos listas

IX. Borrar todos


Disee una funcin que devuelva una
lista donde se hayan eliminado todas
las apariciones de un elemento

XII. Lista mayores


Disee una funcin recursiva que
devuelva una lista con todos los
elementos mayores a uno dado

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Ejercicios

Ejercicios
Dado el carcter recursivo de la denicin del 6po abstracto de datos ListIF, la mayora de
algoritmos sobre listan 6enen un planteamiento recursivo. A con6nuacin se presentan una
coleccin de problemas `picos sobre listas para que se resuelvan de esta manera
XIII. Sumar 1

XIV. Pertenecen 2

Disee una funcin recursiva que


sume 1 a todo los elementos de una
lista de enteros

XVI. Interseccin de listas


Disee una funcin que dadas dos
listas devuelva los elementos
comunes a ambas

XIX. Contador

XVII. Partes de un conjunto


Disee una funcin que recibiendo
un conjunto en forma de lista genere
una lista de listas con las partes del
conjunto

XX. Lista contador

Disee una funcin que cuente el


numero de veces que determinado
elemento aparece en una lista

XXII. Suma de listas

Disee una funcin que genere una


lista con el nmero de veces que
aparece cada elemento de una lista

XXIII. Convertir a nmero

Dadas dos listas que representan


nmeros naturales, implemente el
algoritmo de suma generando una
lista resultado

4 - 24

Disee una funcin que indique si dos


elementos pertenecen a una lista
dada

Disee una funcin que dada una


lista de dgitos construya el nmero
natural que representa

XV. Unin de conjuntos


Disee una funcin que dadas dos
listas que representan 2 conjuntos
devuelva la lista del conjunto unin

XVIII. Complemento a 1
Disee una funcin recursiva que
dada una lista de ceros y unos
devuelva el complemento a 1

XXI. Producto escalar


Disee una funcin recursiva que
calcule el producto escalar de dos
vectores expresados en listas

XXIV. Convertir a lista


Disee una funcin que dado un
nmero genere una lista de dgitos
que lo represente

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Bibliograba

BibliograUa
Bibliografa bsica
Estructuras de datos en java. Weiss, Mark
Allen. Pearson Addison Wesley. ISBN
9788478290352

4 - 25

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Tipos abstractos de datos lineales. Listas


Bibliograba

BibliograUa
Bibliografa complementaria
Estructura de datos y algoritmos en java. A.
Drozdek. Thomsom. ISBN: 9706866116. 2007

4 - 26

Estructuras de datos con Java. J. Lewis, J.


Chase. Pearson Addison Wesley. ISBN 13:
9788420541914

Javier Vlez Reyes jvelez@lsi.uned.es Jos Ignacio Mayorga Toledano nmayorga@lsi.uned .es

Anda mungkin juga menyukai