Está en la página 1de 24

ELO320 Estructuras de Datos y Algoritmos Stacks y Colas Toms Arredondo Vidal 2ndo Semestre 2008

Este material est basado en:


Robert Sedgewick, "Algorithms in C", (third edition), Addison-Wesley, ISBN 0-201-31663-3. 2001 material del curso ELO320 del Prof. Leopoldo Silva material en el sitio http://es.wikipedia.org

6: Stacks

6-Stacks y Colas
6.1 Stacks: definiciones y operaciones 6.2 Stacks: implementacin 6.3 Colas: definiciones y operaciones 6.4 Colas: implementacin

6: Stacks

Definiciones y operaciones
El stack (o pila) es una lista restringida, en cuanto

a operaciones, ya que slo permite inserciones y descartes en un extremo, el cual se denomina tope del stack. Tiene gran utilidad al ser usado para implementar variables automticas, implementar funciones recursivas, para evaluar balance de parntesis entre otras. Operaciones posibles sobre stacks incluyen:
r r r

Empujar en el stack o Push Sacar del stack o Pop Leer el primer elemento del stack
6: Stacks 3

6-Stacks y Colas
6.1 Stacks: definiciones y operaciones 6.2 Stacks: implementacin 6.3 Colas: definiciones y operaciones 6.4 Colas: implementacin

6: Stacks

Stacks: Implementacin
En general la implementacin de las operaciones

generales de insercin y descarte usando arreglos son costosas, en comparacin con nodos enlazados va punteros, porque es necesario desplazar el resto de las componentes despus de una insercin o descarte Otro beneficio de usar punteros es que el stack puede crecer dinmicamente

6: Stacks

Stacks: Implementacin usando arreglos


#ifndef __STACK_H__ #define __STACK_H__ #include "datos.h" #define push2(A, B) StackPush((B)); StackPush((A)); void StackInit(int); int StackEmpty(void); int StackFull(void); void StackPush(Item); Item StackPop(void); void StackDestroy(void); #endif /* __STACK_H__ */
6: Stacks 6

Stacks: Implementacin usando arreglos (cont)


#include "datos.h" #include "stack.h" static Item * stack; static int NumItems; static int MAXN; void StackInit(int max) { stack = malloc(max*sizeof(Item) ); //se solicita arreglo. if (stack == NULL) exit(1); NumItems = 0; MAXN=max; }
6: Stacks 7

//puntero al inicio de la zona del stack //numero items en el stack //Mxima capacidad del stack

Stacks: Implementacin usando arreglos (cont)


int StackEmpty(void) { return(NumItems == 0) ; //Retorna T si stack vaco } int StackFull(void) { return(NumItems == MAXN) ; //Ret. T si stack lleno } //se puede empujar algo al stack si no est lleno. void StackPush(Item item) { if (!StackFull() ) stack[NumItems ++] = item; }
6: Stacks 8

Stacks: Implementacin usando arreglos (cont)


Item StackPop(void) { if( StackEmpty() ) { printf("error. Extraccin de stack vacio\n"); exit(1); return; } else return ( stack[--NumItems] ) ; } void StackDestroy(void) { free(stack); }
6: Stacks 9

Stacks: Implementacin usando arreglos (cont)


Es bueno evitar invocar funciones innecesariamente, cuando las acciones de stas sean simples; esto debido al costo de la creacin del frame, de la copia de valores de argumentos y de la posterior destruccin del frame. En esta aplicacin, podra haberse definido como macros los tests de stack vaco o lleno, segn:
#define StackEmpty( ) (NumItems == 0) #define StackFull( ) (NumItems == MAXN)

6: Stacks

10

Ejemplo: Balance de Parentesis


Es til poder detectar si es que los parntesis en un archivo fuente estn o no balanceados Se puede usar un stack: a + (b + c) * [(d + e])/f Seudo-cdigo:
Crear el stack. Mientras no se ha llegado al final del archivo de entrada: Descartar smbolos que no necesiten ser balanceados. Si es un parntesis de apertura: empujar al stack. Si es un parntesis de cierre, efectuar un pop y comparar. Si son de igual tipo continuar Si son de diferente tipo: avisar el error. Si se llega al fin de archivo, y el stack no esta vaco: avisar error. Destruir el stack.
6: Stacks 11

Ejemplo: Expresiones en notacion Polaca Inversa


Las expresiones aritmticas que generalmente escribimos estn en notacin in situ o fija. En esta notacin los operadores se presentan entre dos operandos; por ejemplo: 2 + 3 * 4. Esta notacin no explica el orden de precedencia, esto puede resolver con reglas y con parntesis: ( 2 + 3) *4 La notacin Reverse Polish Notation inventada por Jan Lukasiewicz y usada en las calculadoras HP resuelve este problema. En esta notacin el operador sigue a los operandos: 423+*
6: Stacks 12

Ejemplo: Expresiones en notacion Polaca Inversa (cont)


(3 + 5) * (7 - 2) puede escribirse: 3 5 + 7 2 - * Leyendo la expresin en RPN se realiza con las siguientes operaciones:
r r r r

r r r r r r

Push 3 en el stack. Push 5 en el stack. El 5 est en el tope, el ltimo en entrar. Se aplica la operacin + : la cual saca los dos nmeros del tope del stack, los suma y coloca el resultado en el tope. Push 7 en el stack. Push 2 en el stack. Ahora el stack contiene ahora (8, 7, 2). Se efecta la operacin con los dos nmeros en el tope. ste contiene ahora (8, 5) ste contiene ahora (40)
6: Stacks 13

Ejemplo: Expresiones en notacion Polaca Inversa (cont)

Seudo-cdigo
leer un smbolo; Si es nmero: empujar el valor del smbolo en el stack Si es un operador: { Efectuar dos pop en el stack; Ejecutar operacin sobre los nmeros; Empujar el resultado en el stack; }

While ( no se haya ledo el smbolo fin de archivo EOF) {

} Retornar contenido del tope del stack como resultado;

6: Stacks

14

Ejemplo: Conversin de in situ a Polaca Inversa


Es til poder convertir las expresiones infijas a RPN para poder evaluarlas en un stack. Para especificar el algoritmo es preciso establecer las reglas de precedencia de operadores:
r

La ms alta prioridad est asociada a los parntesis, los cuales se tratan como smbolos Prioridad media tienen la operaciones de multiplicacin y divisin La ms baja la suma y resta.

Se asume solamente la presencia de parntesis redondos en expresiones. Como la notacin polaca inversa no requiere de parntesis, stos no se sacarn hacia la salida.
6: Stacks 15

Ej:

While ( no se haya ledo el smbolo fin de archivo EOF) { leer un smbolo; Si es nmero: enviar hacia la salida; Si es el smbolo ): sacar del stack hacia la salida, hasta encontrar (, el cual no debe copiarse hacia la salida. Si es operador o el smbolo (: Si la prioridad del recin ledo es menor o igual que la prioridad del operado ubicado en el tope del stack: { if( tope==( ) empujar el operador recin ledo; else { efectuar pop del operador y sacarlo hacia la salida hasta que la prioridad del operador recin ledo sea mayor que la prioridad del operador del tope. Empujar el recin ledo en el tope del stack. } } else empujar recin ledo al tope del stack; } Si se llega a fin de archivo: vaciar el stack, hacia la salida. 6: Stacks
16

6-Stacks y Colas
6.1 Stacks: definiciones y operaciones 6.2 Stacks: implementacin 6.3 Colas: definiciones y operaciones 6.4 Colas: implementacin

6: Stacks

17

Definiciones y operaciones
Una cola es una lista con restricciones. En sta las inserciones ocurren en un extremo y los

descartes en el otro (e.g. una cola en el banco) Si se conoce el mximo nmero de componentes que tendrn que esperar en la cola, se suele implementar en base a arreglos. Requiere dos variables o ndices:
r r

cola que es un ndice a donde insertar o encolar cabeza es un ndice al elemento a descartar o desencolar

6: Stacks

18

Definiciones y operaciones
A medida que se consumen o

desencolan componentes, van quedando espacios disponibles en las primeras posiciones del arreglo.
Tambin a medida que se

encolan elementos va disminuyendo el espacio para agregar nuevos elementos, en la zona alta del arreglo.
Una mejor utilizacin del

espacio se logra con un buffer circular, en el cual la posicin siguiente a la ltima del arreglo es la primera del arreglo.
6: Stacks 19

Buffer circular
Este buffer se puede implementar

aplicando aritmtica modular, si el anillo tiene N posiciones, la operacin: cola = (cola+1) % N, mantiene el valor de la variable cola entre 0 y N-1. Operacin similar puede efectuarse para la variable cabeza cuando deba ser incrementada en uno. La variable cola puede variar entre 0 y N-1. Si cola tiene valor N-1, al ser incrementada en uno (mdulo N), tomar valor cero. Tambin se agrega una variable N con el numero de elementos encolados para poder distinguir entre la cola vaca y llena.
6: Stacks 20

6-Stacks y Colas
6.1 Stacks: definiciones y operaciones 6.2 Stacks: implementacin 6.3 Colas: definiciones y operaciones 6.4 Colas: implementacin

6: Stacks

21

Colas: Implementacin usando arreglos circulares


#include "QUEUE.h" static Item *q; // Puntero al arreglo de Items static int N, cabeza, cola, encolados; //Administran el anillo void QUEUEinit(int maxN) //maxN es el valor N-1 de la Fig { } /* La deteccin de cola vaca se logra con */ int QUEUEempty() { return encolados == 0; }
6: Stacks 22

q = malloc((maxN+1)*sizeof(Item)); // Espacio para N items N = maxN+1; cabeza = 0; cola = 0; encolados=0;

Colas: Implementacin usando arreglos circulares (cont)


/* Si la cola no est vaca se puede consumir un elemento */ Item QUEUEget() { Item consumido= q[cabeza]; cabeza = (cabeza + 1) % N ; encolados--; return (consumido); } /* La deteccin de cola llena se logra con QUEUEfull( )*/ int QUEUEfull() { return( encolados == N); }
6: Stacks 23

Colas: Implementacin usando arreglos circulares (cont) void QUEUEput(Item item) /* Encolar un elemento */
{ q[cola] = item; cola = (cola +1) % N; encolados++; } void QUEUEdestroy(void) /* Para recuperar el espacio */ { free ( q ); }

En un caso prctico las funciones cola llena y vaca se pueden implementar con macros.

#define QUEUEempty() (encolados == 0) #define QUEUEfull() (encolados == N)


6: Stacks 24

También podría gustarte