• No se han encontrado resultados

Tipos abstractos de datos lineales Pilas

N/A
N/A
Protected

Academic year: 2021

Share "Tipos abstractos de datos lineales Pilas"

Copied!
26
0
0

Texto completo

(1)

Javier Vélez Reyes José Ignacio Mayorga Toledano [email protected] [email protected] Departamento de Lenguajes Y Sistemas Informáticos UNED

Estrategias de programación y estructuras de datos

Grado en Ingeniería Informática Grado en Tecnologías de la Información

Departamento de Lenguajes y Sistemas informáticos

Tipos abstractos de datos lineales

Pilas

(2)

Tipos abstractos de datos lineales. Pilas

Índice

Índice

› Introducción

› Tipos abstractos de datos lineales

› El tipo abstracto de datos Pila

› Interfaz del tipo abstracto de datos Pila

› Implementaciones del tipo abstracto de datos Pila

› Implementación dinámica

› Implementación estática

› Implementación con Lista

› Algoritmos sobre Pilas

› Recorrido de los elementos de una Pila

› Búsqueda de un elemento sobre una Pila

› Problemas y ejercicios

› Bibliografía

(3)

Tipos abstractos de datos lineales. Pilas

Objetivos generales

Objetivos

› Conocer la interfaz del tipo abstracto de datos Pila

› Aprender a implementar el TAD Pila mediante la interfaz StackIF

› En versión estática (con limitación explícita de capacidad máxima)

› En versión dinámica (sin limitación explícita de capacidad máxima)

› Utilizando una lista

› Conocer los principales problemas algorítmicos sobre pilas

› Recorrido de los elementos de una pila

› Búsqueda de un elemento sobre una pila

› Practicar el diseño de funciones recursivas sobre pilas

(4)

Tipos abstractos de datos lineales. Pilas

Introducción

Tipos abstractos de datos lineales

Los tipos abstractos de datos lineales representan abstracciones en las que los datos son organizados de forma secuencial. A continuación se muestran los diferentes TADs que caen dentro de esta categoría y que se diferencian, esencialmente, en la forma en que se ofrecen acceso a sus datos

Tipos abstractos de datos lineales

I. Listas

II. Pilas

III. Colas

El tipo abstracto de datos Lista representa una estructuras de datos donde los elementos se disponen de forma secuencial y las operaciones de inserción y extracción se aplican por el principio, que puede moverse recursivamente haciendo referencia a otras sublistas

El tipo abstracto de dato Pila representa una estructuras de datos donde los elementos se disponen de forma secuencial y las operaciones de inserción y extracción se aplican por el principio según la política de acceso último en entrar, primero en salir

El tipo abstracto de dato Cola representa una estructuras de datos donde los elementos se disponen de forma secuencial y las operaciones de inserción y extracción se aplican por el final y por el principio respectivamente de acuerdo a la política de primero en entrar, primero en salir

Tema 4

Tema 5

Tema 6

(5)

Tipos abstractos de datos lineales. Pilas

Introducción

El tipo abstracto de datos Pila

Las pilas son abstracciones de datos que organizan una colección de elementos de manera secuencial, donde existe un único punto de interés llamado cima por donde se realizan las operaciones de acceso. La política de acceso indica que el último elemento en entrar en una pila es el primero en salir de ella (Last In First Out, LIFO).

Una pila es un tipo abstractos de datos que organiza una colección de elementos de forma secuencial. Las operaciones de acceso se realizan por un extremo llamado cima y la política de acceso es último en entrar primero en salir (LIFO)

Cima

Las operaciones de inserción y extracción se realizan por un extremo llamado cima

Una pila puede imaginarse como una estructura de datos que dispone a los mismos en secuencia uno encima de otros de manera que siempre el último elemento en apilarse es el único que puede ser directamente accedido

Pila

1

2

3

4

(6)

Tipos abstractos de datos lineales. Pilas

Interfaz del tipo abstracto de datos Pila

La interfaz del tipo abstracto de datos Pila StackIF <T>

public interface StackIF <T>

{ /**

* Devuelve la cima de la pila.

* @return la cima de la pila.

*/

public T getTop ();

/**

* Inserta un elemento a la pida.

* @param element El elemento a ser añadido.

* @return la pila incluyendo el elemento.

*/

public StackIF<T> push (T element);

/**

* Extrae de la pila el elemento en la cima.

* @return la pila excluyendo la cabeza.

*/

public StackIF<T> pop ();

/**

* Devuelve cierto si la pila esta vacia.

* @return cierto si la pila esta vacia.

*/

public boolean isEmpty ();

El interfaz de Pila que utilizaremos a lo largo de este curso, StackIF está compuesto por las operaciones que describimos a continuación

cima

Todas las operaciones de una pila se atacan por la cima. Este método devuelve el elemento en la cima sin extraerlo

2 3 1 1

Insertar

La operación push inserta un elemento encima de la cima de manera que el elemento insertado pasa a ser la nueva cima

2 3 1 2

3

push (1)

Extraer

La operación pop extrae el elemento en la cima de la pila de manera que el elemento en la cima pasa a ser el de siguiente en la pila 2

3 1

2 3

pop ()

Es vacía

Este predicado indica si la pila no contiene ningún elemento. Semánticamente equivale a preguntar si el número de elementos es 0 (ver después)

2 3 1

falso cierto

(7)

Tipos abstractos de datos lineales. Pilas

Interfaz del tipo abstracto de datos Pila

La interfaz del tipo abstracto de datos Pila StackIF <T>

/**

* Devuelve cierto si la pila esta llena.

* @return cierto si la pila esta llena.

*/

public boolean isFull();

/**

* Devuelve el numero de elementos de la pila.

* @return el numero de elementos de la pila.

*/

public int getLength ();

/**

* Devuelve cierto si la pila contiene el elemento.

* @param element El elemento buscado.

* @return cierto si la pila contiene el elemento.

*/

public boolean contains (T element);

/**

* Devuelve un iterador para la pila.

* @return un iterador para la pila.

*/

public IteratorIF<T> getIterator ();

}

El interfaz de Pila que utilizaremos a lo largo de este curso, StackIF está compuesto por las operaciones que describimos a continuación

Está llena

En implementaciones con capacidad máxima limitada tiene sentido preguntar si una pila ha alcanzado el número máximo de elementos que puede albergar

2 3 1

cierto

2 3

falso

Longitud

La longitud de una pila devuelve el número de elementos que esta contiene. Si la pila esta vacía devuelve 0. Si esta llena devuelve la capacidad de la pila

2 3 1

getLength () 3

Búsqueda

La operación contains busca un elemento en la pila e indica si está contenido dentro de la misma

2 3

1 contains (3)cierto falso contains (7)

Recorrido

El recorrido de una pila devuelve un iterador que permite visitar todos los elementos de la pila según aparecen desde la cima hasta la base de la misma

2 3

1 1

2 3

(8)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

Implementación del tipo abstracto de datos Pila StackIF <T>

Existen varias estrategias para implementar pilas que responden al interfaz StackIF anterior.

En general, éstas se dividen en implementaciones dinámicas, que articulan pilas de capacidad indefinida e implementaciones estáticas, con una capacidad máxima limitada y establecida como parámetro. A continuación presentamos varias implementaciones

Implementación dinámica basada en elemento y siguiente

Según esta estrategia de implementación, una pila está formada por un atributo que representa la cima y otro que es una referencia a una pila y representa el resto de la pila.

De esta manera una pila es una colección encadenada de pares (elemento, siguiente)

1 2 3 4 - -

Cima y siguiente

Cada objeto Pila contiene un atributo para representar el elemento en la cima de la pila y un atributo del tipo definido StackIF que representa una referencia al resto de elementos debajo de la cima

Ultimo, elemento fantasma

Aunque en otras implementaciones el valor del último objeto se aprovecha para incluir un último 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 pila a un único caso base isEmpty ()

Pila

La pila es una secuencia de pares (elemento, siguiente) acabada en un par fantasma

(9)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

public class StackDynamic <T> implements StackIF<T> * {

private T element;

private StackDynamic<T> next;

public StackDynamic () {

element = null;

next = null;

}

public StackDynamic (StackIF<T> stack) {

this ();

if (stack != null) if (!stack.isEmpty ()) {

element = stack.getTop ();

next = new StackDynamic<T> (stack.pop ());

stack.push (element);

} }

public StackDynamic (ListIF<T> list) {

this ();

if (list != null) if (!list.isEmpty () {

element = list.getFirst ();

next = new StackDynamic<T> (list.getTail ());

} }

Implementación dinámica basada en elemento y siguiente

@Override

public T getTop () {

return element;

}

@Override

public StackIF<T> push (T element) {

if (element != null) {

StackDynamic<T> stack = new StackDynamic<T> ();

stack.element = this.element;

stack.next = this.next;

this.element = element;

this.next = stack;

}

return this;

}

@Override

public StackIF<T> pop () {

if (!isEmpty ()) {

element = next.element;

next = next.next;

}

return this;

}

Según esta estrategia de implementación, una pila está formada por un atributo que representa la cima y otro que es una referencia a una pila y representa el resto de la pila.

De esta manera una pila es una colección encadenada de pares (elemento, siguiente)

* Los comentarios de las cabeceras se han omitido por cuestiones de espacio

(10)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

@Override

public boolean isEmpty () {

return element == null &&

next == null;

}

@Override

public boolean isFull() {

return false;

}

@Override

public int getLength () {

if (isEmpty ()) return 0;

return 1 + next.getLength ();

}

@Override

public boolean contains (T element) {

if (isEmpty ()) return false;

else return this.element.equals (element) ||

next.contains (element);

}

Implementación dinámica basada en elemento y siguiente

@Override

public IteratorIF<T> getIterator () {

StackIF<T> handler = new StackDynamic<T> (this);

return new StackIterator<T> (handler);

}

@Override

public int hashCode () {

return 31 * ((element == null) ? 0 : element.hashCode ()) + ((next == null) ? 0 : next.hashCode ());

}

@SuppressWarnings("unchecked")

@Override

public boolean equals (Object o) { ...

}

@Override

public String toString () { ...

} }

Según esta estrategia de implementación, una pila está formada por un atributo que representa la cima y otro que es una referencia a una pila y representa el resto de la pila.

De esta manera una pila es una colección encadenada de pares (elemento, siguiente)

* Los comentarios de las cabeceras se han omitido por cuestiones de espacio

(11)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

Implementación del tipo abstracto de datos Pila StackIF <T>

Existen varias estrategias para implementar pilas que responden al interfaz StackIF anterior.

En general, éstas se dividen en implementaciones dinámicas, que articulan pilas de capacidad indefinida e implementaciones estáticas, con una capacidad máxima limitada y establecida como parámetro. A continuación presentamos varias implementaciones

Implementación estática basada en array

Según esta estrategia de implementación, una pila está constituida por un array de capacidad limitada y especificada mediante un parámetro y un índice que apunta a la cima de la pila. La pila empieza por la posición 0 y avanza hacia posiciones crecientes

0 0 0 0

3 7 2 3

1

cima

Este índice apunta siempre al elemento que se encuentra en la cima de la pila. El índice comienza en 0 y llega hasta capacidad–1 para valores de la pila

Extraer

Extraer mueve la cima de la pila una posición hacia atrás con lo que la posición anterior pasa a ser la nueva cima. Cima == 0 indica una pila vacía luego esa posición se desaprovecha

Insertar

Las inserciones mueven la cima una posición hacia adelante e insertan el elemento. Si cima llega a valer capacidad - 1 la lista está llena y no se puede insertar

Basura

El resto de elementos del array que no pertenecen a la pila son basura, resultado del trabajo con el tipo

Capacidad = 10

Pila

La pila está formada por los elementos que van desde la posición 0 hasta cima

(12)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

public class StackStatic <T> implements StackIF<T> * {

private Object[] elements;

private int capacity;

private int top;

public StackStatic (int capacity) {

this.elements = new Object[capacity + 1];

this.capacity = capacity + 1;

this.top = 0;

}

@SuppressWarnings("unchecked")

public StackStatic (StackIF<T> stack, int capacity) {

this (capacity);

if (stack != null) {

for (int i = stack.getLength (); i > 0; i--) { T element = stack.getTop ();

elements [i] = element;

stack.pop ();

top = top + 1;

}

for (int i = 1; i <= getLength (); i++) { T element = (T) elements [i];

stack.push (element);

} } }

Implementación estática basada en array

public StackStatic (ListIF<T> list, int capacity) {

this (capacity);

if (list != null) {

ListIF<T> aList = list;

for (int index = 0; index < list.getLength (); index++) { this.elements [index] = aList.getFirst ();

aList = list.getTail ();

} } }

@SuppressWarnings("unchecked")

@Override

public T getTop () {

if (isEmpty ()) return null;

return (T) elements [top];

}

@Override

public StackIF<T> push (T element) {

if (element != null) if (!isFull ()) {

top = top + 1;

elements [top] = element;

} return this;

}

Según esta estrategia de implementación, una pila está constituida por un array de capacidad limitada y especificada mediante un parámetro y un índice que apunta a la cima de la pila. La pila empieza por la posición 0 y avanza hacia posiciones crecientes

* Los comentarios de las cabeceras se han omitido por cuestiones de espacio

(13)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

@Override

public StackIF<T> pop () {

if (!isEmpty ()) { top = top - 1;

}

return this;

}

@Override

public boolean isEmpty () {

return top == 0;

}

@Override

public boolean isFull() {

return top == (capacity - 1);

}

@Override

public int getLength () {

return top;

}

Implementación estática basada en array

@Override

public boolean contains (T element) {

IteratorIF<T> stackIt = this.getIterator ();

boolean found = false;

while (!found && stackIt.hasNext ()) { T anElement = stackIt.getNext ();

found = anElement.equals (element);

}

return found;

}

@Override

public IteratorIF<T> getIterator () {

StackIF<T> handler = new StackStatic<T> (this, capacity);

return new StackIterator<T> (handler);

}

@Override

public int hashCode () {...}

@SuppressWarnings("unchecked")

@Override

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

@Override

public String toString () {...}

}

Según esta estrategia de implementación, una pila está constituida por un array de capacidad limitada y especificada mediante un parámetro y un índice que apunta a la cima de la pila. La pila empieza por la posición 0 y avanza hacia posiciones crecientes

* Los comentarios de las cabeceras se han omitido por cuestiones de espacio

(14)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

Implementación del tipo abstracto de datos Pila StackIF <T>

Existen varias estrategias para implementar pilas que responden al interfaz StackIF anterior.

En general, éstas se dividen en implementaciones dinámicas, que articulan pilas de capacidad indefinida e implementaciones estáticas, con una capacidad máxima limitada y establecida como parámetro. A continuación presentamos varias implementaciones

Implementación basada en lista

Dado que las implementaciones de pilas que hemos visto son bastante similares a las de listas, es posible implementar una pila a partir de una lista. El carácter estático o dinámico de la implementación dependerá del tipo de implementación de lista utilizada

1 2 3 4 5 6 7 8 9

Primero es cima

El primer elemento de una lista se corresponde con la cima de la pila

Resto es resto de pila

El resto de elementos de la lista corresponde con la subpila que hay debajo de la cima

Pila

La pila se implementa a partir de cualquier implementación del TAD Lista con interfaz ListIF. La operación de insertar se implementa con la inserción en la lista y la de extracción con la operación de obtener resto en la cola

ListIF

(15)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

public class StackList <T> implements StackIF<T> * {

private ListIF<T> list;

public StackList () {

this.list = new ListDynamic<T> ();

}

public StackList (StackIF<T> stack) {...}

public StackList (ListIF<T> list) {

this.list = new ListDynamic<T> (list);

}

@Override

public T getTop () {

return list.getFirst ();

}

@Override

public StackIF<T> push (T element) {

list.insert (element);

return this;

}

Implementación basada en lista

@Override

public StackIF<T> pop () {

list = list.getTail ();

return this;

}

@Override

public boolean isEmpty () {

return list.isEmpty ();

}

@Override

public boolean isFull() {

return list.isFull ();

}

@Override

public int getLength () {

return list.getLength ();

}

@Override

public boolean contains (T element) {

return list.contains (element);

}

Dado que las implementaciones de pilas que hemos visto son bastante similares a las de listas, es posible implementar una pila a partir de una lista. El carácter estático o dinámico de la implementación dependerá del tipo de implementación de lista utilizada

* Los comentarios de las cabeceras se han omitido por cuestiones de espacio

(16)

Tipos abstractos de datos lineales. Pilas

Implementación del tipo abstracto de datos Pila

@Override

public IteratorIF<T> getIterator () {

StackIF<T> handler = new StackList<T> (list);

return new StackIterator<T> (handler);

}

@Override

public int hashCode () {

return 31 * ((list == null) ? 0 : list.hashCode ());

}

@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 {

StackList<T> s = (StackList<T>) o;

return s.list.equals (list);

} }

Implementación basada en lista

@Override

public String toString () {

StringBuffer buff = new StringBuffer ();

buff.append ("StackList - [");

IteratorIF<T> stackIt = getIterator ();

while (stackIt.hasNext ()) { T element = stackIt.getNext ();

buff.append (element);

if (stackIt.hasNext ()) buff.append (", ");

}

buff.append ("]");

return buff.toString ();

} }

Dado que las implementaciones de pilas que hemos visto son bastante similares a las de listas, es posible implementar una pila a partir de una lista. El carácter estático o dinámico de la implementación dependerá del tipo de implementación de lista utilizada

* Los comentarios de las cabeceras se han omitido por cuestiones de espacio

(17)

Tipos abstractos de datos lineales. Pilas

Algoritmos sobre pilas

Algoritmos sobre pilas

A diferencia de lo que ocurría en el caso de las listas donde estudiamos que la ordenación era uno de los problemas recurrentes, en el caso de las pilas se considera que tal tipo de manipulaciones no son de interés ya que irían en contra de la esencia organizativa del tipo – mantener a los elementos dispuestos en el orden de llegada de acuerdo a una política LIFO.

Por ello, en esta sección nos centraremos en discutir el problema del recorrido de los elementos de una pila y la búsqueda de un elemento dentro de una pila.

Algoritmos sobre pilas

I. Recorrido

El recorrido de los elementos de una pila devuelve un iterador que permite acceder secuencialmente a los mismos según aparecen almacenados en la estructura, en sentido desde la cima hasta la base de la pila. El recorrido en sentido contrario es fácilmente implementable y se deja como ejercicio

II. Búsqueda

La búsqueda de un elemento sobre los elementos de una pila se realiza de forma secuencial dada la definición del tipo lo que imprime un coste lineal al algoritmo. El problema fundamental en este tipo de algoritmos es que dicha búsqueda es destructiva y requiere o utilizar un iterador (con copia) o reconstruir la estructura tras el algoritmo

Independencia de la implementación

(18)

Tipos abstractos de datos lineales. Pilas

Algoritmos sobre pilas

Recorrido de los elementos de una pila

Para articular el recorrido secuencial de los elementos de una pila debe implementarse el interfaz IteratorIF. Las implementaciones de StackIF anteriores construyen una copia de la pila como manejador para garantizar que la iteración no modifique el estado del tipo

class StackIterator<T> implements IteratorIF<T>

{

private StackIF<T> handler;

private StackIF<T> restart;

/**

* Constructor para StackIterator.

* @param handler el manejador de pilas.

*/

public StackIterator (StackIF<T> handler) {

this.handler = handler;

this.restart = new StackDynamic<T> (handler);

} /**

* Devuelve el siguiente elemento de la iteracion.

* @return el siguiente elemento de la iteracion.

*/

@Override

public T getNext () {

T top = handler.getTop ();

handler.pop ();

return top;

}

Se mantienen 2 manejadores constantemente, uno para articular el recorrido de la pila. El otro siempre apunta a la cima de la pila y se utiliza para implementar la operación de reset del iterador

Iteración con reset

La operación de avance devuelve el elemento en cima de la pila y actualiza el manejador de recorrido extrayendo la cima. Para invocar esta operación con seguridad hay que asegurarse de que el manejador no apunta a la cola vacía…

Avance

2 1 4 3

handler getNext()

restart

(19)

Tipos abstractos de datos lineales. Pilas

Algoritmos sobre pilas

Recorrido de los elementos de una pila

Para articular el recorrido secuencial de los elementos de una pila debe implementarse el interfaz IteratorIF. Las implementaciones de StackIF anteriores construyen una copia de la pila como manejador para garantizar que la iteración no modifique el estado del tipo

/**

* 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 = new StackDynamic<T> (restart);

}

@Override

public int hashCode () { ... }

@Override

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

@Override

public String toString () {...}

}

Para saber si el iterador contiene más elementos y por tanto puede volver a invocarse la operación de avance o no, hay que preguntar si el manejador ha alcanzado el final de la pila

Hay siguiente

Una vez que un iterador ha llegado a su fin sólo se puede construir otro iterador, o resetear este a su valor inicial. En este caso sin embargo, la operación de reset requiere una copia con lo que el coste es idéntico al de construir un nuevo iterador.

Reset

2 1 4 3

handler reset ()

restart handler

(20)

Tipos abstractos de datos lineales. Pilas

Algoritmos sobre pilas

Búsqueda de un elemento sobre una pila

La búsqueda de un dato sobre los elementos contenidos en una pila es un problema de recorrido secuencial que termina cuando se encuentra una cima que corresponde con el dato buscado. El problema es que la búsqueda sobre el tipo es destructiva a no ser que se aplique sobre la implementación o se utilice un iterador

Búsqueda iterativa con centinela

/**

* Devuelve cierto si la pila contiene el elemento.

* @param element El elemento buscado.

* @return cierto si la pila contiene el elemento.

*/

@Override

public boolean contains (T element) {

IteratorIF<T> stackIt = this.getIterator ();

boolean found = false;

while (!found && stackIt.hasNext ()) { T anElement = stackIt.getNext ();

found = anElement.equals (element);

}

return found;

}

En la búsqueda con centinela se itera sobre la pila y se utiliza una guarda (centinela) para indicar el momento en que se ha encontrado el elemento y la búsqueda puede parar

Búsqueda recursiva

/**

* 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 this.element.equals (element) ||

next.contains (element);

}

En la búsqueda 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 pila para buscar el elemento

(21)

Tipos abstractos de datos lineales. Pilas

Problemas y ejercicios

Ejercicios

Dado el carácter destructivo de las operaciones sobre pilas – para avanzar en una pila es necesario extraer su cima con pop – la realización de muchos de sus algoritmos requiere de un proceso de protección consistente en hacer una copia de la misma. Ignorando el problema de destrucción resuelva los siguientes problemas

Diseñe una función que calcule el número de elementos que contiene una pila

I. Longitud de una pila

Devolver una lista con los elementos de una pila según aparecen en ésta desde la cima hasta la base

II. Pasar a lista

Diseñe una función que dada una lista determine si ésta esta contenida en una pila como subpila

III. Subpila

Diseñe una función devuelva el último elemento de una pila

IV. Elemento base

Diseñe una función que inserte un dato como elemento en la base de una pila

V. Insertar en la base

Diseñe una función recursiva que devuelve la pila resultante de concatenar dos pilas

VI. Concatenar dos pilas

Diseñe una función recursiva que devuelva una pila con los elementos colocados de forma inversa a otra VII. Pila inversa

Diseñe una función que devuelva una pila que elimine la primera aparición de un elemento

VIII. Borrado de un elemento

Diseñe una función que devuelva una pila donde se hayan eliminado todas las apariciones de un elemento IX. Borrar todos

Diseñe una función que devuelva una pila con los elementos que preceden a un elemento dado

X. Pila prefijo

Diseñe una función que devuelva la pila sufijo que sucede a un elemento dado

XI. Pila sufijo

Diseñe una función recursiva que devuelva una pila con todos los elementos mayores a uno dado XII. Pila mayores

(22)

Tipos abstractos de datos lineales. Pilas

Problemas y ejercicios

Problemas

Las pilas son un tipo abstracto de datos que se utiliza recurrentemente en los problemas de cierta complejidad de programación. A continuación planteamos algunos ejemplos de problemas que se resuelven con el uso de pilas.

El juego, en su forma más tradicional, consiste en tres varillas verticales. En una de las varillas se apila un número n de discos. Los discos se apilan sobre una varilla en tamaño decreciente. No hay dos discos iguales, y todos ellos están apilados de mayor a menor radio en una de las varillas, quedando las otras dos varillas vacantes.

Las torres de Hanoi

1. Sólo se puede mover un disco cada vez.

2. Un disco de mayor tamaño no puede descansar sobre uno más pequeño que él mismo.

3. Sólo puedes desplazar el disco que se encuentre arriba en cada varilla.

El juego consiste en pasar todos los discos de la varilla ocupada a una de las otras varillas vacantes. Para realizar este objetivo, es necesario seguir tres simples reglas:

(23)

Tipos abstractos de datos lineales. Pilas

Problemas y ejercicios

Problemas

Las pilas son un tipo abstracto de datos que se utiliza recurrentemente en los problemas de cierta complejidad de programación. A continuación planteamos algunos ejemplos de problemas que se resuelven con el uso de pilas.

La finalidad del Solitario Carta blanca es mover todas las cartas desde la zona del tablero a las casillas de palo: los cuatro recuadros situados en la parte superior derecha del tablero. Para ganar, el jugador tiene que hacer cuatro montones de cartas en las casillas, uno por cada palo, y amontonarlas en orden ascendente desde el AS hasta el REY. Puedes mover las cartas de una columna a otra ordenando las cartas de mayor a menor y alternando los La carta blanca

colores de los palos, así como utilizar las casillas libres para apartar cartas de las columnas y así acceder a la carta que hay debajo. La partida finaliza cuando el jugador ha movido todas las cartas a las casillas de palo o cuando ya no puede realizar ningún movimiento más. Se dice que todas las partidas de Carta blanca pueden ganarse.

(24)

Tipos abstractos de datos lineales. Pilas

Problemas y ejercicios

Problemas

Las pilas son un tipo abstracto de datos que se utiliza recurrentemente en los problemas de cierta complejidad de programación. A continuación planteamos algunos ejemplos de problemas que se resuelven con el uso de pilas.

Aunque actualmente las calculadores permiten operar con expresiones en notación infija, tradicionalmente ha sido frecuente encontrar máquinas que requerían introducir las expresiones en notación postfija. Esto facilita la forma de calculo y evita el uso de parentización para desambiguar. De esta manera, 2 + 3 * 5 se expresa en notación postfija como 2 3 + 5 * y debe interpretarse como que a los operandos…

Calculadora en notación postfija

(25)

Tipos abstractos de datos lineales. Pilas

Bibliografía

Bibliografía

Bibliografía básica

Estructuras de datos en java. Weiss, Mark Allen. Pearson Addison – Wesley. ISBN 9788478290352

(26)

Tipos abstractos de datos lineales. Pilas

Bibliografía

Bibliografía

Bibliografía complementaria

Estructura de datos y algoritmos en java. A.

Drozdek. Thomsom. ISBN: 9706866116. 2007

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

Chase. Pearson – Addison Wesley. ISBN 13:

9788420541914

Referencias

Documento similar

Cedulario se inicia a mediados del siglo XVIL, por sus propias cédulas puede advertirse que no estaba totalmente conquistada la Nueva Gali- cia, ya que a fines del siglo xvn y en

que hasta que llegue el tiempo en que su regia planta ; | pise el hispano suelo... que hasta que el

Para ello, trabajaremos con una colección de cartas redactadas desde allí, impresa en Évora en 1598 y otros documentos jesuitas: el Sumario de las cosas de Japón (1583),

Entre nosotros anda un escritor de cosas de filología, paisano de Costa, que no deja de tener ingenio y garbo; pero cuyas obras tienen de todo menos de ciencia, y aun

E Clamades andaua sienpre sobre el caua- 11o de madera, y en poco tienpo fue tan lexos, que el no sabia en donde estaña; pero el tomo muy gran esfuergo en si, y pensó yendo assi

Fuente de emisión secundaria que afecta a la estación: Combustión en sector residencial y comercial Distancia a la primera vía de tráfico: 3 metros (15 m de ancho)..

Products Management Services (PMS) - Implementation of International Organization for Standardization (ISO) standards for the identification of medicinal products (IDMP) in

This section provides guidance with examples on encoding medicinal product packaging information, together with the relationship between Pack Size, Package Item (container)