ESTRUCTURAS DINÁMICAS DE DATOS (PILAS) EN C

Documentos relacionados
ESTRUCTURAS DINÁMICAS DE DATOS (PILAS)

ESTRUCTURAS DINÁMICAS DE DATOS (COLAS) EN C

ESTRUCTURAS DINÁMICAS DE DATOS EN LENGUAJE C

ESTRUCTURAS DINÁMICAS DE DATOS (LISTAS)

Realizar el ejercicio anterior utilizando Punteros

Universidad Autónoma del Estado de México 2016, Año del 60 Aniversario de la Universidad Autónoma del Estado de México

ESTRUCTURAS DINÁMICAS DE DATOS

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable.

ESTRUCTURAS DINÁMICAS DE DATOS (LISTAS)

UNIVERSIDAD AUTONOMA DE MADRID ESCUELA POLITÉCNICA SUPERIOR ESTRUCTURAS DE DATOS Y ALGORITMOS

Estructura de datos y algoritmos. Tema IV: TIPOS DE DATOS ABSTRACTOS DINÁMICOS LINEALES

UNIDAD 2. ESTRUCTURAS DE DATOS SECUENCIALES. 1. Pilas (Stacks)

Profesor: José Miguel Rubio L.

Tema: Tipos Abstractos de Datos (TAD s) en C++.

PILAS. Prof. Ing. M.Sc. Fulbia Torres

Uno de los conceptos más útiles en ciencias de la computación es la pila.

Ingeniera de Sistemas: Luz Esperanza Espitia Tutora de Estructura de datos.

Estructura de datos Colas

Estructura de datos Página 1 de 12 ESTRUCTURA DE DATOS TEMA 1 ESTRUCTURA DE DATOS PILA

ESTRUCTURAS. Struct Identificador_ tipo_estructura { Tipo miembro_1; /*Declaración de los miembros*/

Hoja de ejercicios del Tema 9

Punteros. Índice. 1. Qué es un puntero y por que son importantes.

Estructuras de Datos. La pila es un objeto dinámico en constante cambio.

Estructuras Dinámicas

LISTAS ENLAZADAS FUNDAMENTOS TEORICOS

UNIDAD 8 Tipos de datos dinámicos: Punteros Asignación dinámica de memoria. Uso de punteros. Inicialización y asignación de punteros.

UNIDAD 8 Tipos de datos dinámicos: Punteros Asignación dinámica de memoria. Uso de punteros. Inicialización y asignación de punteros.

Estructuras Enlazadas AyED UTN-BA

Las FILAS. ING PEDRO BELTRÁN CANESSA Estructuras de Datos 1

Principal material bibliográfico utilizado

UNIVERSIDAD BANCARIA DE MEXICO CONSTANCIA UNIDAD Y TRABAJO Guadalupe Godínez Maldonado Prof. Juan Carlos Martínez

Tema 13: Apuntadores en C

Estructuras Dinámicas de datos.

Tema 02: TAD Pila. M. en C. Edgardo Adrián Franco Martínez edgardoadrianfrancom

Capítulo. Listas, pilas y colas en C. Contenido. Introducción

Elementos de un programa en C

Estructura de Datos. Pilas Colas. Primer Semestre, Indice. TDA: Pilas TDA: Colas Colas de Prioridad Anillos BiColas BiColas Circulares

Actividad Algoritmos, Estructura y Programación I. FOR, DO-WHILE

Estructura de Datos. TDA: Listas. Primer Semestre, Indice. Tipos de estructura de datos lineales

Contenido PARTE II: ESTRUCTURAS DE DATOS AVANZADAS

1. El Tipo Abstracto de Datos.

Estructura de Datos. Unidad de Aprendizaje: Unidad de Competencia II: Estructuras de Datos Lineales. M. en C. Edith Cristina Herrera Luna

TAD: Pila. TALLER: TAD Pila

Solución práctico 6 Tipos Abstractos de Datos Lista, Pila y Cola

Introducción al lenguaje C

Este material es de uso exclusivo para estudio, los textos fueron tomados textualmente de varios libros por lo que está prohibida su impresión y

(1) Recordemos qué es una pila...

Introducción al lenguaje C

Tipos Recursivos de Datos

PUNTEROS (APUNTADORES)

Tema: Tipos Abstractos de Datos (TAD s) en C#.

Repaso de lenguaje C. Índice. Repaso de lenguaje C. Repaso de lenguaje C: Tipos básicos

TIPOS DE DATOS ABSTRACTOS

Punteros. Definición Un puntero es un dato que contiene una dirección de memoria.

Apuntadores (Punteros)

Estructuras de Datos Estáticas. Diseñar y programar en lenguaje C soluciones utilizando estructuras de datos estáticas

Informática PRÀCTICA 9 Curs Práctica Nº 9: Rango y precisión de representación de números en el ordenador.

IMPLEMENTACIÓN DE PILAS CON LISTAS EN C++

Punteros. Lenguaje C ANSI

ESTRUCTURA DE DATOS. Memoria estática Memoria dinámica Tipo puntero Declaración de punteros Gestión de memoria dinámica Resumen ejemplo

Tema 5. Estructura de datos Pila

11. PILAS Introducción Fundamentos

Programación I Funciones

TEMA 5. CONTROL DE FLUJO DEL PROGRAMA. Sentencia Instrucción Expresión Operadores + Operandos Sintaxis: Sentencia ;

Algoritmo, Estructuras y Programación I Ing. Marglorie Colina

Sistemas Operativos Practica 1: procesos y concurrencia.

Arboles Binarios de Búsqueda en C++

Programación. Test Autoevaluación Tema 3

Estructuras de Datos Dinámicas. Diseñar y programar en lenguaje C soluciones utilizando estructuras de datos dinámicas

WHILE Y DO WHILE BREAK EN LENGUAJE C. BUCLES MIENTRAS. FORZAR SALIDA O TERMINACIÓN. EJEMPLO (CU00534F)

Laboratorio de Arquitectura de Redes. Asignación dinámica de memoria en lenguaje C

7.4. UTILIDADES DE LAS PILAS

Tema 5. Tipos Abstractos de Datos

Punteros y aritmética de punteros. se almacena el operando

FUNDAMENTOS DE PROGRAMACIÓN. PRÁCTICA 11: Apuntadores

1.1 Tipos de Datos Primitivos. 1.2 Tipos de datos estructurados. 1.3 Definición de estructura de datos

A l g o r i t m o y E s t r u c t u r a d e D a t o s Ing. en Sistemas de Información - 1º año -

Listas lineales (circulares,doblemente enlazadas recopilación Raúl H Ruiz C)

Tema 5 Tabla de Símbolos

2. ESTRUCTURAS BÁSICAS

Tema: Plantillas en C++.

Escuela Politécnica Superior de Elche

Introducción al lenguaje C

PROGRAMACION ESTRUCTURADA: Tema 3. Funciones

REPRESENTACIÓN DE DATOS

PUNTEROS O APUNTADORES C++

Existen varios tipos de árboles: 5.1 Árboles binarios

11. PILAS Introducción Fundamentos

Instituto Politécnico Nacional

Tema 7- Modelo y Aplicación de Pila, Cola y. Tema 7- Modelo y Aplicación de. Lista Con Punto de Interés

Tema 3. Estructura de datos lineales. J.T.P. Maria Eugenia Valesani - Programacion 1 - Fa.Ce.Na.

Capitulo V Listas Enlazadas

Números enteros (cortos, largos y sin signo) Números reales (precisión simple y doble) Carácter y cadenas de caracteres. Lógicos.

Programación en Lenguaje C

Guia#9: Punteros en C#.

A l g o r i t m o y E s t r u c t u r a d e D a t o s Ing. en Sistemas de Información - 1º año -

Todo programa en 'C' consta de una o más funciones, una de las cuales se llama main.

Implementaciones de pilas, colas y afines. Memoria dinámica.

Tipos de Datos Abstractos (TDA)

Ejercicios Tema 6. Funciones

Transcripción:

2013 ESTRUCTURAS DINÁMICAS DE DATOS (PILAS) EN C Departamento de Computación UNAN-León

TEMA 4: ESTRUCTURAS DINÁMICAS DE DATOS (PILAS) 4.1 INTRODUCCIÓN: En términos de listas lineales, una pila puede ser definida como, una lista lineal, en la que las inserciones y supresiones se hacen en un extremo de la lista. Por esto, las pilas son estructuras de datos de tipo LIFO (Last In, First Out): último en entrar, primero en salir. Esto sugiere la idea de una pila de platos, en la que se van apilando platos unos encima de otros. En un momento determinado, si nos decidiéramos a quitar un plato, el plato que quitaríamos será el último que pusimos en la pila, es decir, el plato que está más arriba; de ahí, el nombre de estructuras tipo LIFO. Una pila es un tipo especial de lista abierta en la que sólo se pueden insertar y eliminar nodos en uno de los extremos de la lista. Estas operaciones se conocen como "push" y "pop", respectivamente "empujar" y "tirar". Es evidente, que una pila es una lista lineal o abierta. Así que sigue siendo muy importante que nuestro programa nunca pierda el valor del puntero al primer elemento, igual que pasa con las listas lineales. Teniendo en cuenta que las inserciones y borrados en una pila se hacen siempre en un extremo, lo que consideramos como el primer elemento de la lista es en realidad el último elemento de la pila. Para empezar a comprender cómo funciona una pila, haremos uso de una estructura que incluya como campos, un array de elementos enteros y un variable tipo entero, que nos diga a cada momento, cuál es el tope de la pila. En este contexto, entenderemos por tope de la pila, la posición (índice) del arreglo en la que se encuentra el último elemento introducido a la pila. Dicho de otra forma, el tope de la pila incrementado en una unidad (recordar que los arreglos en C comienzan en la posición 0), nos indica el tamaño de la pila o la cantidad de elementos introducidos en la pila. 2

4.2 OPERACIONES BÁSICAS CON PILAS: Las pilas tienen un conjunto de operaciones muy limitado, sólo permiten las operaciones de "push" y "pop": Push: Añadir un elemento al final de la pila. Pop: Leer y eliminar un elemento del final de la pila. Las operaciones con pilas son muy simples, no hay casos especiales, salvo que la pila esté vacía. Los tipos que definiremos normalmente para manejar pilas serán casi los mismos que para manejar listas, tan sólo cambiaremos algunos nombres: typedef struct nodo int dato; struct nodo *siguiente; tiponodo; typedef tiponodo *pnodo; typedef tiponodo *Pila; Donde: tiponodo es el tipo para declarar nodos, evidentemente. pnodo es el tipo para declarar punteros a un nodo. Pila es el tipo para declarar pilas. 4.2.1 PUSH EN UNA PILA VACÍA: Partiremos de que ya tenemos el nodo a insertar y, por supuesto un puntero que apunte a él, además el puntero a la pila valdrá NULL: El proceso es muy simple, bastará con que: nodo->siguiente apunte a NULL. Pila apunte a nodo. 4.2.2 PUSH EN UNA PILA NO VACÍA: Podemos considerar el caso anterior como un caso particular de éste, la única diferencia es que debemos trabajar con una pila vacía como con una pila normal. De nuevo partiremos de un nodo a insertar, con un puntero que apunte a él, y de una pila, en este caso no vacía: El proceso sigue siendo muy sencillo: Hacemos que nodo->siguiente apunte a Pila. Hacemos que Pila apunte a nodo. 3

4.2.3 POP (LEER Y ELIMINAR UN ELEMENTO DE LA PILA): Ahora sólo existe un caso posible, ya que sólo podemos leer desde un extremo de la pila. Partiremos de una pila con uno o más nodos, y usaremos un puntero auxiliar, nodo: Hacemos que nodo apunte al primer elemento de la pila, es decir a Pila. Asignamos a Pila la dirección del segundo nodo de la pila: Pila->siguiente. Guardamos el contenido del nodo para devolverlo como retorno de la función (recordemos que la operación pop equivale a leer y borrar.) Liberamos la memoria asignada al primer nodo, el que queremos eliminar. Si la pila sólo tiene un nodo, el proceso sigue siendo válido, ya que el valor de Pila->siguiente es NULL, y después de eliminar el último nodo la pila quedará vacía, y el valor de Pila será NULL. 4

4.3 EJEMPLO #1 DE PILAS EN C: Algoritmo de la función "push": Creamos un nodo para el valor que colocaremos en la pila. Hacemos que nodo->siguiente apunte a Pila. Hacemos que Pila apunte a nodo. void Push(Pila *pila, int v) pnodo nuevo; /* Crear un nodo nuevo */ nuevo = (pnodo)malloc(sizeof(tiponodo)); nuevo->valor = v; /* Añadimos la pila a continuación del nuevo nodo */ nuevo->siguiente = *pila; /* Ahora, el comienzo de nuestra pila es en nuevo nodo */ *pila = nuevo; Algoritmo de la función "Pop": Hacemos que nodo apunte al primer elemento de la pila, es decir a Pila. Asignamos a Pila la dirección del segundo nodo de la pila: Pila->siguiente. Guardamos el contenido del nodo para devolverlo como retorno, recuerda que la operación pop equivale a leer y borrar. Liberamos la memoria asignada al primer nodo, el que queremos eliminar. int Pop(Pila *pila) pnodo nodo; /* variable auxiliar para manipular nodo */ int v; /* variable auxiliar para retorno */ /* Nodo apunta al primer elemento de la pila */ nodo = *pila; if(!nodo) /* Si no hay nodos en la pila retornamos 0 */ return 0; /* Asignamos a pila toda la pila menos el primer elemento */ *pila = nodo->siguiente; /* Guardamos el valor de retorno */ v = nodo->valor; /* Borrar el nodo */ free(nodo); return v; 5

Programa en C que muestra las operaciones que se realizan en una pila. #include <stdlib.h> #include <stdio.h> typedef struct _nodo int valor; struct _nodo *siguiente; tiponodo; typedef tiponodo *pnodo; typedef tiponodo *Pila; /* Funciones con pilas: */ void Push(Pila *l, int v); int Pop(Pila *l); int main() Pila pila = NULL; Push(&pila, 20); Push(&pila, 10); printf("%d, ", Pop(&pila)); Push(&pila, 40); Push(&pila, 30); printf("%d, ", Pop(&pila)); printf("%d, ", Pop(&pila)); Push(&pila, 90); printf("%d, ", Pop(&pila)); printf("%d\n", Pop(&pila)); system("pause"); return 0; /*Función para insertar un elemento en la pila*/ void Push(Pila *pila, int v) pnodo nuevo; /* Crear un nodo nuevo */ nuevo = (pnodo)malloc(sizeof(tiponodo)); nuevo->valor = v; /* Añadimos la pila a continuación del nuevo nodo */ nuevo->siguiente = *pila; /* Ahora, el comienzo de nuestra pila es en nuevo nodo */ *pila = nuevo; 6

/*Función para extraer un elemento de la pila*/ int Pop(Pila *pila) pnodo nodo; /* variable auxiliar para manipular nodo */ int v; /* variable auxiliar para retorno */ /* Nodo apunta al primer elemento de la pila */ nodo = *pila; if(!nodo) 0; /* Si no hay nodos en la pila retornamos 0 */ /* Asignamos a pila toda la pila menos el primer elemento */ *pila = nodo->siguiente; /* Guardamos el valor de retorno */ v = nodo->valor; /* Borrar el nodo */ free(nodo); return v; EJEMPLO #2 DE PILAS EN C: CALCULADORA CON NOTACIÓN POSTFIJA APLICANDO PILAS. Las operaciones de insertar y suprimir en una pila, son conocidas en los lenguajes ensambladores como push y pop respectivamente. La operación de recuperación de un elemento de la pila, lo elimina de la misma. Como ejemplo de utilización de una pila, vamos a simular una calculadora capaz de realizar las operaciones de +, -, * y /. La mayoría de las calculadoras aceptan la notación infija y unas pocas la notación postfija. Su principio es el de evaluar los datos directamente cuando se introducen y manejarlos dentro de una estructura LIFO (Last In First Out), lo que optimiza los procesos a la hora de programar. Básicamente la diferencias con el método algebraico o notación de infijo es que, al evaluar los datos directamente al introducirlos, no es necesario ordenar la evaluación de los mismos, y que para ejecutar un comando, primero se deben introducir todos sus argumentos, así, para hacer una suma 'a+b=c' el RPN lo manejaría a b +, dejando el resultado 'c' directamente.en estas últimas para sumar 10 y 20 introduciríamos primero 10, después 20 y por último el +. Cuando se introducen los operandos, se colocan en una pila y cuando se introduce el operador, se sacan dos operandos de la pila. La ventaja de la notación postfija es que expresiones complejas pueden evaluarse fácilmente sin mucho código. El programa realiza las siguientes operaciones: 1. Leer un dato, operando u operador, y lo almacena en la variable op. 2. Analiza op; si se trata de un operando lo mete en la pila utilizando la función push(); y si se trata de un operador extrae, utilizando la función pop() los dos últimos operandos de la pila, realiza la operación indicada por dicho operador e introduce el resultado en la pila para encadenarlo con otra posible operación. 7

La función push(), introduce un elemento al inicio de la pila. El método que sigue es simple y sencillo: 1. Crear un nuevo elemento y referenciarlo por q. 2. Apuntar con el puntero siguiente de q, a la cima de la pila. 3. Reasignar la cima de la pila, para que ahora apunte a q. La función pop(), sigue estos pasos para obtener un elemento de la pila: 1. Guarda en una variable auxiliar la cima de la pila. 2. Verifica el estado de la pila, y si está vacía, regresa 0. 3. Si la pila no está vacía, entonces 4. Obtiene en una variable x el dato que se encuentra en el elemento cima. 5. Reasigna la cima de la pila, para que ahora pase a apuntar adonde apunta su puntero siguiente. Luego de esta operación, la cima de la pila puede ser NULL, lo cual quiere decir que sólo había un elemento, o la cima es diferente de NULL, lo cual indica que había al menos dos elementos. 6. Libera el espacio de memoria de la cima antigua, referenciado por la variable auxiliar. 7. Regresa el valor de la variable x. Código en C de la calculadora con notación postfija //calculadorapostfija #include <stdio.h> #include <stdlib.h> #define PilaVacia (cima==null) /* Pila Vacia?*/ typedef struct datos /*Estructura de un elemento de la pila*/ float dato; struct datos *siguiente; elemento; /*Definición de Funciones*/ void error(void) perror("error: insuficiente espacio en memoria."); exit(1); elemento *NuevoElementoPila() elemento *q; q = (elemento *)malloc(sizeof(elemento)); if(q == NULL) error(); return(q); 8

/*Añadir un dato a la pila*/ void push(elemento **p, float x) elemento *q, *cima; cima = *p; /*cima de la pila*/ q=nuevoelementopila(); q->dato=x; q->siguiente=cima; cima=q; *p=cima; /*Recuperar un dato de la cima de la pila*/ float pop(elemento **p) elemento *cima; float x; cima = *p; /*cima o tope de la pila*/ if(pilavacia) printf("\nerror: pop de una pila vacia"); return 0; else x = cima->dato; *p = cima->siguiente; free (cima); return (x); void main() elemento *cima = NULL; /*Pila Vacia*/ float a,b,res; char op[2]; system("cls"); printf("calculadora con las operaciones + - * /\n"); printf("los datos seran introducidos de la forma: (operando1 operando 2 operador)\n"); printf(">operando 1:\n"); printf(">operando 2:\n"); printf("para salir pulse q.\n\n"); 9

do printf("> "); gets(op); switch(*op) case '+': a=pop(&cima); b=pop(&cima); res=a+b; printf("%f\n",res); push(&cima,res); break; case '-': a=pop(&cima); b=pop(&cima); res=a-b; printf("%f\n",res); push(&cima,res); break; case '*': a=pop(&cima); b=pop(&cima); res=a*b; printf("%f\n",res); push(&cima,res); break; case '/': a=pop(&cima); b=pop(&cima); if(b==0) printf("\n\adivision por cero\n"); break; res=a/b; printf("%f\n",res); push(&cima,res); break; default: push(&cima,atof(op)); while(*op!='q'); 10

Ejemplo de Salida: 11