UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf ·...

102
UNIVERSIDAD SALESIANA DE BOLIVIA CARRERA INGENIERIA DE SISTEMAS DOSSIER PROGRAMACION II Tercer Semestre Lic. Katya Maricela Pérez Martínez Lic. Gladys Francisca Chuquimia Mamani Lic. Juan Vito Condori 2012

Transcript of UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf ·...

Page 1: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

         

UNIVERSIDAD SALESIANA DE BOLIVIA

CARRERA INGENIERIA DE SISTEMAS

DOSSIER

PROGRAMACION II Tercer Semestre

Lic. Katya Maricela Pérez Martínez Lic. Gladys Francisca Chuquimia Mamani

Lic. Juan Vito Condori

2012

Page 2: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 2 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

INDICE 1. Capítulo I. Introducción a las Estructuras de Datos 1

1.1. Introducción 1 1.2. Estructuras Fundamentales 1 1.3. Abstracción 2 1.4. Definición de Estructuras de datos 2 1.5. T.D.A. (Tipo de Dato Abstracto) 2 1.6. Clasificación de las Estructuras de Datos 2 1.7. Estructuras de Datos Estáticas 4 1.8. Registros 18 1.9. Conjuntos 24

1.9.1. Definición de Conjuntos 24 1.10. Matrices poco densas 24 1.11. Archivos 26 1.12. Ejercicios propuestos 32

2. Capítulo II: Pilas 36

2.1. Introducción 36 2.2. Representación de las Pilas 37 2.3. Operaciones con pilas 38 2.4. Operaciones adicionales 39 2.5. Aplicaciones 43

2.5.1. Llamadas a subprogramas 43 2.5.2. Recursión 45

2.6. Ejercicios Propuestos 46 3. Capitulo III: Colas 47

3.1. Introducción 47 3.2. Características 48 3.3. Representación de las colas 48 3.4. Estructura de una cola 48 3.5. Operaciones con colas 49 3.6. Colas circulares 53 3.7. Operaciones con colas circulares 54 3.8. Aplicación de Pilas y Colas 55 3.9. Ejercicios 56

4. Capitulo IV: Recursividad 58 4.1. Introducción 58

Page 3: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 3 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

4.2. Ámbito de aplicación 58 4.3. Razones de uso 58 4.4. ¿En qué consiste la recursividad? 59 4.5. Forma de Enfrentar problemas recursivos 59 4.6. Tipos de recursividad 61 4.7. La pila de recursion 62 4.8. La llamada a una función 63 4.9. Ejercicios 63

5. Listas Enlazadas 65 5.1. Introducción a las Estructuras de datos dinámica 65 5.2. Mecanismos para enlazar información 66 5.3. El tipo puntero 67 5.4. Tipo de dato abstracto Nodo 72 5.5. Punteros 72

5.5.1. Operador -> 72 5.6. Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78

6. Capítulo IV: Árboles y Grafos 79 6.1. Introducción 79 6.2. Conceptos Básicos 79 6.3. Árboles Binarios 81 6.4. Representación de árboles binarios 82 6.5. Recorridos 83 6.6. Árboles Binarios de Búsqueda (Abb) 86 6.7. Operaciones sobre árboles binarios de búsqueda 86 6.8. Árboles ordenados 90 6.9. Grafos 91

6.9.1. Definiciones Básicas 91 6.10. Ejercicios 95

7. Lecturas Complementarias 97 8. Glosario 102

Page 4: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

Capítulo I

Introducción a las Estructuras De Datos

1.1. Introducción Para procesar información en un computador es necesario hacer una abstracción de los datos que tomamos del mundo real, abstracción en el sentido de que se ignoran algunas propiedades de los objetos reales, es decir, se simplifican. Se hace una selección de los datos más representativos de la realidad a partir de los cuales pueda trabajar el computador para obtener unos resultados. Cualquier lenguaje suministra una serie de tipos de datos simples, como son los números enteros, caracteres, números reales. En realidad suministra un subconjunto de éstos,

Asamblea en la carpintería  

 Cuentan  que  en  la  carpintería  hubo  una  vez  una  extraña  asamblea.  Fue  una  reunión  de  herramientas  para  arreglar  sus diferencias. El martillo ejerció la presidencia, pero la asamblea le notificó que tenía que renunciar.  ¿La causa? ¡Hacía demasiado ruido! Y, además, se pasaba el tiempo golpeando.   El martillo aceptó su culpa, pero pidió que también fuera expulsado el tornillo; dijo que había que darle muchas vueltas para que sirviera de algo.   Ante el ataque, el tornillo aceptó también, pero a su vez pidió la expulsión de la lija. Hizo ver que era muy áspera en su trato y siempre tenía fricciones con los demás.   Y la lija estuvo de acuerdo, a condición de que fuera expulsado el metro que siempre se la pasaba midiendo a los demás según su medida, como si fuera el único perfecto.   En eso entró el carpintero, se puso el delantal e inició su trabajo.  Utilizó el martillo, la lija, el metro y el tornillo.   Finalmente, la tosca madera inicial se convirtió en un lindo mueble.   Cuando  la carpintería quedó nuevamente sola,  la asamblea reanudó  la deliberación. Fue entonces cuando tomó  la palabra el serrucho, y dijo: "Señores, ha quedado demostrado que tenemos defectos, pero el carpintero  trabaja con nuestras cualidades. Eso es lo que nos hace valiosos. Así que no pensemos ya en nuestros puntos malos y concentrémonos en la utilidad de nuestros puntos buenos".   La asamblea encontró entonces que el martillo era fuerte, el tornillo unía y daba fuerza, la lija era especial para afinar y limar asperezas y observaron que el metro era preciso y exacto.   Se sintieron entonces un equipo capaz de producir muebles de calidad. Se sintieron orgullosos de sus  fortalezas y de trabajar juntos. 

Anónimo

Page 5: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 2 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

pues la memoria del ordenador es finita. Los punteros (si los tiene) son también un tipo de datos. El tamaño de todos los tipos de datos depende de la máquina y del compilador sobre los que se trabaja.

1.2. Estructuras Fundamentales Los datos a procesar por una computadora se clasifican en:

Simples Estructurados

Los datos simples ocupan sólo una casilla de memoria, por tanto una variable simple hace referencia a un único valor a la vez. Los datos Estructurados o Compuestos se caracterizan por el hecho de que con un nombre (identificador de variable estructurada) se hace referencia a un grupo de casillas de memoria. Tiene varios componentes.

Ejemplos: Dato Simple Declaramos una variable A de tipo entero y asignamos el valor 25.

A Identificador int A;

A = 25;

Dato Estructurado Declaramos un dato compuesto o estructurado A que tendrá 5 elementos de tipo entero.

25

Cabe hacer notar que en el presente texto, se tomará como herramienta para los programas y representar las diferentes estructuras de datos el Lenguaje C++ y Java.

Page 6: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 3 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

int A[5] ;

A = {20,30,40,50,60}; A =

1.3. Abstracción Una abstracción es un proceso mental donde se extraen rasgos esenciales de algo para representarlos por medio de un lenguaje gráfico o escrito.

1.4. Definición de Estructuras de Datos Una estructura de datos es cualquier colección de datos organizados de tal forma que tengan asociados un conjunto de operaciones para poder manipularlos.

1.5. T.D.A. (Tipo de Dato Abstracto) Al diseñar una estructura de datos con la técnica de abstracción pasa a ser un TDA, que:

Puede implementarse en cualquier lenguaje Puede aplicarse en cualquier concepto

Ejemplo: Abstraemos el concepto Estudiante Nombre del TAD Elementos Operaciones o métodos Como se puede notar existe una operación No Permitida denominada: CalcularNotaFinal(); que no debiera estar presente en el TAD, debido a que no se cuenta con elementos que nos permitan realizar esta operación.

              ESTUDIANTE Ru: entero Nombre: Cadena Sexo: carácter Direccion: Cadena  LeerDatosEstudiante () ImprimirDatosEstudiante () ModificarDireccion() CalcularNotaFinal() 

20 30 40 50 60

Identificador

Page 7: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 4 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Recuerda en todo momento que sólo deben incluirse las operaciones que puedan trabajar con los elementos que contiene el TAD.

1.6. Clasificación de las Estructuras de Datos Las estructuras de datos desde el punto de vista de asignación de memoria, se clasifican

en:

Estructuras de datos estáticas

Estructuras de datos dinámicas

También pueden ser clasificadas en:

Estructuras Lineales

Estructuras No Lineales

1.6.1. Estructuras de Datos Estáticas Son aquellas en las que el tamaño ocupado en memoria se define antes de que el programa se ejecute y no puede modificarse dicho tamaño durante la ejecución del programa. Por ejemplo tenemos a los Arreglos, Registros y Conjuntos.

1.6.2. Estructuras de Datos Dinámicas Las estructuras dinámicas de datos son estructuras que cuya dimensión puede crecer o disminuir durante la ejecución del programa. Por ejmplos: Listas Enlazadas, Árboles y Grafos.

1.6.3. Estructuras de Datos Lineales Las estructuras de datos lineales se derivan del concepto de secuencia. Primero se definen las secuencias como conjuntos de elementos entre los que se establece una relación de predecesor y sucesor. Los diferentes TADs basados en este concepto se diferenciaran por las operaciones de acceso a los elementos y manipulación de la estructura. Desde el punto de vista de la informática, existen tres estructuras lineales especialmente importantes: vectores, las pilas, las colas y las listas.

1.6.4. Estructuras de Datos No Lineales Se denominan estructuras de datos No Lineales porque a cada elemento le pueden seguir varios elementos o puede estar rodeado de elementos. Por ejemplo: Árboles, Grafos y Matrices

Page 8: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 5 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

1.7. Estructuras de Datos Estáticas

1.7.1. Arreglos Definición: Colección finita, homogénea y ordenada de elementos. Finita: Porque todo arreglo tiene un límite. Homogénea: Porque todos los elementos son del mismo tipo. Ordenada: Porque se puede determinar cuál es el enésimo elemento. Un arreglo tiene dos partes: Componentes e índices

C1 C2 … Cn i0 i1 … iN

Componentes: Hacen referencia a los elementos que forman el arreglo. Índices: Permiten referirse a los componentes del arreglo en forma individual.

1.7.2. Arreglos Unidimensionales (Vectores) Son los arreglos más simples y constan de un solo índice, también se llaman vectores. Notación: Podría ser de diferentes maneras. Por ejemplo:

Array [0...9] de enteros: Vector Vector: C componente

30 50 70 60 0 1 2 … 8 Identificador Indice Donde, C hace referencia a todo el vector, mientras que los índices hacen referencia a los

elementos en forma individual.

1.7.3. Declaración de vectores En Java

Para declarar un Array se utilizan corchetes para indicar que se trata de un Array y no de

una simple variable de tipo especificado. Su sintaxis es:

Componentes

Indices

C =

Tipo_dato identificador[ ];

Page 9: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 6 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

O bien:

Donde:

Tipo_dato: es el tipo de datos de los elementos del vector.

Identificador: es el nombre del vector.

Luego, se debe crear el Array con el operador new, de la siguiente manera:

Por ejemplo:

El programa: Array.java, trabaja con el vector losValores, que almacena un máximo de

10 elementos enteros.

Implementación del TAD Vector Este es el diseño del TAD vector que maneja números enteros.

Ejercicios A continuación se muestra la implementación de este TAD en Java.

En lenguaje java:

public class Array { public static void main (String arg []) { int losValores []; losValores = new int [10]; losValores [0] = 100; System.out.println (losValores [0]); } }

Archivo: Array.java

Tipo_dato [ ] identificador;

Identificador = new tipo [ cantidad_de_elementos ];

VECTOR V[15]: Entero N: Entero leedim() leervector() mostrarvector()

Page 10: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 7 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

//ARCHIVO VECTOR.JAVA import java.io.*; public class Vector { static int v[]; static int n; static InputStreamReader Caracteres; static BufferedReader Buffer; static String dato; static void leedim () throws IOException { System.out.println ("Cuantos elementos insertara en el Vector? "); dato = Buffer.readLine (); n = Integer.parseInt (dato); } static void leervector () throws IOException { int i; for(i=0; i < n; i++) { System.out.println("Ingrese elemento "+ i + " = "); dato = Buffer.readLine(); v[i] = Integer.parseInt(dato); } } static void mostrarvector () throws IOException { int i; for(i=0; i < n; i++) { System.out.print(v[i] + " "); } } public static void main (String [] args) throws IOException { v = new int[15]; Caracteres = new InputStreamReader (System.in); Buffer = new BufferedReader(Caracteres); leedim (); leervector(); mostrarvector(); } }

Page 11: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 8 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

EJERCICIOS EN LENGUAJE C 1. Queremos efectuar estadísticas con una serie de valores (las edades de 15 personas).

En una primera versión, solicitaremos las edades de todas las personas y, a continuación,

calcularemos y mostraremos por pantalla la edad media, la desviación estándar, la moda

y la mediana. Las fórmulas para la media y la desviación estándar son:

15

15

1∑ == i ixx 15

)(15

12∑ =

−= i i xx

δ

Donde Xi es la edad del individuo número i.

Se diseña a continuación el TAD.

//ARCHIVO EJERCICIO1.CPP #include <conio.h> #include <iosteam.h> #include <math.h> #define PERSONAS 15 struct ESTADISTICA { int E[PERSONAS]; void LeerEdades(void); void ImprimirEdades(void); void CalculaMedia(void); void CalculaDesviacion(void); }; void ESTADISTICA::LeerEdades(void) { //Lectura de edades for (int i=0; i<PERSONAS; i++) {

ESTADISTICA E[15]: Entero LeerEdades() ImprimirEdades() CalculaMedia() CalculaDesviacion()

Page 12: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 9 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

cout<<"Por favor, introduce la edad de la persona nïumero"<< i; cin>>E[i]; } //fin del for } // fin de IngresarDatos void ESTADISTICA::ImprimirEdades(void) { //imprime edades for (int i=0; i<PERSONAS; i++) { cout<<E[i]<<” - “; } //fin del for } // fin de IngresarDatos

// Calculo de la media void ESTADISTICA::CalculaMedia(void) { double sumaedad = 0, media; for (int i=1; i<=PERSONAS; i++) sumaedad = sumaedad +edad[i]; media =(double) sumaedad / PERSONAS; cout<<”La media de las edades es……”<< media; } // Calculo de la desviación estándar void ESTADISTICA::CalculaDesviacion(void) { double desviacion, sumadesviacion = 0.0; for (int i=0; i<PERSONAS; i++) sumadesviacion = sumadesviacion+(edad[i]-media)*(edad[i] - media); desviacion = sqrt(sumadesviacion / PERSONAS ); cout<<”La desviación estándar es….”<<desviación; } void main(void ) { ESTADISTICA Es; clrscr(); Es.LeerEdades(); Es.ImprimirEdades(); Es.CalculaMedia(); Es.CalculaDesviacion(); getch(); }

Page 13: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 10 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

1.7.4. Cadenas de Caracteres Los arreglos de caracteres tienen varias características únicas. Un arreglo de caracteres puede inicializarse de la siguiente forma:

• El tamaño de CADENA1 está determinado por el compilador, y generalmente es de

256 caracteres máximo.

• La cadena "rosa" contiene cuatro caracteres, más un caracter especial de terminación denominado caracter nulo (' \0 ').

• Los arreglos de caracteres pueden inicializarse también con constantes individuales

dentro de una lista. • También podemos colocar una cadena de caracteres directamente dentro de un

arreglo de caracteres desde el teclado. Por ejemplo: char CAD2[20];

cin >> CAD2;

EJERCICIO 1. El programa puede parecer a primera vista muy sencillo. En primer lugar vamos a leer y escribir una cadena. La primera solución intuitiva:

char CADENA1[ ] = "rosa";

char CADENA1[ ]= {' r ', ' o ', ' s ', ' a ', ' \0 ' };

#include <iostream> // USAMOS: cin, cout

void main() { char s[20]; // Cadena de hasta 19 caracteres cin >> s; // Leer la primera palabra cout << endl << s // Escribir en nueva línea la cadena << endl; // Y pasar a la línea siguiente }

Page 14: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 11 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

EJERCICIO 1. Programa para leer caracteres desde teclado hasta que el caracter sea nulo EJERCICIO 3. Bien, ahora veamos un ejemplo tradicional, se trata de leer caracteres desde el teclado y contar cuántos hay de cada tipo. Los tipos que deberemos contar serán: consonantes, vocales, dígitos, signos de puntuación, mayúsculas, minúsculas y espacios. Cada carácter puede pertenecer a uno o varios grupos. Los espacios son utilizados frecuentemente para contar palabras.

#include <iostream.h> // Usamos: ios, cin, cout #include <iomanip.h> // Usamos: resetiosflags void Leer_Cadena(char * s) { cin >> resetiosflags(ios::skipws); // Para que no pase los caracteres blancos. for (int i= 0; cin >> s[i]; i++) // Leer caracteres hasta el caracter nulo. if (s[i] == '\n') break; s[i]= '\0'; // Pone el caracter de fin de cadena. } void main() { char s[100]; // Buffer de capacidad de hasta 99 caracteres y '\0'. Si // metemos mas caracteres hay posibilidad de 'cuelgue' cout << endl << "Introduce una cadena (termina con CTRL-Z o INTRO)" << endl; Leer_Cadena(s); cout << endl << "La cadena es: " << s << endl; }

Page 15: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 12 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

// Cuenta letras #include <iostream.h> #include <ctype.h> int main() { int consonantes = 0; int vocales = 0; int digitos = 0; int mayusculas = 0; int minusculas = 0; int espacios = 0; int puntuacion = 0; char c; // caracteres leidos desde el teclado cout << "Contaremos caracteres hasta que se pulse ^Z" << endl; while((c = getchar()) != EOF) { if(isdigit(c)) digitos++; else if(isspace(c)) espacios++; else if(ispunct(c)) puntuacion++; else if(isalpha(c)) { if(isupper(c)) mayusculas++; else minusculas++; switch(tolower(c)) { case 'a': case 'e': case 'i': case 'o': case 'u': vocales++; break;

default: consonantes++; } } } cout << "Resultados:" << endl; cout << "Dígitos: " << digitos << endl; cout << "Espacios: " << espacios << endl; cout << "Puntuación: " << puntuacion << endl; cout << "Alfabéticos: " << mayusculas + minusculas<< endl; cout << "Mayúsculas: " << mayusculas << endl; cout << "Minúsculas: " << minusculas << endl; cout << "Vocales: " << vocales << endl; cout << "Consonantes: " << consonantes << endl; cout << "Total: " << digitos + espacios + vocales + consonantes + puntuacion << endl; return 0;

}

Page 16: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 13 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

1.7.5. Arreglos Multidimensionales Existe en la mayoría de los lenguajes una estructura de arreglos multidimensionales. El número de dimensiones (índices) permitido depende del lenguaje elegido.

1.7.5.1. Matrices Una matriz es un arreglo de dos dimensiones, y para especificar cualquier elemento, debemos hacer referencia a dos índices (que representan la posición como renglón y columna). Aunque no se justificará aquí, es conveniente mencionar que la representación matricial es puramente conceptual y con el único fin de facilitar al programador el manejo de los elementos, ya que la computadora almacena los datos en una forma totalmente diferente Se analizarán primero los arreglos bidimensionales (caso especial de los multidimensionales) por ser los mas utilizados.

• C++ soporta hasta arreglos con 12 dimensiones. En arreglos de dos dimensiones, el primer elemento representa el renglón y el segundo la columna.

• Cada elemento de un arreglo bidimensional puede referenciarse de la siguiente

manera: arreglo [ i ] [ j ].

• Un arreglo multidimensional puede inicializarse desde su declaración. Por ejemplo, un arreglo bidimensional b[2][2] puede declararse e inicializarse así:

int b[2][2] = { {1,2} , {3,4} };

• Los valores son agrupados en renglones.

Declaración de una Matríz La sintaxis en el lenguaje C++ es el siguiente: donde:

• tipo puede ser cualquier tipo de dato (int, float, char, etc.).

tipo nombre_de_variable [rango1][rango2];

Page 17: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 14 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

• nombre_de_variable es el nombre del arreglo. • rango 1 corresponde al número de renglones que conforman el arreglo. • rango 2 corresponde al número de columnas. Podemos trabajar con cada uno de los elementos de la matriz:

X[3][5] = 20;

Operaciones con arreglos bidimensionales Las operaciones que pueden realizarse con arreglos bidimensionales son las siguientes:

• Lectura/escritura • Asignación • Actualización: Inserción

Eliminación Modificación

• Ordenación • Búsqueda

En general los arreglos bidimensionales son una generalización de los unidimensionales, por lo que se realizará un ejemplo con algunas de estas operaciones a continuación. Ejemplo: La Tabla contiene gastos que registra una ama de casa correspondientes a los 12 meses del año anterior. Meses/Gastos Agua Luz Telefono Mercado Enero 23 57 840 250 Febrero 28 60 560 280 Marzo 34 55 400 275 Abril 24 87 700 340 Mayo 29 80 450 310 Junio 34 65 670 320 Julio 45 67 560 325 Agosto 48 78 570 323 Septiembre 32 54 540 290 Octubre 33 50 250 300 Noviembre 35 70 330 350 Diciembre 38 62 300 430 Es posible interpretar esta tabla de la siguiente manera: dado un mes, se conocen los gasto realizados por la ama de casa; y dado un gasto se conocen los gastos mensuales. El programa será el siguiente:

Page 18: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 15 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

// PROCEDIMIENTO PARA IMPRIMIR TODOS LOS GASTOS DE LA // MATRIZ G void Imprime_Gastos(MATRIZ G, int m, int g) { for (int i=1; i<=m; i++) { for(int j=1; j<=n; j++) cout<<G[i][j]<<” “; cout<<”\n”; } } //PROCEDIMIENTO PARA LISTAR SUMAR TODOS LOS GASTOS DE TODO EL AÑO void Suma_Gastos (MATRIZ G, int m, int g) { int TotalGastos=0;

for (int i=1; i<=m; i++) for(int j=1; j<=n; j++) TotalGastos = TotalGastos + G[i][j]; Cout<<”\n \n EL TOTAL DE GASTOS DEL AÑO ES...”<<TotalGastos; } //PROGRAMA PRINCIPAL void main(void) { MATRIZ GASTOS ; clrscr() ; Lee_Gastos (GASTOS, 12, 4) ; //lee gastos para 12 meses y 4 gastos Imprime_Gastos (GASTOS, 12,4); //Imprime los gastos de la matriz Suma_Gastos(GASTOS, 12,4); getch(); }

#iclude<iostream.h> #include<conio.h> typedef int MATRIZ[13][5]; //definimos un tipo de dato MATRIZ de números enteros //PROCEDIMIENTO PARA REGISTRAR LOS GASTOS EN LA MATRIZ G //DE DIMENSIONES m filas y g columnas void Lee_gastos(MATRIZ G, int m, int g) { int i; //contador de meses int j; //contador de columnas de gasto for ( i= 1; i<=m ; i++) for ( j=1; j<=g; j++) { cout<<”\n Ingrese el gasto del mes “<< i << “gasto ”<< j<<; cin>>G[i][j]; } }

Page 19: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 16 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

1.8. Registros (Estructuras) Cuando se habló de los arreglos se mencionó que se trataba de una colección de datos, todos del mismo tipo, que era un tipo estructurado de datos, y que son ellos se podía solucionar un gran número de problemas. Sin embargo, en la práctica a veces se necesitan estructuras que permitan almacenar distintos tipos de datos (característica con la cual no cuentan los arreglos). Ejemplo Una compañía tiene por cada empleado los siguientes datos: • Nombre (cadena de caracteres) • Dirección (cadena de caracteres) • Edad (entero) • Sexo (carácter) • Antigüedad (entero) Si lo vemos gráficamente estos datos tenemos;

Nombre Direccion Nom Pat Mat Calle Nro Zona Edad Sexo Antig Juan Maria

RodríguezAlvarez

Salas Vargas

Av. Arce Calle 12

123 1345

Central Obrajes

25 29

M F

2 3

Si se quisiera almacenar estos datos no sería posible usar un arreglo, ya que sus componentes deben ser todos del mismo tipo.

1.8.1. Definición De Registro y declaración de la variable de registro.

Un registro es un dato estructurado, donde cado uno de sus componentes se denomina campo. Los campos de un registro pueden ser todos de diferentes tipos. Por lo tanto también podrán ser registros o arreglos. Cada campo se identifica por un nombre único (el identificador de campo). No se establece orden entre los campos. Para definir un registro en el lenguaje C, utilizamos la siguiente sintaxis:

Page 20: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 17 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Donde: Nom_Registro: Es el nombre o identificador del registro. campoi: Es el nombre del campo i tipo_datoi: es el tipo de dato del campo i. EJEMPLO Definir la estructura para los datos de un empleado y luego declarar la variable de registro.

1.8.2. Acceso a los Campos De Un Registro Como un registro es un dato estructurado no puede accecsarse directamente como un todo, sino que debe especificarse qué elemento (campo) del registro interesa. Para ello, en la mayoría de los lenguajes se sigue la siguiente sintaxis: Variable_registro.campo

struct Nom_Registro { tipo_dato1 campo1; tipo_dato1 campo2;

tipo_daton campon; }; //declaración de la variable Variable_registro de tipo // Nom_Registro Nom_Registro Variable_registro ;

struct EMPLEADO { char nombre[20]; char direccion[30]; int edad;

int antigüedad: char sexo;

}; EMPLEADO E ;

Page 21: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 18 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Ejemplo: Escribir un programa para leer los registros de N empleados de una empresa.

#include<iostream.h> #include<conio.h> struct EMPLEADO { char nombre[20]; char direccion[30]; int edad;

int antiguedad: char sexo;

}; //PROCEDIMIENTO PARA LEER LOS DATOS DE UN EMPLEADO EMPLEADO LeeEmpleado (void) { EMPLEADO E; cout<<”\n Nombre del Empleado “; cin>> E.nombre; cout<<”\n Dirección del Empleado “; cin>> E.direccion; cout<<”\n Edad del Empleado “; cin>> E.edad; cout<<”\n Antigüedad del Empleado “; cin>> E.antiguedad; cout<<”\n Sexo del Empleado “; cin>> E.sexo; return ( E ); } // PROCEDIMIENTO PARA IMPRIMIR LOS DATOS PARA UN EMPLEADO void ImprimeEmpleado (EMPLEADO E) { cout<<”\n NOMBRE : “<<E.nombre; cout<<”\n DIRECCION : “<<E.direccion; cout<<”\n EDAD : “<<E.edad; cout<<”\n ANTIGUEDAD : “<<E.antiguedad; cout<<”\n SEXO : “<<E.sexo; } // PROCEDIMIENTO LEER LOS DATOS DE LOS EMPLEADOS EN UN VECTOR void Lee_N_Empleados (EMPLEADO VE[50], int N) { //llena el vector de empleados VE con registros de N empleados for (int i=1; i<= N; i++) { cout<<”\n INTRODUZCA LOS DATOS DEL EMPLEADO “<<i<<endl; VE[i]= LeeEmpleado(); } } // PROCEDIMIENTO IMPRIMIR LOS DATOS DE LOS EMPLEADOS EN UN VECTOR void Imprime_N_Empleados (EMPLEADO VE[50], int N) { for (int i=1; i<= N; i++) { cout<<”\n EMPLEADO “<<i<<endl; ImprimeEmpleado( VE[i]); } getch(); }

Page 22: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 19 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

1.8.3. Funciones en el interior de estructuras: C++, al contrario que C, permite incluir funciones en el interior de las estructuras. Normalmente estas funciones tienen la misión de manipular los datos incluidos en la estructura. Aunque esta característica se usa casi exclusivamente con las clases, como veremos más adelante, también puede usarse en las estructuras. Dos funciones muy particulares son las de inicialización, o constructor, y el destructor. Veremos con más detalle estas funciones cuando asociemos las estructuras y los punteros.

1.8.4. Asignación de estructuras: La asignación de estructuras está permitida, pero sólo entre variables del mismo tipo de estructura, salvo que se usen constructores, y funciona como la intuición dice que debe hacerlo. Veamos un ejemplo: La línea:

//PROGRAMA PRINCIPAL void main (void) { EMPLEADO ve[50]; int N; clrscr( );

cout<<”\n Cuantos empleados desea registrar ?”; cin >>N;

Leer_N_Empleados (ve , N); Imprimir_N_Empleados (ve, N); getch( ); }

struct Punto { int x, y; Punto() {x = 0; y = 0;} } ; Punto Punto1, Punto2; int main() { Punto1.x = 10; Punto1.y = 12; Punto2 = Punto1; }

Page 23: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 20 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Punto2 = Punto1;

equivale a:

Punto2.x = Punto1.x;

Punto2.y = Punto1.y;

1.8.5. Arrays de estructuras: La combinación de las estructuras con los arrays proporciona una potente herramienta para el almacenamiento y manipulación de datos. Ejemplo: Vemos en este ejemplo lo fácil que podemos declarar el array Plantilla que contiene los datos relativos a doscientas personas. Podemos acceder a los datos de cada uno de ellos: cout << Plantilla[43].Direccion;

O asignar los datos de un elemento de la plantilla a otro: Plantilla[0] = Plantilla[99];

1.8.6. Estructuras anidadas: También está permitido anidar estructuras, con lo cual se pueden conseguir superestructuras muy elaboradas.

struct Persona { char Nombre[65]; char Direccion[65]; int AnyoNacimiento; }; Persona Plantilla[200];

Page 24: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 21 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Ejemplo: Definiremos una estructura para persona con los datos: Nombre (nombre de pila, paterno, materno), Direccion (Calle, nro y zona) y telefono.

En general, no es una práctica corriente definir estructuras dentro de estructuras, ya que resultan tener un ámbito local, y para acceder a ellas se necesita hacer referencia a la estructura más externa. Por ejemplo para declarar una variable del tipo stNombre hay que utilizar el operador de acceso (::):

stPersona::stNombre NombreAuxiliar;

Sin embargo para declarar una variable de tipo stDireccion basta con declararla:

stDireccion DireccionAuxiliar;

1.9. Conjuntos El conjunto es también un tipo de dato estructurado. Puede definirse un conjunto como una colección de objetos del mismo tipo base. El tipo base puede ser solamente un tipo ordinal (enteros, caracteres, enumerados y subrangos).

struct stDireccion { char Calle[64]; int Nro; char Zona[32]; }; Struct stNombre { char nom[20]; char pat[20]; char mat[25]; }; struct stPersona { stNombre Nomb; stDireccion Direccion; long int Telefono; }; ...

Page 25: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 22 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

1.9.1. Definición De Conjuntos Los conjuntos serán definidos de la siguiente manera: Ident_conjunto = CONJUNTO DE tipo_base Donde: Tipo_base es cualquier tipo ordinal de dato. Ejemplo: Se definen los conjuntos NUMEROS, MAYUSCULAS y ALUMNOS. NUMEROS es el tipo conjunto formado por todos los números enteros comprendidos entre el 1 y el 50 inclusive. MAYUSCULAS es el tipo conjunto formado por las letras mayúsculas, y finalmente ALUMNOS es el tipo conjunto formado por todos los elementos del tipo enumerado NOMBRES. NOMBRES = (Juan, Jose, Julio,Javier) NUMEROS = CONJUNTO DE 1..50

MAYUSCULAS = CONJUNTO DE ‘A’..’Z’ ALUMNOS = CONJUNTO DE nombres

1.10. Matrices Poco Densas Matriz es un término matemático utilizado para definir un conjunto de elementos organizados por medio de renglones y columnas, equivalente al término arreglo bidimensional utilizado en computación. Poco Densa indica una proporción muy alta de ceros entre los elementos de la matríz. Es decir una matriz poco densa es aquella que tiene gran cantidad de elementos ceros. Ejemplo: La matriz A de 4 filas por 4 columnas, del total de elementos que es 16, solo 4 de ellos son diferentes de cero.

0 1 1 0 0 0 1 0 0 1 0 0 0 1 0 0

A =

Page 26: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 23 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Existen diversos métodos para almacenar los valores diferentes de cero de una matríz poco densa. A continuación presentamos uno de ellos. Arreglo de Registros Se utiliza un arreglo unidimensional, donde cada elemento es un registro formado por tres campos: uno para guardar la fila donde se encontró el valor diferente de cero, otro para guardar la columna, y el tercero para guardar el valor del elemento distinto de cero de la matriz. El siguiente programa nos permite registrar una matriz poco densa

#include<iostream.h> #include<conio.h> struct PocoDensa { int fila; int col; int valor; }; //PROCEDIMIENTO PARA LLENAR LA MATRIZ POCO DENSA void LeePocoDensa( PocoDensa PD[20]) { int F, C, k; int e; cout<< “\n Cual es la dimensión de la matríz poco densa (filas y columnas) ” cin>>M>>N; k=1; for (int i= 1; i<= F; i++) for (int j=1; j<=C;j++) { cout<< “\n Ingrese el elemento ”<<i<<” “<<j<<” “; cin>>e; if (e != 0) { PD[k].fila = i; PD[k].col =j; PD[k].valor = e; k++; } PD[0].fila = F ; PD[0].col = C; PD[0].valor= k-1; } //PROGRAMA PRINCIPAL void main (void) { PocoDensa M[20]; //M es un vector de registros clrscr() ; LeePocoDensa(M) ; getch() ; }

Page 27: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 24 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

1.11. Archivos • El almacenamiento de datos en variables y arreglos es temporal; al terminar un

programa todos estos datos se pierden. Para la conservación permanente de grandes cantidades de datos se utilizan los archivos.

• Las computadoras almacenan los archivos en dispositivos de almacenamiento

secundario, especialmente en discos.

• C ve cada uno de los archivos simplemente como un flujo secuencial de bytes. Cada archivo termina con un marcador de fin de archivo.

• Abrir un archivo regresa un apuntador a una estructura FILE (definida en

<stdio.h>) que contiene información utilizada para procesar dicho archivo.

Modos de apertura de archivos w :Para crear un archivo, o para descartar el contenido de un archivo antes de escribir

datos. r :Para leer un archivo existente. a :Para añadir registros al final de un archivo existente. r+ :Para abrir un archivo de tal forma que pueda ser escrito y leído (abre un

archivo de lectura y escritura para actualizar) w+ :Genera un archivo para lectura y escritura. Si el archivo ya existe, se abre y el

contenido se descarta a+ :Abre un archivo para lectura y escritura - toda escritura se efectuará al final del

archivo. Si no existe, será creado. Si al abrir un archivo en cualquiera de los modos anteriores ocurre un error, fopen regresará NULL. EJEMPLO ARCHIVO DE TEXTO CREACION Y LECTURA. Lee y escribe en un archivo de texto de n números sus cubos.

Page 28: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 25 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

//ARCHIVOS DE TEXTO #include<iostream.h> #include<conio.h> #include<process.h> #include<stdio.h> FILE *Miarch; void crear(void) { int a,n; if ( (Miarch=fopen("C:\\prueba.dat","w"))==NULL) { cout<<"no se puede abrir el archivo \n"; exit(1); } else { cout<<"Cuantos numeros quieres introducir al archivo "<<endl; cin>>n; for (int i=1; i<=n; i++) { a=i*i*i; fprintf(Miarch,"\n %d %d",i,a); } fclose(Miarch); } } void leer(void) { int a,b; if ((Miarch=fopen("c:\\prueba.dat","r"))==NULL) { cout<<"no se puede abrir el archivo "<<endl; exit(1); } else { cout<<"\n n n^3"; fscanf(Miarch,"%d%d",&a,&b); while (!feof(Miarch)) { cout<<"\n "<<a<<" "<<b; fscanf(Miarch,"%d%d",&a,&b); } fclose(Miarch); } } void main(void) { clrscr(); crear(); leer(); }

Page 29: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 26 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

// Ejemplo de ficheros de acceso aleatorio. #include <stdio.h> #include <stdlib.h> struct stRegistro { char valido; // Campo que indica si el registro es válido S->Válido, N->Inválido char nombre[34]; int dato[4]; }; int Menu(); void Leer(struct stRegistro *reg); void Mostrar(struct stRegistro *reg); void Listar(long n, struct stRegistro *reg); long LeeNumero(); void Empaquetar(FILE **fa); int main() { struct stRegistro reg; FILE *fa; int opcion; long numero; fa = fopen("alea.dat", "r+b"); // Este modo permite leer y escribir if(!fa) fa = fopen("alea.dat", "w+b"); // si el fichero no existe, lo crea. do { opcion = Menu(); switch(opcion) { case '1': // Añadir registro Leer(&reg); // Insertar al final: fseek(fa, 0, SEEK_END); fwrite(&reg, sizeof(struct stRegistro), 1, fa); break; case '2': // Mostrar registro system("cls"); printf("Mostrar registro: "); numero = LeeNumero(); fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET); fread(&reg, sizeof(struct stRegistro), 1, fa); Mostrar(&reg); break; case '3': // Eliminar registro system("cls"); printf("Eliminar registro: "); numero = LeeNumero(); fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET); fread(&reg, sizeof(struct stRegistro), 1, fa); reg.valido = 'N'; fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET);

Page 30: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 27 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

fwrite(&reg, sizeof(struct stRegistro), 1, fa); break; case '4': // Mostrar todo rewind(fa); numero = 0; system("cls"); printf("Nombre Datos\n"); while(fread(&reg, sizeof(struct stRegistro), 1, fa)) Listar(numero++, &reg); system("PAUSE"); break; case '5': // Eliminar marcados Empaquetar(&fa); break; } } while(opcion != '0'); fclose(fa); return 0; } // Muestra un menú con las opciones disponibles y captura una opción del usuario int Menu() { char resp[20]; do { system("cls"); printf("MENU PRINCIPAL\n"); printf("--------------\n\n"); printf("1- Insertar registro\n"); printf("2- Mostrar registro\n"); printf("3- Eliminar registro\n"); printf("4- Mostrar todo\n"); printf("5- Eliminar registros marcados\n"); printf("0- Salir\n"); fgets(resp, 20, stdin); } while(resp[0] < '0' && resp[0] > '5'); return resp[0]; } // Permite que el usuario introduzca un registro por pantalla void Leer(struct stRegistro *reg) { int i; char numero[6]; system("cls"); printf("Leer registro:\n\n"); reg->valido = 'S'; printf("Nombre: "); fgets(reg->nombre, 34, stdin);

Page 31: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 28 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

// la función fgets captura el retorno de línea, hay que eliminarlo: for(i = strlen(reg->nombre)-1; i && reg->nombre[i] < ' '; i--) reg->nombre[i] = 0; for(i = 0; i < 4; i++) { printf("Dato[%1d]: ", i); fgets(numero, 6, stdin); reg->dato[i] = atoi(numero); } } // Muestra un registro en pantalla, si no está marcado como borrado void Mostrar(struct stRegistro *reg) { int i; system("cls"); if(reg->valido == 'S') { printf("Nombre: %s\n", reg->nombre); for(i = 0; i < 4; i++) printf("Dato[%1d]: %d\n", i, reg->dato[i]); } system("PAUSE"); } // Muestra un registro por pantalla en forma de listado, // si no está marcado como borrado void Listar(long n, struct stRegistro *reg) { int i; if(reg->valido == 'S') { printf("[%6ld] %-34s", n, reg->nombre); for(i = 0; i < 4; i++) printf(", %4d", reg->dato[i]); printf("\n"); } } // Lee un número suministrado por el usuario long LeeNumero() { char numero[6]; fgets(numero, 6, stdin); return atoi(numero); } // Elimina los registros marcados como borrados void Empaquetar(FILE **fa) { FILE *ftemp; struct stRegistro reg; ftemp = fopen("alea.tmp", "wb");

Page 32: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 29 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Ejercicios Propuestos

ARREGLOS DE UNA DIMENSIÓN

1. Declare e inicialice un vector de N elementos de modo que los

componentes de indice par valgan 0 y los de indice impar valgan 1. Ejm. V(1,0,1,0, . . . . .)

2. Escriba un programa que almacene en un vector los N primeros números de

Fibonacci. Una vez calculados, el programa los mostrará por pantalla en orden inverso.

3. Escriba un programa que almacene en un vector los N primeros números de

Fibonacci. Una vez calculados, el programa pedirá al usuario que introduzca un número y dirá si es o no es uno de los N primeros números de Fibonacci.

4. Hallar la mediana, en el anterior planteado en la pagina 6 del texto 5. Modifica el programa anterior para que permita efectuar cálculos con N personas. 6. Modifica el programa del ejercicio anterior para que muestre, además, cuántas

edades hay entre 0 y 9 años, entre 10 y 19, entre 20 y 29, etc. Considera que ninguna edad es igual o superior a 150. Ejemplo: si el usuario introduce las siguientes edades correspondientes a 12 personas:

10 23 15 18 20 18 57 12 29 31 78 28 el programa mostrará (además de la media, desviación estándar, moda y mediana), la siguiente tabla:

rewind(*fa); while(fread(&reg, sizeof(struct stRegistro), 1, *fa)) if(reg.valido == 'S') fwrite(&reg, sizeof(struct stRegistro), 1, ftemp); fclose(ftemp); fclose(*fa); remove("alea.bak"); rename("alea.dat", "alea.bak"); rename("alea.tmp", "alea.dat"); *fa = fopen("alea.dat", "r+b"); }

Page 33: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 30 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

0 - 9: 0 10 - 19: 5 20 - 29: 4 30 - 39: 1 40 - 49: 0 50 - 59: 1 60 - 69: 0 70 - 79: 1 80 - 89: 0 90 - 99: 0 100 - 109: 0 110 - 119: 0 120 - 129: 0 130 - 139: 0 140 - 149: 0

4 Modifica el programa para que muestre un histograma de edades. La tabla anterior se mostrará ahora como este histograma:

0 - 9: 10 - 19: ***** 20 - 29: **** 30 - 39: * 40 - 49: 50 - 59: * 60 - 69: 70 - 79: * 80 - 89: 90 - 99: 100 - 109: 110 - 119: 120 - 129: 130 - 139: 140 - 149:

Como puedes ver, cada asterisco representa la edad de una persona.

5 Modifica el programa anterior para que el primer y último rangos de edades mostrados en el histograma correspondan a tramos de edades en los que hay al menos una persona. El histograma mostrado antes aparecerá ahora así:

10 - 19: ***** 20 - 29: **** 30 - 39: * 40 - 49: 50 - 59: * 60 - 69: 70 - 79: *

6 Modifica el programa del ejercicio anterior para que muestre el mismo histograma de esta otra forma:

Page 34: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 31 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

| ####### | | | | | | | | ####### | ####### | | | | | | | ####### | ####### | | | | | | | ####### | ####### | | | | | | | ####### | ####### | ####### | | ####### | | ####### | +----------+-----------+-----------+-----------+-----------+-----------+-----------+ | 10 – 19 | 20 - 29 | 30 – 39 | 40 – 49 | 50 – 59 | 60 - 69 | 70 – 79 |

7 Diseñe un programa que pida el valor de N números enteros distintos y los almacene en un vector. Si se da el caso, el programa advertirá al usuario, tan pronto sea posible, si introduce un número repetido y solicitará nuevamente el número hasta que sea diferente de todos los anteriores. A continuación, el programa mostrará los N números por pantalla

8 Diseñe un programa C que lea y almacene en un vector N números enteros

asegurándose de que sean positivos. A continuación, el programa pedirá que se introduzca una serie de números enteros y nos dirá si cada uno de ellos está o no en el vector. El programa finaliza cuando el usuario introduce un número negativo. Luego ordenar el vector, por el método de la burbuja.

9 En un arreglo se ha almacenado el número total de toneladas de cereales

cosechadas durante cada mes del año anterior. Se desea la siguiente información:

i. El promedio anual de toneladas cosechadas ii. ¿Cuántos meses tuvieron una cosecha superior al promedio anual?

iii. ¿Cuántos meses tuvieron una cosecha inferior al promedio anual?Escriba un programa que proporcione estos datos.

ARREGLOS MULTIDIMENSIONALES 20. Escriba un programa que intercambie por renglón los elementos de un arreglo

bidimensional. Los elementos del renglón 1 deben intercambiarse con los del renglón N, los del renglón 2 con los del N-1, y así sucesivamente.

21. Escriba un programa que asigne valores a A, a partir de B teniendo en cuenta los

siguientes criterios: iv. Aij = (bi) si i <= j v. Aij = 0 si i >j

Page 35: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 32 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

REGISTROS 22. Una compañía distribuye N productos a distintos comercios de la ciudad. Para ellos almacena en un arreglo toda la información relacionada con su mercancía: • Clave • Descripción • Existencia • Mínimo a mantener de existencia • Precio unitario Escriba un programa que pueda llevar a cabo las siguientes operaciones: a) Venta de un producto: se deben actualizar los campos que correspondan, y

verificar que la nueva existencia no esté por debajo del mínimo. (datos: clave, cantidad_vendida)

b) Reabastecimientos de un producto: se deben actualizar los campos que correspondan. (Datos: clave, cantidad comprada)

c) Actualizar el precio de un producto: se deben proporcionar todos los datos relacionados con un producto. (Dato: clave)

Page 36: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 33 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Capítulo II Pilas

2.1. Introducción La pila es una lista de elementos caracterizada porque las operaciones de inserción y eliminación se realizan solamente en un extremo de la estructura. El extremo donde se realizan estas operaciones se denomina habitualmente 'cima' o tope (top en nomenclatura inglesa). Dada una pila P = (a, b, c, ... k ), se dice que a, es el elemento más inaccesible de la pila, está en el fondo de la pila (bottom) y que k, por el contrario, el más accesible, está en el Tope. Las restricciones definidas para la pila implican que si una serie de elementos A, B, C, D, E se añaden, en este orden a una pila, entonces el primer elemento que se borre de la estructura deberá ser el E. Por tanto, resulta que el último elemento que se inserta en una pila es el primero que se borra. Por esta razón, se dice que una pila es una lista LIFO (Last Input First Output, es decir, el último que entra es el primero que sale). Un ejemplo típico de pila lo constituye un montón de platos, cuando se quiere introducir un nuevo plato, éste se pone en la posición más accesible, encima del último plato. Cuando se coge un nuevo plato, éste se extrae, igualmente, del punto más accesible, el último que se ha introducido.

El pequeño pez "Usted perdone", le dijo un pez a otro, "es usted más viejo y con más experiencia que yo y probablemente podrá usted ayudarme. Dígame: ¿dónde puedo encontrar eso que llaman Océano? He estado buscándolo por todas partes, sin resultado". "El Océano", respondió el viejo pez, "es donde está ahora mismo". "¿Esto? Pero si esto no es más que agua... Lo que yo busco es el Océano, replicó el joven pez, totalmente decepcionado, mientras se marchaba nadando a buscar en otra parte. Deja de buscar, pequeño pez. No hay nada que buscar. Sólo tienes que estar tranquilo, abrir tus ojos y mirar. No puedes dejar de verlo.

de Anthony de Mello, libro: "El canto del pájaro".

Page 37: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 34 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Una pila de papeles Una pirámide de personas

Otro ejemplo natural de la aplicación de la estructura pila aparece durante la ejecución de un programa de ordenador, en la forma en que la máquina procesa las llamadas a los procedimientos. Cada llamada a un procedimiento (o función) hace que el sistema almacene toda la información asociada con ese procedimiento (parámetros, variables, constantes, dirección de retorno, etc..) de forma independiente a otros procedimientos y permitiendo que unos procedimientos puedan invocar a otros distintos (o a si mismos) y que toda esa información almacenada pueda ser recuperada convenientemente cuando corresponda. Como en un procesador sólo se puede estar ejecutando un procedimiento, esto quiere decir que sólo es necesario que sean accesibles los datos de un procedimiento (el último activado que está en la cima). De ahí que la estructura pila sea muy apropiada para este fin. Como en cualquier estructura de datos, asociadas con la estructura pila existen una serie de operaciones necesarias para su manipulación, éstas son:

a. Crear la pila. b. Comprobar si la pila está vacía. Es necesaria para saber si es posible eliminar

elementos. c. Acceder al elemento situado en la cima. d. Añadir elementos a la cima. e. Eliminar elementos de la cima.

La especificación correcta de todas estas operaciones permitirá definir adecuadamente una pila.

2.2. Representación de Las Pilas Las pilas no son estructuras fundamentales de datos, es decir, no están definidas como tales en los lenguajes de programación (como lo están por ejemplo los arreglos). Las pilas pueden representarse mediante el uso de:

Page 38: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 35 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

• Arreglos • Listas Enlazadas

Aquí se utilizarán arreglos. En consecuencia deberá definirse cuál será el tamaño máximo de la pila, y además una variable auxiliar a la que se denominará TOPE, que será un apuntador al último elemento insertado en la pila. En la figura siguiente se presentan dos alternativas de representación de una pila, utilizando arreglos.

2.3. Estructura de una Pila utilizando Arreglos

Donde los elementos son:

V[MAX]:es el vector que representa a la pila y es de tamaño de la pila.

Tope: es la varible que indica la posición del ultimo elemento de la pila.

Y las operaciones como se describen a continuación.

2.4. Operaciones Con Pilas La definición de una estructura de datos queda completa al incluir las operaciones que se pueden realizar en ella. Las operaciones principales con pilas son:

444 222 434 555

555 434 222 4444 PILA =

PILA

1 2 3 4 … MAX

TOPE

MAX 4 3 2 1

E TOPE

PILA V[MAX]: tipo_dato Tope: entero Poner(e) Quitar() Imprimir() Vacia() Llena()

Nombre del TAD

elementos

operaciones

Page 39: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 36 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

• Pone (e) un elemento en la pila (push)

• Quita () un elemento de la pila (pop)

• Llena() verifica si la pila esta llena, si es asi, retorna el valor verdad, caso contrario falso.

• Vacia() verifica si la pila esta vacia, si es asi, reotrna el valor verdad, caso

contrario falso.

• Imprime() Permite imprimir todos los elementos de la pila desde el tope hasta el fondo de la pila.

2.5. Implementación del TAD pila en lenguaje java

//clase pila y sus operaciones import java.io.*; public class Pila { private final int MAX = 20; private int v[] = new int [MAX]; private int tope; Pila () { tope = 0; System.out.println ("PILA CREADA..."); } boolean vacia () { if (tope == 0) return (true); else return (false); } boolean llena () { if (tope == MAX) return (true); else return (false); }

Page 40: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 37 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

void poner (int elem) { if (llena ()) System.out.println ("PILA LLENA..."); else { tope++; v [tope] = elem; } } int quitar () { int elem = 0; if (vacia ()) System.out.println ("PILA VACIA..."); else { elem = v [tope]; tope--; } return (elem); } void imprimir () { System.out.println ("...IMPRIMIENDO LA PILA..."); for (int i = tope ; i >= 1 ; i--) System.out.println (v [i]); } void llenarPila () { int n, e; System.out.println ("cuantos elementos ??..."); n = Lectura.Entero (); for (int i = 1 ; i <= n ; i++) { System.out.print ("elemento?...... "); e = Lectura.Entero (); poner (e); } } }

Page 41: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 38 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Ejercicios con pilas

a. Sumar dos pilas del mismo tamaño.

//sumar dos pilas del mismo tamaño class EjPila1 { static Pila P1 = new Pila (); static Pila P2 = new Pila (); static Pila P3 = new Pila (); static void sumarPilas (Pila A, Pila B, Pila C) { int e, f; while (!A.vacia ()) { e = A.quitar (); f = B.quitar (); C.poner (e + f); } } public static void main (String args[]) { P1.llenarPila (); P2.llenarPila (); P1.imprimir (); P2.imprimir (); sumarPilas (P1, P2, P3); P3.imprimir (); } }

Page 42: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 39 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

b. Eliminar los elementos negativos de una pila.

//ELIMINAR ELEMENTOS NEGATIVOS DE LA PILA class EjPila2 { static Pila P = new Pila (); static void EliminaNegativos (Pila A) { Pila aux = new Pila (); int e; System.out.println ("Eliminando Elementos Negativos de la Pila..."); while (!A.vacia ()) { e = A.quitar (); if (e > 0) aux.poner (e); } while (!aux.vacia ()) { e = aux.quitar (); A.poner (e); } } public static void main (String args[]) { P.llenarPila (); P.imprimir (); EliminaNegativos (P); P.imprimir (); } }

Page 43: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 40 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

c. Realizar un procedimiento para intercalar los elementos de una pila A con los elementos de una pila B en una pila C. Es decir:

C =

3 4 77 89 23 11 44 33

89 33 77 44 4 11 3 23

A = B =1 2 3 4 5 1 2 3 4 5

TOPE TOPE

1 2 3 4 5 6 7 8

TOPE

//intercalar los elementos de una pila A con los elementos de una pila B //en una pila c class EjPila3 { static Pila p1 = new Pila (); static Pila p2 = new Pila (); static void Intercala (Pila A, Pila B) { Pila aux = new Pila (); int e; System.out.println ("****** INTERCALANDO LA PILA *********"); while (!A.vacia ()) { e = A.quitar (); aux.poner (e); e = B.quitar (); aux.poner (e); } aux.imprimir (); } public static void main (String args[]) { p1.llenarPila (); p2.llenarPila (); p1.imprimir (); p2.imprimir (); Intercala (p1, p2); } }

Page 44: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 41 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

2.6. Aplicaciones Las pilas son una estructura de datos muy usada en la solución de diversos tipos de problemas. Ahora se verán algunos de los casos más representativos de aplicación de pilas:

• Llamadas a subprogramas • Recursión • Tratamiento de expresiones aritméticas • Ordenación

2.6.1. Llamadas a subprogramas Cuando se tiene un programa que llama a un subprograma, internamente se usan pilas para guardar el estado de las variables del programa en el momento que se hace la llamada. Así, cuando termina la ejecución del subprograma, los valores almacenados en la pila pueden recuperarse para continuar con la ejecución del programa en el punto en el cual fue interrumpido. Además de las variables debe guardarse la dirección del programa en la que se hizo la llamada, porque es a esa posición a la que regresa el control del proceso. Por ejemplo, se tiene un programa principal (PP) que llama a los subprogramas UNO y DOS. A su vez, el subprograma DOS llama al subprograma TRES. Cada vez que la ejecución de uno de los subprogramas concluye, se regresa el control al nivel inmediato superior. Cuando el programa PP llama a UNO, se guarda en una pila la posición en la que se hizo la llamada. Al terminar UNO, el control se regresa a PP recuperando previamente la dirección de la pila. Al llamar a DOS, nuevamente se guarda la dirección de PP en la pila. Cuando DOS llama a TRES, se pone en la pila la dirección de DOS. Después de procesar TRES, se recupera la posición de DOS para continuar con su ejecución. Al terminar DOS se regresa el control a PP, obteniendo previamente la dirección guardada en la pila.

Page 45: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 42 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

PP UNO DOS TRES

Finalmente podemos concluir que las pilas son necesarias en esta área de aplicaciones por lo siguiente:

• Permiten guardar la dirección del programa (subprograma) desde donde se hizo la llamada a otros subprogramas, para poder regresar y seguir ejecutándolo a partir de la instrucción inmediata a la llamada.

• Permiten guardar el estado de las variables en el momento que se hace la llamada, para poder seguir ocupándolas al regresar del subprograma.

… UNO…. DOS ….

…… ….

… …. TRES ….

… …. ….

PP

5 4 3 2 1

TOPE

PP

5 4 3 2 1 TOPE

5 4 3 2 1 0

PP

5 4 3 2 1

TOPE

PP

5 4 3 2 1

DOS PP

5 4 3 2 1 TOPE

PP

54 3 2 1

PP

54 3 2 1TOPE

PP

54 3 2 1

5 4 3 2 1 0TOPE

Page 46: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 43 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

2.6.2. Recursión Se Tratará en el tema 5 el tema de recursión. Se dejará para entonces la aplicación de pilas en procesos recursivos.

2.6.3. Tratamiento de expresiones aritméticas Un problema interesante en computación es poder convertir expresiones en notación infija a su equivalente en notación postfija.(o prefija). Revisaremos algunos conceptos:

• Dada la expresión A+B se dice que está en notación infija, y su nombre se debe a que el operador (+) está entre los operandos ( A y B).

• Dada la expresión AB+ se dice que está en notación postfija, y su nombre se debe a que el operador (+) está después de los operandos (A y B).

• Dada la expresión +AB se dice que está en notación prefija, y su nombre se debe a que el operador (+) está antes que los operando (A y B).

• La ventaja de usar expresiones en notación polaca postfija o prefija radica en que no son necesarios los paréntesis para indicar orden de operación, ya que éste queda establecido por la ubicación de los operadores con respecto a los operandos.

• Para convertir una expresión dada en notación infija a una notación postfija (o prefija) deberán establecerse previamente ciertas condiciones:

• Solamente se manejarán los siguientes operadores (están dados ordenadamente de mayor a menor según su prioridad de ejecución):

^ (potencia) * / (multiplicación y división) + - (suma y resta)

• Los operadores de más alta prioridad se ejecutan primero. • Si hubiera en una expresión dos o más operadores de igual prioridad, entonces se

procesarán de izquierda a derecha. • La subexpresiones patentizadas tendrán más prioridad que cualquier operador. • Presentaremos, paso a paso, algunos ejemplos de conversión de expresiones

infijas a notación polaca postfija. EJEMPLO En este ejemplo se presentan dos casos de traducción de notación infija a postfija. El primero de ellos es una expresión simple, mientras que el segundo presenta un mayor grado de complejidad.

Page 47: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 44 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

a) expresión infija: X + Z * W

X + [ZW*] Expresión postfija XZW*+

b) transformamos a notación prefija la misma expresión anterior X + Z * W X + [* Z W]

Notación prefija + X*ZW

EJERCICIOS

PROPUESTOS

3. Traduzca las siguietes expresiones a notación postfija utilizando el algoritmo de evaluación.

3.1. X*(Z+W)/(T-V) 3.2. Z-W*Y+XˆK 3.3. W*(Z/(K-T)) 4. Realizar un programa para hallar el mayor elemento de una pila P. 5. Realizar un procedimiento para intercambiar el último elemento de la pila por el

primer elemento. 6. Escriba un programa que elimine los elementos repetidos de una pila. Los elementos

repetidos ocupan posiciones sucesivas. 7. Escriba un subprograma que invierta los elementos de una pila. 8. Insertar n elementos después al fondo de una pila que ya tiene datos. 9. Eliminar los elementos divisores de X de la pila 10. Intercambiar cada elemento de la pila con su adyacente. 11. eliminar el primer elemento par de la pila 12. Hallar la frecuencia de repetición de cada elemento de la pila 13. Apilar los elementos de la pila B sobre la pila A. 14. Insertar el elemento X en una pila cuyos elementos estan ordenados en forma

ascendente desde el fondo hasta el tope. La pila debe quedar ordenada 15. Escriba un programa que lea una expresión en notación infija, y la traduzca anotación

postfija.

Page 48: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 45 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Capítulo III

Colas

3.1. Introducción La estructura de datos "cola" también llamada "Queue", es un tipo de datos abstracto "TDA". Una cola TDA permite a una lista de cosas ser removidos en el orden en que fueron almacenados. Una cola es una lista de elementos en la que éstos se introducen por un extremo y se eliminan por otro. Los elementos se eliminan en el mismo orden en el que se insertaron. Por lo tanto, el primer elemento que entra a la cola será el primero en salir. Debido a esta característica, las colas también reciben el nombre de estructuras FIFO (First In, First Out: Primero en entrar, primero en salir). Las colas en computación son muy similares a las colas de la vida real. Ejemplos:

a. cola de clientes esperando pagar en una caja de supermercado b. cola de clientes esperando ser atendidos por algún cajero en un banco c. cola de procesos esperando ser ejecutados por una CPU

Al igual que la pila, la cola es una estructura de datos dinámica, pero puede ser representado en forma estática (arreglos).

El camino del Tigre

Un hombre caminaba por el bosque cuando vió una zorra lisiada. "¿Cómo hará para alimentarse?", pensó.

En ese momento, se acercó un tigre, con un animal entre los dientes. Sació su apetito, y le dejó a la zorra lo que había sobrado. "Si Dios ayuda a la zorra, también me va a ayudar", reflexionó.

Volvió a su casa, se encerró en ella, y se quedó esperando que los Cielos le proveyeran de alimento. Nada pasó. Cuando ya se estaba quedando demasiado débil para salir a trabajar, se le apareció un ángel.

- ¿Por qué decidiste imitar a la zorra lisiada? -preguntó el ángel.

- ¡Levántate, toma tus herramientas, y sigue el camino del tigre! de Paulo Coelho

Page 49: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 46 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

3.2. Características

• Todos los elementos de la cola son del mismo tipo. • Existe un orden de elementos ya que es una estructura lineal, pero los elementos

no están ordenados por su valor sino por orden de introducción en la cola. • Existen dos extremos en la estructura lineal cola, el frente y el final de la cola. • Sólo se puede acceder y eliminar al dato que está en el frente de la cola. • Sólo se puede añadir información al final de la cola.

3.3. Representación De Las Colas Al igual que las pilas, las colas no existen como estructuras de datos estándares en los lenguajes de programación. Las colas pueden representarse mediante el uso de:

• Arreglos • Listas Enlazadas.

Como en el caso de las pilas, utilizaremos arreglos. Debe definirse el tamaño máximo para la cola y dos variables auxiliares. Una de ellas para que guarde la posición del primer elemento de la cola (FRENTE) y otra para que guarde la posición del último elemento de la cola (FINAL). En el ejemplo siguiente se muestra una representación de una cola en la cual se ha insertado cuatro elementos: 11, 22, 33 y 44, en ese orden. El elemento 11 está en el frente ya que fue el primero que entró en la cola. Mientras que el elemento 44, que fue el último en entrar, está en el FINAL de la cola.

Ejemplo: sea una cola Q de números enteros:

11 22 33 44

3.4. Estructura de Una cola Implementado mediante Arreglos A continuación diseñamos la estructura de datos para una cola representada mediante un arreglo:

Q =

1 2 3 4 5 6

MAX=6

Frente Final

Page 50: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 47 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Donde los elementos son:

V[MAX]:es el vector que representa a la cola y es de tamaño MAX.

Frente: es la variable que indica la posición del elemento del frente de la cola.

Fin: es la variable que indica la posición del último elemento de la cola.

Y las operaciones, como se describen a continuación.

3.5. Operaciones Con Colas Análogamente a las pilas, es necesario definir el conjunto de operaciones básicas para especificar adecuadamente una estructura cola. Estas operaciones serían:

• Insertar(e): Inserta un elemento al final de la cola. • Eliminar(): Elimina un elemento del frente de la cola. • Imprimir(): Imprime los elementos desde el frente hasta el final de la cola. • Vacia(): Verifica si la cola esta vacía, retorna un valor booleano. • Llena(): Verifica si la cola está llena, retorna un valor booleano. • FRENTE(): Retorna el valor del frente. • FINAL(): Retorna el valor del fin.

COLA V[MAX]: tipo_dato frente: entero fin: entero Insertar(e) Eliminar() Imprimir() Vacia() Llena() FRENTE() FINAL()

elementos

operaciones

Page 51: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 48 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Insertar un elemento en la cola:

Debido a la implementación estática de la estructura cola es necesario determinar si existen huecos libres donde poder insertar antes de hacerlo. Esto puede hacerse de varias formas.

Eliminar un elemento de la cola:

Como vera la eliminación no borra nada 'físicamente', sólo se encarga de actualizar el puntero 'frente' en una posición y devolver el valor x como mucho, aunque esto último no sea estrictamente necesario. Aunque esa posición aun contenga datos será considerada como vacía a efectos del otro puntero 'fin'.

COLAS LINEALES

A continuación implementamos el código correspondiente al programa de manejo de colas lineales en java

//COLA LINEAL DE NUMEROS ENTEROS Y SUS OPERACIONES class Cola { final int MAX = 20; private int v[] = new int [MAX]; private int fin; private int frente; Cola () { frente = 0; fin = 0; System.out.println ("COLA CREADA...."); } boolean vacia () { if (frente == 0) return (true); else return (false); } boolean llena () { if (fin == MAX) return (true); else return (false); }

Page 52: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 49 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

void insertar (int elem) { if (!llena ()) { fin++; v [fin] = elem; if (frente == 0) frente = 1; } else { System.out.println ("COLA LINEAL LLENA...."); System.exit (0); } } int eliminar () { int e = 0; if (!vacia ()) { e = v [frente]; if (frente == fin) { frente = 0; fin = 0; } else frente = frente + 1; } else { System.out.println ("LA COLA ESTA VACIA..."); System.exit (0); } return (e); } void imprimir () { System.out.println ("IMPRIMIENDO LA COLA......"); for (int i = frente ; i <= fin ; i++) System.out.println (v [i]); } int FINAL () { return (fin); }

Page 53: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 50 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Ejercicios con Colas Lineales

a. Eliminar los divisores de x de una cola

int FRENTE () { return (frente); } void llenarCola () { int N; int e; System.out.println ("Cuantos elementos desea insertar a la cola ??"); N = Lectura.Entero (); for (int i = 1 ; i <= N ; i++) { System.out.print ("Introduzca un elemento...."); e = Lectura.Entero (); insertar (e); } } }

// ELIMINAR LOS DIVISORES DE X DE UNA COLA LINEAL class EjCola1 { static Cola Q = new Cola (); static void EliminarDivisoresX (Cola A) { int x; int e; int m = A.FINAL (); System.out.print ("/////" + m); System.out.println ("***** Eliminando Divisores de X de la Cola Lineal****** "); System.out.print ("Ingrese el valor de x...."); x = Lectura.Entero (); while (A.FRENTE () != m + 1) { e = A.eliminar (); if (x % e != 0) A.insertar (e);

Page 54: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 51 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

COLAS CIRCULARES

Para hacer un uso más eficiente de la memoria disponible se trata a la cola como una estructura circular. Es decir, el elemento anterior al primero es el último. En la siguiente figura se muestra la representación de una cola circular.

Ejemplo

Para el siguiente ejemplo (a), en el cual ya no es posible adicionar elementos siguiendo la anterior estructura, se propone la alternativa (b):

22

33 45

9

1

8

7

6

5 4

3

2 85

67 Final Frente

1 2 3 4 5

D E

Frente Final

(a)

} A.imprimir (); } public static void main (String args[]) { Q.llenarCola (); Q.imprimir (); EliminarDivisoresX (Q); } }

Page 55: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 52 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

El diseño de la estructura de datos de una cola circular no varia en relación a una estructura de datos lineal, por tanto a continuación mostramos las operaciones que sufren cambios en este tipo de colas.

3.6. Operaciones Con Colas Circulares Las operaciones básicas con colas circulares son: insertar, eliminar y mostrar una cola circular. A continuación mostramos la implementación en Java de una Cola Circular.

//COLA CIRCULAR DE NUMEROS ENTEROS Y SUS OPERACIONES class ColaCircular { final int MAX = 20; private int v[] = new int [MAX]; private int fin; private int frente; ColaCircular () { frente = 0; fin = 0; System.out.println ("COLA CREADA...."); } boolean vacia () { if (frente == 0) return (true); else return (false); }

(b)

1 2 3 4 5

F D E

FrenteFinal

Page 56: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 53 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

boolean llena () { if ((fin == MAX && frente == 1) || (fin + 1 == frente)) return (true); else return (false); } void insertar (int elem) { if (!llena ()) { if (fin == MAX) fin = 1; else if (frente == 0) { frente = 1; fin = 1; } else fin++; v [fin] = elem; } else { System.out.println ("COLA CIRCULAR LLENA...."); System.exit (1); } } int eliminar () { int e = 0; if (!vacia ()) { e = v [frente]; if (frente == fin) { frente = 0; fin = 0; } else if (frente == MAX) frente = 1; else frente = frente + 1; } else { System.out.println ("LA COLA ESTA VACIA..."); System.exit (0); }

Page 57: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 54 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Ejercicios con Colas Circulares

a. Eliminar los elementos negativos de la cola circular

return (e); } void imprimir () { System.out.println ("IMPRIMIENDO LA COLA......"); for (int i = frente ; i <= fin ; i++) System.out.println (v [i]); } int FINAL () { return (fin); } int FRENTE () { return (frente); } void llenarCola () { int N; int e; System.out.println ("Cuantos elementos desea insertar a la cola ??"); N = Lectura.Entero (); for (int i = 1 ; i <= N ; i++) { System.out.print ("Introduzca un elemento...."); e = Lectura.Entero (); insertar (e); } } }

Page 58: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 55 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

3.7. Colas de Prioridades

Una cola de prioridad es una estructura característica, donde se pude retirar e insertar un ítem teniendo en cuenta la clave más grande o más chica (según la implementación) definida por el programador. Si los ítems tienen claves iguales, entonces la regla usual utilizada es que el primer ítem insertado es el que se retirará primero. Algunas aplicaciones de éste tipo de estructura son: la representación simulada de eventos dependientes del tiempo, como por ejemplo el funcionamiento de un aeropuerto, controlando partidas y aterrizajes de aviones. Otro ejemplo puede verse en los sistemas informáticos, el CPU asigna prioridades a las distintas tareas que debe ejecutar y las inserta en su cola, para de esta manera realizarlas en el orden correcto (multitareas).

// ELIMINAR LOS NEGATIVOS DE LA COLA CIRCULAR class EjColaCircular1 { static ColaCircular Q = new ColaCircular (); static void EliminarNegativos (ColaCircular A) { int e; int m = A.FINAL (); System.out.println ("***** Eliminando elementos Negativos de la Cola Circular ****** "); while (A.FRENTE () != m + 1) { e = A.eliminar (); if (e>0) A.insertar (e); } A.imprimir (); } public static void main (String args[]) { Q.llenarCola (); Q.imprimir (); EliminarNegativos(Q); } }

Page 59: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 56 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Podemos representar una cola de prioridad como una lista contigua ordenada, en la cual retirar un ítem es una operación inmediata, pero la inserción tomaría un tiempo proporcional al número de elementos que se encuentren en la cola, hay que tener en cuenta que dicha operación se debe realizar en forma tal que la cola quede ordenada. Otra forma de representación es a través de una lista desordenada, en la cual el proceso de inserción es inmediato, pero el de extracción es muy lento, ya que debo recorrer toda la cola para encontrar el ítem que debo retirar.

3.8. Aplicación De Pilas Y Colas Hasta ahora se ha tratado solamente con la representación en memoria y manipulación de una única pila o cola. Se han visto dos representaciones secuenciales eficientes para dichas estructuras. Sin embargo, en ocasiones, es preciso representar varias estructuras utilizando el mismo espacio de memoria. Supongamos que seguimos transformando las estructuras de datos en representaciones Secuenciales, tipo array. Si sólo hay que representar dos pilas sobre un mismo array A[1..n], la solución puede resultar simple. Se puede hacer crecer las dos pilas partiendo desde los extremos opuestos del array, de forma que A[1] será el elemento situado en el fondo de la primera pila y A[n] el correspondiente para la segunda pila. Entonces, la pila 1 crecerá incrementando los índices hacia A[n] y la pila 2 lo hará decrementando los índices hacia A[1]. De esta manera, es posible utilizar eficientemente todo el espacio disponible. Si se plantea representar más de dos pilas sobre ese mismo array A, no es posible seguir la misma estrategia, ya que un array unidimensional sólo tiene dos puntos fijos, A[1] y A[n], y cada pila requiere un punto fijo para representar el elemento más profundo. Cuando se requiere representar secuencialmente más de dos pilas, por ejemplo m pilas, es necesario dividir en m segmentos la memoria disponible, A[1..n], y asignar a cada uno de los segmentos a una pila. La división inicial de A[1..n] en segmentos se puede hacer en base al tamaño esperado de cada una de las estructuras. Si no es posible conocer esa información, el array A se puede dividir en segmentos de igual tamaño. Para cada pila i, se utilizará un índice f(i) para representar el fondo de la pila i y un índice c(i) para indicar dónde está su tope. En general, se hace que f(i) esté una posición por debajo del fondo real de la pila, de forma que se cumpla la condición f(i)=c(i) si y solamente si la pila i está vacía.

Page 60: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 57 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

EJERCICIOS

1. Realizar un programa para eliminar los elementos positivos de una cola. 2. Escribir un programa para intercambiar con su adyacente los elementos de una

cola 3. Eliminar los elementos impares de la cola lineal 4. Insertar dos elementos después del elemento X de la cola 5. Hallar el promedio de los elementos de la cola 6. Sumar dos colas A y B en una Cola C. 7. Intercambiar el elemento del frente de la cola por el elemento del final de la cola. 8. Intercambiar cada elemento con su adyacente. 9. Hallar el menor elemento de la cola 10. Llevar los elementos primos al frente de la cola 11. Eliminar los elementos múltiplos de X de la cola circular 12. Utilizando colas circulares resuelva el problema de Josefo. 13. Utilice una estructura de cola para simular el movimiento de clientes en una cola

de espera de un banco.. 14. Escriba un programa que invierta los elementos de una cola. 15. Escriba un procedimiento para insertar un elemento en una doble cola Escriba un

programa que cree una pila a partir de una cola.

Page 61: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 58 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Capítulo IV

Recursividad

4.1. Introducción Definición de Recursividad: Técnica de programación muy potente que puede ser usada en lugar de la iteración. Se dice que un objeto es recursivo, si en parte está formado por sí mismo o se define en función de sí mismo El concepto de recursividad va ligado al de repetición. Son recursivos aquellos algoritmos que, estando encapsulados dentro de una función, son llamados desde ella misma una y otra vez, en contraposición a los algoritmos iterativos, que hacen uso de bucles while, do-while, for, etc.

4.2. Ambito de Aplicación: – General – Problemas cuya solución se puede hallar solucionando el mismo problema pero con un caso de menor tamaño.

4.3. Razones de uso: – Problemas “casi” irresolubles con las estructuras iterativas. – Soluciones elegantes. – Soluciones más simples.

Aprende a nacer desde el dolor y a ser más grande que el más grande de los obstáculos, mírate en el espejo de ti mismo y serás libre y fuerte y dejarás de ser un títere de las circunstancias, porque tu mismo eres tu destino.

Pablo Neruda

Page 62: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 59 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

• Condición necesaria: ASIGNACIÓN DINÁMICA DE MEMORIA

4.4. ¿En qué consiste la recursividad? En el cuerpo de sentencias del subalgoritmo se invoca al propio subalgoritmo para

resolver “una versión más pequeña” del problema original. Habrá un caso (o varios) tan simple que pueda resolverse directamente sin necesidad de hacer otra llamada recursiva.

• Aspecto de un subalgoritmo recursivo. ALGORITMO Recursivo(...) INICIO ... Recursivo(...); ... FIN

“... Como el costo de la programación aumenta con regularidad y el costo de la

computación disminuye, hemos llegado al punto en donde la mayoría de los casos no vale la pena que un programador desarrolle laboriosamente una solución no recursiva para un problema que se resuelve con mayor naturalidad en forma recursiva”. La recursividad desde el punto de vista de la programación es una poderosa herramienta

que facilita la implementación de algunos algoritmos que de otro modo se harían muy complejos. El ejemplo clásico de esto último es el recorrido de arboles.

4.5. Forma de Enfrentar Problemas Recursivos.

a) Debe existir un caso BASE o Fin de recursión ete debe ser un caso en que la función se puede computar en forma simple (sin llamar a ninguna "copia" de ella). Este es el caso en que se DETIENE la recursión b) b) Parte puramente recursiva Se debe confiar en que, al llamar a una COPIA de la función, ESA función VA A RESOLVER EL PROBLEMA QUE LE ENTREGAMOS. No importa cuan difícil sea ese problema, debemos creer que lo soluciona. Hay que verificar que el problema "más pequeño" sea efectivamente MÁS PEQUEÑO, es decir, que el problema esté más cerca de solucionarse. La idea es que sepamos que en cada llamada recursiva estamos mas cerca del caso BASE

Page 63: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 60 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

+ Ejemplo definición de nº natural: el N º 0 es natural El Nº n es natural si n-1 lo es El factorial de un número natural esta definido como:

n! = n*(n-1)*(n-2)* ... *3*2*1 con 0!= 1 claramente se ve que: n! = n * (n-1)! ^ ^ ^ | | | | | Problema de tamaño (n-1) | Calculo Problema de tamaño n

En la siguiente figura vemos el proceso de la recursividad

PROBLEMA DE TAMAÑO N

PEQUEÑO CALCULO

PROBLEMA DE TAMAÑO N-1

//ITERATIVO: int Factorial( int n ) { int i, res=1; for (i=1; i <= n; i++ ) res = res * i; return ( res ); }

//RECURSIVO: int Factorial ( int n ) { if (n == 0) return (1); return (n * Factorial (n-1) ); }

Page 64: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 61 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Es necesario llevar un registro de todas las operaciones que se dejan pendientes hasta

que se llega al caso base. El patrón que sigue este registro es el de una pila, en donde la operación original se deja

en el fondo y en el tope aparecería el caso base. Una vez que se llenó la pila, se efectúa la operación de vaciar la pila efectuando todos

los cálculos que previamente se habían dejado pendientes Por lo general, los lenguajes de alto nivel como el C, enmascaran todos los detalles de la

implementación. A pesar de lo anterior es necesario tomarlo en cuenta debido a que la pila exige una gran cantidad de recursos (memoria y tiempo) de la máquina a la hora de ponerla a funcionar.

4.6. Tipos de recursividad.

♦ Recursividad simple: Aquella en cuya definición sólo aparece una llamada recursiva. Se puede transformar con facilidad en algoritmos iterativos.

♦ Recursividad múltiple: Se da cuando hay más de una llamada a sí misma dentro

del cuerpo de la función, resultando más dificil de hacer de forma iterativa.

Page 65: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 62 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Ejemplo ♦ Recursividad anidada: En algunos de los arg. de la llamada recursiva hay una nueva llamada a sí misma.

♦ Recursividad cruzada o indirecta: Son algoritmos donde una función provoca una llamada a sí misma de forma indirecta, a través de otras funciones. Ejemplo: Par o Impar:

4.7. La pila de recursion

La memoria del ordenador se divide (de manera lógica, no física) en varios segmentos (4):

int Fib( int n ) /* ej: Fibonacci */ { if ( n <=1) return(1); return ( Fib( n-1) + Fib(n-2) ); }

int Ack ( int n, int m ) /* ej: Ackerman */ { if (n == 0 ) return (m+1) else if ( m == 0 ) return (Ack (n-1,1) ); return( Ack (n-1, Ack(n,m-1) ) ); }

int par ( int nump ) { if ( nump == 0 ) return(1); return (impar (nump-1) ); }

int impar ( int numi ) { if ( numi == 0 ) return(0); return( par ( numi -1) ); }

Page 66: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 63 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Segmento de código: Parte de la memoria donde se guardan las instrucciones del programa en cod. Máquina. Segmento de datos: Parte de la memoria destinada a almacenar las variables estáticas. Montículo: Parte de la memoria destinada a las variables dinámicas. Pila del programa: Parte destinada a las variables locales y parámetros de la función que está siendo ejecutada.

4.8. La llamada a una función Se reserva espacio en la pila para los parámetros de la función y sus variables locales. Se guarda en la pila la dirección de la línea de código desde donde se ha llamado a la

función. Se almacenan los parámetros de la función y sus valores en la pila. Al terminar la función, se libera la memoria asignada en la pila y se vuelve a la

instrucción actual. En el caso recursivo, cada llamada genera un nuevo ejemplar de la función con sus

correspondientes objetos locales: La función se ejecutará normalmente hasta la llamada a sí misma. En ese momento se

crean en la pila nuevos parámetros y variables locales. El nuevo ejemplar de función comieza a ejecutarse. Se crean más copias hasta llegar a los casos bases, donde se resuelve directamente el

valor, y se va saliendo liberando memoria hasta llegar a la primera llamada (última en cerrarse)

EJERCICIOS

1) Calcular x elevado a n de forma recursiva: 3^2 = 9 3^0 = 1

float xelevn ( float base, int exp ) { if (exp == 0 ) return(1); return( base * xelevn (base , exp-1)); }

Page 67: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 64 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

b). Multiplicar 2 nºs con sumas sucesivas recursiva: 3*2 = 6

C) realizar en forma recursiva la función de Stirling d) implementar en forma recursiva la función de ackerman e) implementar en forma recursiva el problema de las torres de Hanoi

int multi( int a, int b ) { if ( b == 0 ) return(0); return( a + multi(a, b-1) ); }

Page 68: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 65 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Capitulo IV Listas Enlazadas

5.1. Introducción a las Estructuras de Datos Dinámica

Hasta ahora, todos los tipos de datos que se han visto, ya sean simples o estructurados, tienen una propiedad común: son estáticos. Esto significa que las variables que se declaran en un programa de alguno de estos tipos mantendrán la misma estructura durante la ejecución del mismo. Son variables estáticas y se definen en tiempo de compilación.

Ejemplo 1:

Si se declara un Vector de 5 elementos de tipo int, éste podrá cambiar su contenido, pero no su estructura.

Hay muchas situaciones en las que se desea cambiar el tamaño de las estructuras usadas.

La técnica usada para manejar estas situaciones es la asignación dinámica de memoria. Con este tipo de asignación se tendrán variables dinámicas o referenciadas, que pueden crearse y destruirse en tiempo de ejecución.

Ejemplo 2:

Si se pide diseñar un programa para gestionar una agenda de teléfonos con los datos de personas (nombre, apellidos, dirección, cumpleaños, teléfono, email, etc...). ¿Qué estructura puede utilizarse para realizarla?

Muere lentamente, quien abandona un proyecto antes de iniciarlo, no preguntando de un asunto que desconoce

o no respondiendo cuando le indagan sobre algo que sabe.

Evitemos la muerte en suaves cuotas, recordando siempre que estar vivo exige un esfuerzo mucho mayor

que el simple hecho de respirar. Pablo Neruda

Page 69: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 66 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Una respuesta inmediata pareciera ser la de usar un array (vector o matriz).

Si se usa un arreglo de dimensión MAX, pueden surgir los siguientes problemas:

¿Qué pasa si se quieren insertar más personas de MAX en la agenda? Hay que recompilar el programa para ampliar MAX Si el número de personas de la agenda es mucho menor que MAX se está

desperdiciando memoria que podría ser utilizada por otros programas

En muchos otros casos no es posible conocer anteladamente el numero de “elementos” que se van a usar.

Ejemplo 3:

Bases de datos para almacenar los datos de los estudiantes de la universidad

Elementos de un dibujo de pantalla, cuyo tamaño depende del dibujo trazado

5.2. Mecanismos Para Enlazar Información

a. LISTAS o Listas simplemente enlazadas

Solo hay un enlace por nodo Solo se puede recorrer en una dirección

o Listas doblemente enlazadas o Lista circular simplemente enlazada o Lista circular doblemente enlazada

b. ÁRBOLES Y GRAFOS

Page 70: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 67 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Info enlace

5.3. Listas Enlazadas

• Una lista enlazada es una estructura de datos en la que los objetos están ubicados linealmente.

• En lugar de índices de arreglo aquí se emplean punteros para agrupar linealmente los elementos.

• La lista enlazada permite implementar todas las operaciones de un conjunto dinámico.

• Si el predecesor de un elemento es NULL, se trata de la cabeza de la lista. • Si el sucesor de un elemento es NULL, se trata de la cola de la lista. • Cuando la cabeza es NULL, la lista está vacía o no existe la lista

Gráficamente una lista simplemente enlazada se representa de la siguiente forma:

NOTA Las listas almacenadas en arreglos están sujetos al tamaño del arreglo para su crecimiento. Si estos están vacíos se esta ocupando memoria sin uso. Además las listas reflejan el orden lógico y el orden físico de los elementos en el arreglo.

Las listas enlazadas son estructura de datos naturales donde el número de elementos que la integran no es conocido, o en su mejor

caso, la cantidad de los mismos puede variar.

Toda lista cuenta con una cabecera y nodos.

Nodo Cabeza de la Lista

Ultimo elemento de la Lista

P

23 12 4

Dirección de memoria

Page 71: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 68 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Características:

Las listas son una secuencia ordenada de elementos llamados nodo

Toda lista tiene una cabecera y una cola. Todos los nodos de la lista son del mismo tipo. Los nodo pueden ser agregados o suprimidos en cualquier momento en la lista

Una lista enlazada es una secuencia ordenada de elementos llamados nodos

5.4. Tipo De Dato Abstracto Nodo

La implementación de un nodo podría ser de la siguiente forma:

5.5. Construcción de un TAD Lista Enlazada Lineal Simple La estructura del nodo para una lista enlazada Lineal Simple es la siguiente, para datos de tipo doublé, implementado en java

Un NODO es una estructura compuesta básicamente de dos partes: • Un campo de información, en cual se almacenan datos o

estructuras • Un campo de dirección, en el cual se almacena la dirección

del nodo siguiente.

ListaLineal P: Nodo InsertarInicio(e) InsertarFinal() EliminarInicio() EliminarFinal() Recorrido()

Nodo Info: tipo_dato Dirsgte: Nodo Nodo()

Page 72: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 69 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Donde: Info: es la información del nodo. dirsgte: almacena la dirección del siguiente nodo de la lista, en caso de ser

el último nodo entonces apunta a nulo.

5.6. Operaciones Básicas Sobre Listas Enlazadas

Existen cinco operaciones básicas que se pueden hacer sobre listas enlazadas:

• Creación: de una lista vacía • Vacía: Retorna verdadero si la lista L está vacía y falso en caso contrario. • Inserción: Agregar un elemento al final de la lista. • Acceso: Examinar el primer elemento de la lista. • Eliminar: Se puede quitar el primer elemento de la lista, o remover todos los

elementos de la misma. • Buscar: ver si la lista contiene un elemento determinado. • Anula: Permite convertir la lista en una lista vacía • Imprime Lista: Imprime los elementos de la lista L

Creación de una lista vacía A continuación implementamos la sentencia para crear una lista vacía en java.

Inserción

nodo p = null;

private class nodo { private double info; private nodo dirsgte;

private nodo () { } }

Page 73: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 70 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

a) Inserción al Final de la lista

En el siguiente segmento de código se ejemplifica solamente el caso en el que el elemento se adiciona al final de la lista tal y como si se tratase de una estructura Pila o Cola. La implementación en java es la siguiente: b) Inserción al Inicio de la lista

En el siguiente segmento de código se implementa el caso en el que el nuevo nodo se inserta en la cabeza de la lista, a continuación se muestra la implementación en java: Para el siguiente ejemplo se ilustra el proceso de adición de un nuevo nodo

public void insertarFinal (double elem) { //Inserta un elemento elem al final de la lista p en el nodo q nodo q = new nodo (); nodo t = p; q.info = elem; q.dirsgte = null; if (p == null) p = q; else { while (t.dirsgte != null) t = t.dirsgte; t.dirsgte = q; } }

public void insertarInicio (double elem) { //Aniadir un elemento al principio de la lista nodo q = new nodo (); q.info = elem; q.dirsgte = p; p = q; }

Page 74: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 71 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

p = Inserta_Inicio(&p,10);

c) Recorrido de una Lista: Para mostrar los elementos de la lista se realiza el recorrido de la misma, a partir del nodo cabeza de la lista hasta encontrar el último nodo. Recordemos que el último nodo tiene la propiedad que su miembro dirsgte es igual a NULL.

public void recorrido () { //Recorrer la lista System.out.println (" ....RECORRIDO DE LA LISTA...."); nodo q = p; while (q != null) { System.out.println (q.info + " "); q = q.dirsgte; } }

Page 75: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 72 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

d) Eliminar el nodo del inicio de la Lista La siguiente función recibe una lista y devuelve esa misma lista, sin el nodo que ocupaba inicialmente la posición de la cabeza. La función será la siguiente:

e) Eliminar el nodo del Final de la Lista

void eliminaInicio () { //elimina el nodo del inicio de la lista nodo q = p; p = p.dirsgte; q = null; }

void eliminaFinal () { //elimina un nodo del final de la lista nodo q = p; if (p.dirsgte == null) p = null; else { nodo t = p; while (q.dirsgte != null) { t = q; q = q.dirsgte; } t.dirsgte = null; q = null; } }

Page 76: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 73 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

5.7. Implementación en el Lenguaje Java de la Clase Listas Lineales

A continuación realizamos la implementación del programa completo de listas simples, para datos de tipo doublé en java

//LISTAS LINEALES import java.io.*; public class listaLineal { //p: referencia al primer elemento de la lista, es el puntero cabecera private nodo p = null; //crea la lista p //nodo de una lista lineal simplemente enlazada private class nodo { private double info; private nodo dirsgte; private nodo () { } } public listaLineal () { } public void insertarInicio (double elem) { //Aniadir un elemento al principio de la lista nodo q = new nodo (); q.info = elem; q.dirsgte = p; p = q; } public void insertarFinal (double elem) { //Inserta un elemento elem al final de la lista p en el nodo q nodo q = new nodo (); nodo t = p; q.info = elem; q.dirsgte = null; if (p == null) p = q; else { while (t.dirsgte != null) t = t.dirsgte;

Page 77: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 74 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

t.dirsgte = q; }} public void recorrido () { //Recorrer la lista System.out.println (" ....RECORRIDO DE LA LISTA...."); nodo q = p; while (q != null) { System.out.println (q.info + " "); q = q.dirsgte; } } void eliminaInicio () { //elimina el nodo del inicio de la lista nodo q = p; p = p.dirsgte; q = null; } void eliminaFinal () { //elimina un nodo del final de la lista nodo q = p; if (p.dirsgte == null) p = null; else { nodo t = p; while (q.dirsgte != null) { t = q; q = q.dirsgte; } t.dirsgte = null; q = null; } } public void llenarLista () throws IOException { //llena la lista enlazada con elementos de tipo real con N elementos InputStreamReader isr = new InputStreamReader (System.in); BufferedReader br = new BufferedReader (isr); String dato; int N;

Page 78: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 75 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

EJERCICIO Escribir una aplicación en java para llamar a todas las operaciones con listas.

import java.io.*; class ejemLista1 { public static void main (String args[]) throws IOException { //crear una lista lineal L vacia listaLineal L = new listaLineal (); //leer datos reales y agregarlos a la lista L.llenarLista (); L.recorrido (); L.eliminaInicio (); L.recorrido (); L.eliminaFinal (); L.recorrido (); } }

double elem; System.out.println ("Cuantos elementos desea ingresar a la lista ?"); dato = br.readLine (); N = Integer.parseInt (dato); for (int i = 1 ; i <= N ; i++) { System.out.println ("ingrese elemento ...."); dato = br.readLine (); elem = Double.valueOf (dato).doubleValue (); insertarFinal (elem); } } }

Page 79: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 76 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

5.8. Listas Doblemente Enlazadas Una lista doble, ó doblemente enlazada es una colección de nodos en la cual cada nodo tiene dos punteros, uno de ellos apuntando a su predecesor (li) y otro a su sucesor (ld). Por medio de estos punteros se podrá avanzar o retroceder a través de la lista, según se tomen las direcciones de uno u otro puntero. La estructura de un nodo en una lista doble es la siguiente:

Existen dos tipos de listas doblemente ligadas:

• Listas dobles lineales. En este tipo de lista doble, tanto el puntero izquierdo del

primer nodo como el derecho del último nodo apuntan a NIL.

• Listas dobles circulares. En este tipo de lista doble, el puntero izquierdo del

primer nodo apunta al último nodo de la lista, y el puntero derecho del último nodo

apunta al primer nodo de la lista.

Debido a que las listas dobles circulares son más eficientes, los algoritmos que en esta

sección se traten serán sobre listas dobles circulares.

En la figura siguiente se muestra un ejemplo de una lista doblemente ligada lineal que

almacena números:

En la figura siguiente se muestra un ejemplo de una lista doblemente ligada circular que

almacena números:

Page 80: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 77 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

A continuación mostraremos algunos algoritmos sobre listas enlazadas. Como ya se

mencionó, llamaremos li al puntero izquierdo y ld al puntero derecho, también usaremos el

apuntador top para hacer referencia al primer nodo en la lista, y p para referenciar al nodo

presente.

Algoritmo de creación  top<--NIL repite si top=NIL entonces new(p) lee(p(dato)) p(ld)<--p p(li)<--p top<--p en caso contrario new(p) lee(p(dato)) p(ld)<--top p(li)<--p p(ld(li))<--p mensaje(otro nodo?) lee (respuesta) hasta respuesta=no

Algoritmo para recorrer la lista  --RECORRIDO A LA DERECHA. p<--top repite escribe(p(dato)) p<--p(ld) hasta p=top --RECORRIDO A LA IZQUIERDA. p<--top repite escribe(p(dato)) p<--p(li) hasta p=top(li)

Page 81: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 78 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Algoritmo para insertar antes de 'X' información  p<--top mensaje (antes de ?) lee(x) repite si p(dato)=x entonces new(q) leer(q(dato)) si p=top entonces top<--q q(ld)<--p q(li)<--p(li) p(ld(li))<--q p(li)<--q p<--top en caso contrario p<--p(ld) hasta p=top

Algoritmo para insertar despues de 'X' información  p<--top mensaje(despues de ?) lee(x) repite si p(dato)=x entonces new(q) lee(q(dato)) q(ld)<--p(ld) q(li)<--p p(li(ld))<--q p(ld)<--q p<--top en caso contrario p<--p(ld) hasta p=top

Algoritmo para borrar un nodo  p<--top mensaje(Valor a borrar) lee(valor_a_borrar) repite si p(dato)=valor_a_borrar entonces p(ld(li))<--p(ld) p(li(ld))<--p(li) si p=top entonces si p(ld)=p(li) entonces top<--nil en caso contrario

Page 82: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 79 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

top<--top(ld) dispose(p) p<--top en caso contrario p<--p(ld) hasta p=top

5.9. Listas Circulares Dobles Las listas circulares tienen la característica de que el último elemento de la misma apunta al

primero

La siguiente figura es una representación gráfica de una lista circular.

Enseguida se mostrarán los algoritmos más comunes en listas circulares. Al igual que en las

secciones anteriores, utilizaremos el apuntador top para hacer referencia al primer nodo en

la lista.

Algoritmo de creación repite new(p) lee(p(dato)) si top=nil entonces top<--p q<--p en caso contrario q(liga)<--p q<--p p(liga)<--top mensaje (otro nodo ?) lee(respuesta) hasta respuesta=no

Algoritmo para recorrer la lista p<--top repite escribe(p(dato)) p<--p(liga) hasta p=top

Page 83: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 80 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Algoritmo para insertar antes de 'X' información new(p) lee(p(dato)) si top=nil entonces top<--p p(liga)<--top en caso contrario mensaje(antes de ?) lee(x) q<--top r<--top(liga) repite si q(dato)=x entonces p(liga)<--q r(liga)<--p si p(liga)=top entonces top<--p q<--q(liga) r<--r(liga) hasta q=top

Algoritmo para insertar después de 'X' información new(p) lee(p(dato)) mensaje(después de ?) lee(x) q<--top r<--top(liga) repite si q(dato)=x entonces q(liga)<--p p(liga)<--r q<--q(liga) r<--r(liga) hasta q=top

Algoritmo para borrar  mensaje(valor a borrar ) lee(valor_a_borrar) q<--top r<--top p<--top mientras q(liga)<>top haz q<--q(liga) repite si p(dato)=valor_a_borrar entonces si p=top entonces si top(liga)=top entonces top<--NIL en caso contrario top<--top(liga) q(liga)<--top en caso contrario r(liga)<--p(liga) dispose(p) p<--top en caso contrario

Page 84: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 81 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

r<--p p<--p(liga) hasta p=top

EJERCICIOS

1. Eliminar el primer elemento negativo de la lista lineal

2. Insertar un nuevo nodo después del tercer nodo de la lista lineal

3. Eliminar todos los elementos X dado por el usuario de una lista circular simple.

4. Escriba un programa que permita adicionar elementos no repetidos a una lista. Es

decir antes de insertar un determinado elemento se debe verificar antes que éste

no se encuentre en la lista.

5. adicionar un elemento X a una lista de forma ordenada, de tal forma que la lista

quede ordenada, una vez insertado X.

6. Escriba un programa que permita eliminar el elemento de la cola de una lista

7. En una lista doble eliminar todos los elementos cuya información sea X. X dado

por el usuario

8. Insertar N nodos nuevos después del nodo K-esimo.

9. Eliminar N nodos desde la posición k de la lista enlazada circular simple.

10. Considere que dos listas L1 y L2, ya tienen elementos de tipo doublé, entonces se

desea llevar todos los elementos impares al final de la lista L1, de la lista L2.

Page 85: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 82 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Capitulo VI Árboles y Grafos

6.1. Definición Árbol

6.2. Conceptos Básicos

a. Nodo hijo: cualquiera de los nodos apuntados por uno de los nodos del árbol. En el ejemplo, 'L' y 'M' son hijos de 'F'.

b. Nodo padre: nodo que

contiene un puntero al nodo actual. En el ejemplo, el nodo 'A' es

Un árbol es una estructura no lineal en la que cada nodo puede apuntar a uno o varios nodos.

Tu vida no cambia cuando cambia tu jefe, Cuando tus amigos cambian, Cuando tus padres cambian, Cuando tu pareja cambia.

Tu vida cambia, cuando tu cambias, Eres el único responsable por ella.

"examínate.. Y no te dejes vencer"

Page 86: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 83 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

padre de 'B', 'C' y 'D'. Los árboles con los que trabajaremos tienen otra característica importante: cada nodo sólo puede ser apuntado por otro nodo, es decir, cada nodo sólo tendrá un padre. Esto hace que estos árboles estén fuertemente jerarquizados, y es lo que en realidad les da la apariencia de árboles. En cuanto a la posición dentro del árbol:

c. Nodo raíz: nodo que no tiene padre. Este es el nodo que usaremos para referirnos

al árbol. En el ejemplo, ese nodo es el 'A'. d. Nodo hoja: nodo que no tiene hijos. En el ejemplo hay varios: 'G', 'H', 'I', 'K', 'L',

'M', 'N' y 'O'. e. Nodo rama: aunque esta definición apenas la usaremos, estos son los nodos que

no pertenecen a ninguna de las dos categorías anteriores. En el ejemplo: 'B', 'C', 'D', 'E', 'F' y 'J'.

Existen otros conceptos que definen las características del árbol, con relación a su tamaño:

f. Orden: es el numero potencial de hijos que puede tener cada elemento de árbol. De este modo, diremos que un árbol en el que cada nodo puede apuntar a otros dos es de orden dos, si puede apuntar a tres será de orden tres, etc.

g. Grado: el número de hijos que tiene el elemento con más hijos dentro del árbol. En el árbol del ejemplo, el grado es tres, ya que tanto 'A' como 'D' tienen tres hijos, y no existen elementos con más de tres hijos.

h. Nivel: se define para cada elemento del árbol como la distancia a la raíz, medida en nodos. El nivel de la raíz es cero y el de sus hijos uno. Así sucesivamente. En el ejemplo, el nodo 'D' tiene nivel 1, el nodo 'G' tiene nivel 2, y el nodo 'N', nivel 3.

i. Altura: la altura de un árbol se define como el nivel del nodo de mayor nivel. Como cada nodo de un árbol puede considerarse a su vez como la raíz de un árbol, también podemos hablar de altura de ramas. El árbol del ejemplo tiene altura 3, la rama 'B' tiene altura 2, la rama 'G' tiene altura 1, la 'H' cero, etc.

6.3. Características de los Arboles Binarios

A los arboles ordenados de grado dos se les conoce como arboles binarios ya que cada nodo del árbol no tendrá más de dos descendientes directos. Las aplicaciones de los

Page 87: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 84 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

arboles binarios son muy variadas ya que se les puede utilizar para representar una estructura en la cual es posible tomar decisiones con dos opciones en distintos puntos. La representación gráfica de un árbol binario es la siguiente:

Los arboles representan las estructuras no lineales y dinámicas de datos más importantes en computación . Dinámicas porque las estructuras de árbol pueden cambiar durante la ejecución de un programa. No lineales, puesto que a cada elemento del árbol pueden seguirle varios elementos. Los arboles pueden ser construidos con estructuras estáticas y dinámicas. Las estáticas son arreglos, registros y conjuntos, mientras que las dinámicas están representadas por listas. La definición de árbol es la siguiente: es una estructura jerárquica aplicada sobre una colección de elementos u objetos llamados nodos; uno de los cuales es conocido como raíz. además se crea una relación o parentesco entre los nodos dando lugar a términos como padre, hijo, hermano, antecesor, sucesor, ansestro, etc.. Formalmente se define un árbol de tipo T como una estructura homogénea que es la concatenación de un elemento de tipo T junto con un número finito de arboles disjuntos, llamados subarboles. Una forma particular de árbol puede ser la estructura vacía. La figura siguiente representa a un árbol general.

Se utiliza la recursión para definir un árbol porque representa la forma más apropiada y porque además es una característica inherente de los mismos. Los arboles tienen una gran variedad de aplicaciones. Por ejemplo, se pueden utilizar para representar fórmulas matemáticas, para organizar adecuadamente la información,

Page 88: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 85 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

para construir un árbol genealógico, para el análisis de circuitos eléctricos y para numerar los capítulos y secciones de un libro.

6.4. Transformación de un Arbol Gral. en un Arbol Binario

Estableceremos los mecanismos necesarios para convertir un árbol general en un árbol binario. Para esto, debemos seguir los pasos que se describen a continuación: 1. Enlazar los hijos de cada nodo en forma horizontal (los hermanos). 2. Enlazar en forma vertical el nodo padre con el nodo hijo que se encuentra más a la

izquierda. Además, debe eliminarse el vínculo de ese padre con el resto de sus hijos. 3. Rotar el diagrama resultante aproximadamente 45 grados hacia la izquierda, y así se

obtendrá el árbol binario correspondiente.

6.5. Representación de un Árbol en Memoria Hay dos formas tradicionales de representar un árbol binario en memoria: Por medio de datos tipo punteros también conocidos como variables dinámicas o listas. Por medio de arreglos. Sin embargo la más utilizada es la primera, puesto que es la más natural para tratar este tipo de estructuras. Los nodos del árbol binario serán representados como registros que contendrán como mínimo tres campos. En un campo se almacenará la información del nodo. Los dos restantes se utilizarán para apuntar al subarbol izquierdo y derecho del subarbol en cuestión. Cada nodo se representa gráficamente de la siguiente manera:

El algoritmo de creación de un árbol binario es el siguiente:

Page 89: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 86 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Procedimiento crear(q:nodo) inicio mensaje("Rama izquierda?") lee(respuesta) si respuesta = "si" entonces new(p) q(li) <-- nil crear(p) en caso contrario q(li) <-- nil mensaje("Rama derecha?") lee(respuesta) si respuesta="si" entonces new(p) q(ld)<--p crear(p) en caso contrario q(ld) <--nil fin INICIO new(p) raiz<--p crear(p) FIN

6.6. Clasificación de Arboles Binarios Existen cuatro tipos de árbol binario:.

• A. B. Distinto.

• A. B. Similares.

• A. B. Equivalentes.

• A. B. Completos.

A continuación se hará una breve descripción de los diferentes tipos de árbol binario así

como un ejemplo de cada uno de ellos.

A. B. DISTINTO Se dice que dos árboles binarios son distintos cuando sus estructuras son diferentes.

Ejemplo:

Page 90: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 87 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

A. B. SIMILARES Dos arboles binarios son similares cuando sus estructuras son idénticas, pero la

información que contienen sus nodos es diferente. Ejemplo:

A. B. EQUIVALENTES Son aquellos arboles que son similares y que además los nodos contienen la misma

información. Ejemplo:

A. B. COMPLETOS Son aquellos arboles en los que todos sus nodos excepto los del ultimo nivel, tiene dos

hijos; el subarbol izquierdo y el subarbol derecho

6.7. Recorrido de un Arbol Binario Hay tres manera de recorrer un árbol : en inorden, preorden y postorden. Cada una de

ellas tiene una secuencia distinta para analizar el árbol como se puede ver a continuación:

1. INORDEN

o Recorrer el subarbol izquierdo en inorden.

o Examinar la raíz.

o Recorrer el subarbol derecho en inorden.

2. PREORDEN

o Examinar la raíz.

o Recorrer el subarbol izquierdo en preorden.

o recorrer el subarbol derecho en preorden.

3. POSTORDEN

o Recorrer el subarbol izquierdo en postorden.

o Recorrer el subarbol derecho en postorden.

Page 91: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 88 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

o Examinar la raíz.

A continuación se muestra un ejemplo de los diferentes recorridos en un árbol binario.

Inorden: GDBHEIACJKF

Preorden: ABDGEHICFJK

Postorden: GDHIEBKJFCA

6.8. Arboles Enhebrados Existe un tipo especial de árbol binario llamado enhebrado, el cual contiene hebras que

pueden estar a la derecha o a la izquierda. El siguiente ejemplo es un árbol binario

enhebrado a la derecha.

• ARBOL ENHEBRADO A LA DERECHA. Este tipo de árbol tiene un apuntador a

la derecha que apunta a un nodo antecesor.

• ARBOL ENHEBRADO A LA IZQUIERDA. Estos arboles tienen un apuntador a la

izquierda que apunta al nodo antecesor en orden

Page 92: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 89 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

6.9. Arboles binarios de búsqueda Un árbol de búsqueda binaria es una estructura apropiada para muchas de las

aplicaciones que se han discutido anteriormente con listas. La ventaja especial de utilizar

un árbol es que se facilita la búsqueda.

Un árbol binario de búsqueda es aquel en el que el hijo de la izquierda (si existe) de

cualquier nodo contiene un valor más pequeño que el nodo padre, y el hijo de la derecha

(si existe) contiene un valor más grande que el nodo padre.

Un ejemplo de arbol binario de búsqueda es el siguiente:

6.10. Grafos Un grafo dirigido G consiste en un conjunto de vértices V y un conjunto de arcos o aristas A. Los vertice se denominan también nodos o puntos. Un arco, es un par ordenado de vértices(V,W) donde V es el vértice inicial y W es el vértice terminal del arco. Un arco se expresa como: V-->W y se representa de la siguiente manera:

Los vértice de un grafo pueden usarse para representar objetos. Los arcos se utilizan para representar relaciones entre estos objetos. Las aplicaciones más importantes de los grafos son las siguientes:

• Rutas entre ciudades. • Determinar tiempos máximos y mínimos en un proceso. • Flujo y control en un programa.

Page 93: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 90 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

6.10.1. Definiciones Básicas La terminología que manejaremos regularmente para el uso de grafos es la siguiente:

• CAMINO.Es una secuencia de vértices V1, V2, V3, ... , Vn, tal que cada uno de

estos V1-&gtV2, V2-&gtV3, V1-&gtV3.

• LONGITUD DE CAMINO. Es el número de arcos en ese camino.

• CAMINO SIMPLE. Es cuando todos sus vértices, excepto tal vez el primero y el

último son distintos.

• CICLO SIMPLE. Es un camino simple de longitud por lo menos de uno que

empieza y termina en el mismo vértice.

• ARISTAS PARALELAS. Es cuando hay más de una arista con un vértice inicial y

uno terminal dados.

• GRAFO CICLICO. Se dice que un grafo es cíclico cuando contiene por lo menos

un ciclo.

• GRAFO ACICLICO. Se dice que un grafo es aciclíco cuando no contiene ciclos.

• GRAFO CONEXO. Un grafo G es conexo, si y solo si existe un camino simple en

cualesquiera dos nodos de G.

• GRAFO COMPLETO ó FUERTEMENTE CONEXO.Un grafo dirigido G es

completo si para cada par de nodos (V,W) existe un camino de V a W y de W a V

(forzosamente tendrán que cumplirse ambas condiciones), es decir que cada nodo

G es adyacente a todos los demás nodos de G.

• GRAFO UNILATERALMENTE CONEXO.Un grafo G es unilateralmente conexo si

para cada par de nodos (V,W) de G hay un camino de V a W o un camino de W a

V.

• GRAFO PESADO ó ETIQUETADO. Un grafo es pesado cuando sus aristas

contienen datos (etiquetas). Una etiqueta puede ser un nombre, costo ó un valor

de cualquier tipo de dato. También a este grafo se le denomina red de actividades,

y el número asociado al arco se le denomina factor de peso.

• VERTICE ADYACENTE. Un nodo o vértice V es adyacente al nodo W si existe un

arco de m a n.

• GRADO DE SALIDA.El grado de salida de un nodo V de un grafo G, es el número

de arcos o aristas que empiezan en V.

Page 94: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 91 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

• GRADO DE ENTRADA.El grado de entrada de un nodo V de un grafo G, es el

número de aristas que terminan en V.

• NODO FUENTE.Se le llama así a los nodos que tienen grado de salida positivo y

un grado de entrada nulo.

• NODO SUMIDERO.Se le llama sumidero al nodo que tiene grado de salida nulo y

un grado de entrada positivo.

6.10.2. Representación En Memoria Secuencial Los grafos se representan en memoria secuencial mediante matrices de adyacencia. Una matríz de adyacencia, es una matríz de dimensión n*n, en donde n es el número de vértices que almacena valores booleanos, donde matríz M[i,j] es verdadero si y solo si existe un arco que vaya del vértice y al vértice j. Veamos el siguiente grafo dirigido:

La matríz de adyacencia, que se obtuvo a partir del grafo anterior es la siguiente:

6.10.3. Representación en Memoria Enlazada Los grafos se representan en memoria enlazada mediante listas de adyacencia.

Page 95: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 92 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

Una lista de adyacencia, se define de la siguiente manera: Para un vértice i es una lista en cierto orden formada por todos los vértices adyacentes [a,i]. Se puede representar un grafo por medio de un arreglo donde cabeza de i es un apuntador a la lista de adyacencia al vértice i. Veamos el siguiente grafo dirigido:

La lista de adyacencia, que se obtuvo a partir del grafo anterior es la siguiente:

Otros ejemplos de Representación de grafo son los siguientes

Page 96: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 93 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

6.10.4. Operaciones Sobre Grafos En esta sección analizaremos algunas de las operaciones sobre grafos, como :

• Creación.

• Inserción.

• Búsqueda.

• Eliminación.

En esta sección, continuaremos utilizando los apuntadores que se usaron en las

secciones anteriores. TOP para hacer referencia al primer nodo, LD para indicar liga

derecha y LA para indicar liga abajo, por último usaremos los apuntadores P y Q para

hacer referencia a los nuevos nodos que vayan a ser usados.

ALGORITMO DE CREACION. repite si top=NIL entonces new(top) top(la)<--NIL

Page 97: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 94 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

top(ld)<--NIL lee(top(dato)) q<--top en caso contrario new(p) p(ld)<--NIL p(la)<--NIL q(la)<--p lee(p(dato)) q<--p mensaje(otro vertice ?) lee(respuesta) hasta repuesta=no p<--top mientras p<>NIL haz mensaje(tiene vértices adyacentes p(dato) ?) lee(respuesta) si respueta=si entonces repite new(q) lee(q(dato)) q(ld)<--p(ld) p(ld)<--q mensaje(otro vértice ?) lee(respuesta2) hasta respuesta2=no p<--p(la)

ALGORITMO DE INSERCION mensaje(valor a insertar ?) lee(valor_a_insertar) si top<>NIL entonces p<--top mientras p(la)<>NIL haz p<--p(la) new(q) lee(q(dato)) p(la)<--q q(la)<--NIL mensaje(Hay vértices adyacentes?) lee(respuesta) si respuesta=si entonces mensaje(Cuantos vértices?) lee(número_vértices) desde i=1 hasta número_vértices haz new(p) lee(p(dato)) q(ld)<--p q<--q(ld) en caso contrario mensaje(no existe lista)

ALGORITMO DE BUSQUEDA mensaje(vértice a buscar) lee(vértice_a_buscar) p<--top repite

Page 98: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 95 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

si p(dato)=vértice_a_buscar entonces repite p<--p(ld) escribe(p(dato)) hasta p(ld)=NIL en caso contrario p<--(la) hasta p=NIL

ALGORITMO DE BORRADO mensaje(vértice a borrar ?) lee(vértice_a_borrar) p&Lt--top r<--p q<--p sw<--falso repite si p(dato)=vértice_a_borrar entonces si p=top entonces top<--top(la) r<--top sw<--verdadero en caso contrario r(la)<--p(la) repite p<--p(ld) dispose(q) q<--p hasta p=NIL si sw=verdadero entonces p<--r q<--p en caso contrario p<--r(la) q<--p en caso contrario r<--p repite q<--p(ld) si q(dato)=vértice_a_borrar entonces p(ld)<--q(ld) dispose(q) q<--p en caso contrario p<--p(ld) hasta p=NIL

6.10.5. Camino Mínimo Se denomina camino mínimo entre dos vértices V y W, al camino óptimo entre ambos

vértices.Para determinar el camino mínimo entre dos vértices se utiliza el siguiente

algoritmo:

Page 99: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 96 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

desde i=1 hasta número_vértices haz desde j=1 hasta número_vértices haz si w[i,j]=0 entonces q[[i,j]<--infinito en caso contrario q[i,j]<--w[i,j] desde k=1 hasta número_vértices haz desde i=1 hasta número_vértices haz desde j=1 hasta número_vértices haz q[i,j]<--min(q[i,j], q[i,k] + q[k,j])

EJERCICIOS

3. Dado un árbol binario de busqueda , que contiene el nombre, el apellido y la

edad de un grupo de personas , ordenados por edades . Se pide : Hacer un algoritmo que visualice los datos de las personas de mayor a menor edad .

4. Dado un ABB que contiene números enteros .

Se pide : - Hacer un procedimiento que reciba como parámetros: el puntero a raiz del arbol , y un número entero . El procedimiento debe buscar el elemento NUM y una vez encontrado visualizar todos sus antecesores (los anteriores).

Page 100: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 97 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

GLOSARIO ALGORITMO. Es una descripción de los pasos de una tarea. ASCII. American Standard Code for Information Interchange. Es un código muy utilizado para el intercambio de datos. Como los ordenadores solo procesan dígitos binarios, cada letra, dígito o carácter especial tiene su correspondiente código binario. ASIGNACIÓN. Usado en programación. Es la acción de poner en una variable un valor, él contenido de otra variable o el resultado de evaluar una expresión. En la mayoría de los lenguajes se representa con el signo igual. ÁRBOL. Es uno de los posibles tipos de estructurar los datos. Todos los elementos menos uno, (el raíz), tienen un antecedente. Todos pueden tener otros elementos asociados llamados consecuentes. BIFURCACIÓN. En programación: transferencia de la secuencia de ejecución a otra parte del programa. Puede ser condicional o incondicional aunque esta última está mal vista en los lenguajes estructurados. BUCLE. En un programa es un grupo de instrucciones que se repiten hasta que se cumple una condición. BYTE. Conjunto de bits que contiene el código para un carácter. El byte de 8 bits, llamado octeto, es el más usado actualmente. Las capacidades de almacenamiento se miden en bytes o en sus múltiples. 1 K (kilobyte) = 1024 bytes. 1 Mb (megabyte) = 1024K. 1Gb (Gigabyte) = 1024 Mb. C. Lenguaje de programación de alto nivel que posee características de los de bajo nivel y esto lo hace adecuado para escribir software de sistemas. C++. Lenguaje C orientado a objetos CADENA. Tipo de estructura de datos que es un conjunto de caracteres almacenados consecutivamente. También recibe este nombre un conjunto de programas relacionados lógicamente para realizar una tarea. CARÁCTER. Dígito, letra o símbolo que puede ser tratado por un ordenador. Es la unidad elemental de información desde el punto de vista externo. CODIFICAR. Es la parte de la programación consistente en escribir en un lenguaje informático el algoritmo que resuelve un problema. CÓDIGO. Tabla de traducción entre todos los posibles símbolos de dos alfabetos. El más conocido es el código ASCII (American Standard Code for Information Interchange). COLA. Estructura de información consistente en una lista lineal en la que la nueva información se coloca en un extremo y la salida para procesar es por el otro extremo. Ejemplos: la cola de trabajos pendientes de ejecutar o la cola de espera de impresión de resultados.

Page 101: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 98 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

COMANDO. Mandato ejecutable por el ordenador. Cada una de las instrucciones que componen el sistema operativo y que el ordenador puede traducir en acciones específicas. CONTADOR. Usado en programación. Variable que contiene el número de acciones realizadas. COMPILADOR. Programa que traduce un programa escrito en un lenguaje de alto nivel a lenguaje de máquina. Además de traducir se detectan posibles errores de sintaxis. DIRECCIÓN. Etiqueta, nombre o número que identifica la posición de un dato en la memoria o en una unidad de almacenamiento EDITOR. Programa que permite escribir y corregir ficheros de texto como documentos o programas. EJECUTAR. Realizar una instrucción en código máquina o bien hacer que se realicen las instrucciones de un programa. ESTRUCTURA DE DATOS. Conjunto de datos en que sus componentes están relacionados entre sí de una forma particular y sobre los que se pueden realizar ciertas operaciones según sea el tipo de relación que hay entre ellos. EXPRESIÓN. Conjunto de variables, constantes, funciones y símbolos de operación que expresan un cálculo a realizar. Proporcionan un valor que será del tipo (aritmético, alfanumérico o lógico) de las variables y constantes que contiene. FICHERO. Conjunto organizado de información almacenado en un soporte. Está formado por registros que contienen la información de cada elemento del fichero. Los registros a su vez están divididos en campos, siendo cada campo uno de los datos del registro. Por ejemplo en un fichero de clientes, cada cliente sería un registro y tendríamos los campos: nombre, apellidos, dirección, teléfono, etc. I/O. Símbolo de Input/Output. Entrada/Salida desde o hacia un ordenador. IMPLEMENTAR. Instalar y hacer funcionar INSTRUCCIÓN. Se llama instrucción a cada una de las líneas que componen un programa de ordenador. Lenguaje de programación. Conjunto de símbolos e instrucciones que pueden ser reconocidos y procesados por un ordenador. LIBRERÍA. Conjunto de programas o módulos almacenados generalmente sobre un dispositivo magnético. LISTA. Conjunto de elementos de datos organizados de modo que se conoce la posición relativa de cada elemento. MENU. Es un conjunto de opciones presentado por un programa. La elección se efectúa tecleando un código, con los cursores o señalándolo con algún dispositivo como el ratón o el lápiz óptico. MÓDULO. En programación, cada uno de los bloques lógicos en que se puede dividir un programa.

Page 102: UNIVERSIDAD SALESIANA DE BOLIVIAvirtual.usalesiana.edu.bo/web/contenido/dossier/22012/1583.pdf · Operaciones básicas sobre listas enlazadas 73 5.7. Ejercicios 78 6. Capítulo IV:

[Estructura de Datos]  Page 99 Lic. Katya Perez Martinez &Lic. Gladys Chuquimia

PILA. Un tipo de estructura de datos en el que el último dato en llegar es el primero en salir. RECURSIVIDAD. Propiedad de algunos lenguajes de programación de permitir que un programa solicite su propia ejecución en el curso de su desarrollo. SUBPROGRAMA. Conjunto de instrucciones que efectúan una tarea específica dentro de un programa y al que es posible referirse. USUARIO. Es la persona que hace uso de un sistema de ordenadores. VARIABLE. En programación es una entidad dedicada a contener valores que pueden cambiar durante la ejecución de un programa. VENTANA. Una parte de la pantalla dedicada a representar un subconjunto de datos particulares.

LECTURAS COMPLEMENTARIAS

1. Estructuras de Datos http://cuhwww.upr.clu.edu/~jse/cursos/4097/notas/

2. versión electrónica y en línea de uno de los libros sobre estructuras de datos de mayor interés (Baeza-Yates). http://www.dcc.uchile.cl/~rbaeza/handbook/hbook.html

3. Algorithms and Data Structures Research & Reference Material". Muchas implementaciones, algoritmos y material de referencia

http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/index.html

4. Estructuras arbóreas

http://www.infor.uva.es/~jmrr/TAD2003/home.htm 5. MANUAL DE C++

http://kataix.umag.cl/~mmarin/topinf/cs23/c++/pagina022a.htm 6. Recursividad

http://www.conclase.net/c/curso/index.php?cap=024 http://decsai.ugr.es/~lcv/Docencia/mp2/apuntes/tema3.pdf.

7. Tutorial de estructuras de datos en C++ interactivo http://decsai.ugr.es/~jfv/ed1/c++/cdrom5/index.htm

8. Metodología de la Programacion II