pilas - Profesor ROBERTO OSORNIO SOTO

Anuncio
 NOMBRE ALUMNO: Apellido paterno Apellido materno Nombre (s) No. BOLETA INSTITUTO POLITÉCNICO NACIONAL SECRETARIA ACADÉMICA DIRECCIÓN DE EDUCACIÓN SUPERIOR ESIME CULHUACAN GRUPO FECHA DIA MES AÑO INGENIERÍA EN COMPUTACIÓN ASIGNATURA ESTRUCTURAS DE DATOS PROFESOR M. en C. BEATRIZ EUGENIA CORONA RAMÍREZ PRÁCTICA No. 4 PILAS 1. Objetivo El alumno comprenderá y aplicara los conceptos de las pilas en un programa que cree una pila y realice las operaciones básicas push y pop. 2. Material y Equipo Computadora, Compilador C y/o Java y unidad de almacenamiento (USB) 3. Introducción Teórica Definición de pila y su implementación con arreglos PILA: Es una estructura lineal, finita donde se tiene un conjunto ordenado de objetos los que pueden obtenerse uno a la vez siguiendo un orden determinado. Solo se obtienen por un solo lado de la estructura, (la cima) tope. UEPS = Último en Entrar – Primero en Salir LIFO = Last Input – First Output Los elementos pueden identificarse por la posición en que están, los elementos se sacan en el orden inverso en que entraron o se insertaran. Ej. Supongamos que se meten seis elementos en una pila vacía. AAA, BBB, CCC, DDD, EEE, FFF 47
EEE no puede ser eliminado antes de haber eliminado FFF. 1 AAA 2 BBB 3 CCC 4 DDD 5 EEE 6 FFF Cima
.. N‐
1 N 


FFFF EEE DDD CCC BBB AAA Se puede representar por medio de una lista unidireccional o un arreglo lineal. arreglo lineal (pila) puntero  cima / tope (contiene la posición del elemento cima) variable MAX_PILA (capacidad máxima de la pila) Si CIMA = 0 ó CIMA = NULL  Pila vacía 1 XX
X 2 3 4 Z
Z
Z Y
Y
Y 5 6 _
_
_
_ _
_
_
_ 7 8 _
_
_
_ _
_
_
_ _
_
_
_ Cima =3 MAX_PILA = 8 Operación sobre pilas Las operaciones de meter y sacar en una pila son conocidas en los lenguajes ensambladores como push y pop, respectivamente. Meter: Debemos saber si hay espacio en la pila para el nuevo elemento. Si no hay existirá un desbordamiento. METER (PILA, CIMA, MAX_PILA,DATO) 1.
[¿Pila llena?] Si CIMA = MAXPILA, entonces imprimir: DESBORDAMIENTO Y VOLVER 48
2. Hacer CIMA = CIMA +1 //incrementa CIMA en 1 3. Hacer PILA [CIMA]=DATO // inserta el Dato en la nueva posición CIMA 4. Volver Sacar: Examinar si hay un elemento en la pila para ser eliminado si no habrá un subdesbordamiento. SACAR (PILA, CIMA, DATO) 1.
[¿La pila tiene algún elemento a eliminar?] Si CIMA = 0, entonces imprimir: SUB DESBORDAMIENTO y volver 2. Hacer DATO = PILA[ CIMA ]//asigna el elemento CIMA a DATO 3. Hacer CIMA=CIMA ‐ 1 // decrementa CIMA 4. Volver Ej. Considerar la pila 1 2 XX
X 3 4 Z
Z
Z Y
Y
Y 5 6 _
_
_
_ _
_
_
_ 7 8 _
_
_
_ _
_
_
_ _
_
_
_ Cima =3 a)
1.
2.
3.
4.
MAX_PILA = 8 METER (PILA, WWW) Como CIMA=3, pasar al paso 2 CIMA=3+1=4 PILA[CIMA]=PILA[4]=WWW VOLVER 1 XX
X 2 3 4 Y
Y
Y Z
Z
Z 5 6 W
W
W _
_
_
_ 7 8 _
_
_
_ _
_
_
_ _
_
_
_ Cima =4 MAX_PILA = 8 49
Tomar la pila inicial b)
1.
2.
3.
4.
SACAR (PILA,DATO) Como CIMA=3 pasar al paso 2 PILA[CIMA] = DATO = PILA[3]=ZZZ CIMA = 3‐1=2 VOLVER _
XX
Y
_
X Y
_
Y _ _
_
_
_ _
_
_
_ _
_
_
_ _
_
_
_ _
_
_
_ Cima =2 MAX_PILA = 8 Su implementación con punteros Al igual que en el caso de la pila, se utilizará una lista encadenada en la que cada nodo de la lista guarde un dato de la fila. Sin embargo, a diferencia de la pila, se requiere tener dos apuntadores en ambos extremos de la lista para accesar a ellos: uno para el frente y otro para el final.7Tambien es importante analizar en qué orden estarán estos apuntadores: ¿Frente está al inicio de la lista y final en el último nodo? O ¿final en el primer nodo y frente en el último? Aunque podría parecer indistinto, esto repercute en la eficiencia de las operaciones. Por la forma en que se construye la lista, lo más conveniente será que el frente esté al inicio de la lista y final en el último nodo. Final Frente R Y Z X 50
4. Desarrollo Desarrollar la especificación lógica para el TDA pila así como su programa Elementos Estructura Dominio El tipo de los elementos depende de la aplicación de la pila Lineal La pila tendrá la capacidad de almacenar cualquier cantidad de elementos, según su representación lo permita El diseño de las operaciones es lo que realmente distingue a los TDA pila y fila. Sin embargo las operaciones que se diseñarán serán las mismas para ambos. Adicionalmente, se podrá observar que puede haber diversos diseños para las operaciones, dependiendo del enfoque del diseñador lógico. En este caso, se presentan dos opciones de diseño que permiten ejemplificar y razonar el impacto en la abstracción de datos. Diseño para las operaciones del TDA Pila Agrega un elemento a una pila La pila a la que se va a agregar el elemento y el elemento que se agregará La pila con un elemento más La pila está creada y no está llena La pila queda con un elemento adicional, agregado por el extremo del tope de la pila Sacar (Pop) Utilidad: Elimina el último elemento que se agrego a una pila Entradas La pila a la que se va a quitar un elemento Salidas: La pila con un elemento menos Precondición: La pila esta creada y no está vacía Postcondición: La pila queda con un elemento menos, eliminado por el extremo del tope de la pila Vacía Utilidad: Verifica si una determinada pila está vacía o no Entradas La pila que se va a verificar Meter (Push) Utilidad: Entradas Salidas: Precondición: Postcondición: 51
Salidas: Precondición: Postcondición: Llena Utilidad: Entradas Salidas: Precondición: Postcondición: Valor booleano que indique si la pila está vacía o no La pila por verificar existe Ninguna, la estructura no se modifica Verifica si la pila determinada se encuentra llena o no La pila que se va a verificar Valor booleano que indique si la pila está llena o no La pila por verificar existe Ninguna, la estructura no cambia Programa de la PILA #include <iostream> #include <conio.h> class nodo { public: nodo(int v, nodo *sig = NULL) { valor = v; siguiente = sig; } private: int valor; nodo *siguiente; friend class pila; }; typedef nodo *pnodo; class pila { public: pila() : ultimo(NULL) {} ~pila(); void Push(int v); int Pop(); private: pnodo ultimo; }; 52
pila::~pila() { while(ultimo) Pop();} void pila::Push(int v) { pnodo nuevo; /* Crear un nodo nuevo */ nuevo = new nodo(v, ultimo); /* Ahora, el comienzo de nuestra pila es en nuevo nodo */ ultimo = nuevo; } int pila::Pop() { pnodo nodo; /* variable auxiliar para manipular nodo */ int v; /* variable auxiliar para retorno */ if(!ultimo) return 0; /* Si no hay nodos en la pila retornamos 0 */ /* Nodo apunta al primer elemento de la pila */ nodo = ultimo; /* Asignamos a pila toda la pila menos el primer elemento */ ultimo = nodo‐>siguiente; /* Guardamos el valor de retorno */ v = nodo‐>valor; /* Borrar el nodo */ delete nodo; return v; } int main() { pila Pila; Pila.Push(20); cout << "Push(20)" << endl; Pila.Push(10); cout << "Push(10)" << endl; cout << "Pop() = " << Pila.Pop() << endl; Pila.Push(40); cout << "Push(40)" << endl; Pila.Push(30); cout << "Push(30)" << endl; cout << "Pop() = " << Pila.Pop() << endl; cout << "Pop() = " << Pila.Pop() << endl; Pila.Push(90); cout << "Push(90)" << endl; cout << "Pop() = " << Pila.Pop() << endl; cout << "Pop() = " << Pila.Pop() << endl; cin.get(); 53
getch(); } VERSIÓN #2 #include <iostream> #include <conio.h> #include <stdio.h> class nodo { public: nodo(int v, nodo *sig = NULL) { valor = v; siguiente = sig; } private: int valor; nodo *siguiente; friend class pila; }; typedef nodo *pnodo; /class pila { public: pila() : ultimo(NULL) {} ~pila(); pnodo Push(int v); int Pop(); void Imprime(pnodo ini); private: pnodo ultimo; }; pila::~pila() { while(ultimo) Pop(); } pnodo pila::Push(int v) { pnodo nuevo,inicio; /* Crear un nodo nuevo */ nuevo = new nodo(v, ultimo); /* Ahora, el comienzo de nuestra pila es en nuevo nodo */ ultimo = nuevo; return inicio; 54
} int pila::Pop() { pnodo nodo; /* variable auxiliar para manipular nodo */ int v; /* variable auxiliar para retorno */ if(!ultimo) return 0; /* Si no hay nodos en la pila retornamos 0 */ /* Nodo apunta al primer elemento de la pila */ nodo = ultimo; /* Asignamos a pila toda la pila menos el primer elemento */ ultimo = nodo‐>siguiente; /* Guardamos el valor de retorno */ v = nodo‐>valor; /* Borrar el nodo */ delete nodo; return v; } void pila::Imprime(pnodo ini) { pnodo nodo, inicio,nodoini; /* variable auxiliar para manipular nodo */ int v; /* variable auxiliar para retorno */ //nodo =ultimo; nodo=inicio; while( nodo!=0) {cout<<nodo‐>valor; nodo‐>siguiente; } } int main() { pila Pila; pnodo pn; int opcion,dato; char opc='S'; while(opc=='S'||opc=='s') { printf("1. push\n 2. pop\nOpcion: "); scanf("%d",&opcion); switch(opcion) {case 1: printf("dato: "); scanf("%d",&dato); pn=Pila.Push(dato); //Pila.Imprime(); 55
break; case 2: Pila.Pop(); //Pila.Imprime(); break; case 3: Pila.Imprime(pn); break; default: printf("Opcion invalida"); break; } fflush(stdin); printf("Otra operacion?: "); scanf("%c",&opc); } getch(); } 56
5. Cuestionario [Trabajo complementario] 1.
Define una Pila y menciona sus operaciones básicas 2. ¿Cuántas y cuales formas se puede implementar una pila? 3. ¿Cuáles son los argumentos que deben llevar una sentencia iterativa? 4. Menciona por lo menos 5 ejemplos donde pudiéramos aplicar este tipo de sentencias 5. ¿Cuáles son los errores más comunes que se comenten al implementar cada una de las sentencias en lenguaje C? 6. Conclusiones 57
Descargar