Arreglos. Algoritmos y Estructuras de Datos I. Arreglos en C++ Arreglos y listas

Documentos relacionados
Notación Asintótica 2

Tema 3. Análisis de costes

Introducción a C++ y Code::Blocks

<tipo> Tipo de dato de los elementos del vector

Algoritmos para determinar Caminos Mínimos en Grafos

7.1 Consideraciones. Considere la búsqueda de un libro en una biblioteca. Considere la búsqueda de un nombre en el directorio telefónico.

ALGORITMOS DE ORDENAMIENTO COUNTING SORT CHRISTIAN ESTEBAN ALDANA ROZO BRAYAN STIF FORERO CRUZ GIOVANNY GUZMÁN CÉSPEDES JORGE MEJIA

Curso de Programación 1

Algoritmos y programas. Algoritmos y Estructuras de Datos I

Solución - práctico 10

Clases e instancias. Algoritmos y Estructuras de Datos I. Clases e instancias. memoria dinámica.

Sorting++ Herman Schinca. Clase de Junio de 2011

Tipos algebraicos y abstractos. Algoritmos y Estructuras de Datos I. Tipos algebraicos

Introducción al lenguaje C

Universidad de Valladolid. Departamento de informática. Campus de Segovia. Estructura de datos Tema 4: Ordenación. Prof. Montserrat Serrano Montero

Tipos de datos en S. Lógica y Computabilidad. Codificación de variables y etiquetas de S. Codificación de programas en S

Algoritmos de Ordenación

ORDENAMIENTO Y BÚSQUEDA EN ARREGLOS

Las plantillas permiten definir funciones genéricas.

TEORIA DE NUMEROS DIVISIBILIDAD Y NUMEROS PRIMOS. PRUEBAS DE PRIMALIDAD. LA CRIBA DE ERATOSTENES. ALGORITMOS. TEOREMA: EXISTENCIA DE INFINITOS PRIMOS.

Límites y continuidad. Cálculo 1

Estructuras de Control

Análisis y Diseño de Algoritmos Tablas de Hash

Analisis de algoritmos

Tema 9. Algoritmos sobre listas. Programación Programación - Tema 9: Algoritmos sobre listas

INTRODUCCIÓN. Estructura de Datos Tipos Abstractos de Datos (TAD S) Profs. Lorna Figueroa M. Mauricio Solar F. UTFSM 1 / 2008

Algorítmica y Complejidad. Tema 3 Ordenación.

Programación Dinámica 1

Máquinas de Turing IIC3242. IIC3242 Máquinas de Turing 1 / 42

NOTACIÓN O GRANDE. El análisis de algoritmos estima el consumo de recursos de un algoritmo.

Ecuaciones Diofánticas

El programa que permite el manejo de la base de datos tiene la siguiente funcionalidad:

Primer Parcial de Programación 3 (1/10/2009)

Complejidad de Algoritmos

Introducción Supongamos un subconjunto de n elementos X = {e 1,,e n de un conjunto referencial Y, X Y. Dentro de Y se define una relación de orden tot

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

CAPITULO II ORDENAMIENTO Y BUSQUEDA. Ivan Medrano Valencia

Estructura de Datos. Arreglos. Experiencia Educativa de Algorítmica ESTRUCTURA DE DATOS - ARREGLOS 1

Java para programadores

PHP: Lenguaje de programación

La eficiencia de los programas

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Algoritmo para Calcular Logaritmos

Algoritmos de Búsqueda y Ordenamiento

Máquinas de Turing IIC3242. IIC3242 Máquinas de Turing 1 / 45

Algoritmos glotones. mat-151

Análisis de Algoritmos

Ejemplos de conversión de reales a enteros

Funciones Tipos de funciones y Recursividad

VI Colas de prioridad

Práctica IV: Métodos de Newton-Raphson y de la secante, para encontrar las raíces de una función.

Algoritmos sobre secuencias y conjuntos de datos

Complejidad de los Algoritmos

Estatutos de Control C# Estatutos de Decisión (Selección)

NIVEL 15: ESTRUCTURAS RECURSIVAS BINARIAS

Árboles. Cursos Propedéuticos Dr. René Cumplido M. en C. Luis Rodríguez Flores

Algoritmos Recursivos de Búsqueda y Ordenación y sus tiempos

Soluciones oficiales Clasificación Olimpiada Nacional Nivel Mayor

Aritmética de Enteros

Tecnólogo Informático- Estructuras de Datos y Algoritmos- 2009

TEMA 7. ALGORITMOS DE BÚSQUEDA, ORDENACIÓN

Programación de Sistemas

ELO320 Estructuras de Datos y Algoritmos. Arboles Binarios. Tomás Arredondo Vidal

Retículos y Álgebras de Boole

Tiempo de Ejecución. Midiendo el Tiempo de Ejecución

Algoritmos de Ordenamiento

Agradecimientos. Nota de los autores. 1 Problemas, algoritmos y programas 1

Fundamentos de la programación

Ruta más Corta con una sóla Fuente de Inicio (Single-Source Shortest Paths) DR. JESÚS A. GONZÁLEZ BERNAL CIENCIAS COMPUTACIONALES INAOE

Normas de estilo para la codificación de programas

TADs en C. Matías Bordese Algoritmos y Estructuras de Datos II - Laboratorio 2013

Integrantes. Leonardo Herrera Cristian Fernandez Jorge A Mondragón. Análisis y Diseño de Algoritmos. Docente Diana Mabel Díaz Herrera.

Vectores. 27/05/05 Programación Digital I 1

USO DE SUBRUTINAS, TRANSMISIÓN DE PARÁMETROS Y COMPILACIÓN CONDICIONAL EN C++

Taller de Informática I Dpto. Computación F.C.E. y N. - UBA 2010

Se guardan en archivos con extencion c y los cabezales con extension h

PRÁCTICA No. 13 ÁRBOL BINARIO DE BÚSQUEDA

(TALF- ITIS- C) Clase 3 5 de Octubre de 2010

la solución a una ecuación cuadrática solicitando al usuario los términos de dicha ecuación.

$0 Representa al parámetro cero o nombre del programa $1 Representa al parámetro uno $2 Representa al parámetro dos

PROGRAMACIÓN UNIDADES

Conjunto R 3 y operaciones lineales en R 3

Introducción a la Geometría Computacional. Análisis de Algoritmos

Tema 2: Teorema de estructura de los grupos abelianos finitamente generados.

PRÁCTICA ALGORÍTMICA: EJERCICIOS PROPUESTOS

2.2 Nombres, Ligado y Ámbito

Árboles AVL. Laboratorio de Programación II

Diagramas de secuencia

Diagnóstico de fallas en circuitos digitales

Inducción Matemática. Departamento de Matemáticas. Inducción Matemática p. 1/31

1. Ejemplo de clase : La clase Cuenta 2. Uso de la clase Cuenta. 3. Métodos y objetos receptores de mensajes (Importante)

Titulación: Ingeniero Técnico en Informática de Gestión Curso: 2º

Isabelle como un lenguaje funcional

CURSOS CENEVAL TOLUCA

Examen escrito de Programación 1

Mostrar Números Ascendentemente. Soluciones Ejercicios Tema 5. tostring Recursivo de LEG. Suma Recursiva de un Vector (1/3)

Introducción a la Teoría de Grafos

Es toda la información que utiliza el computador. Según sea la información que guardemos en los datos, se clasifican en los siguientes tipos:

Este es un arreglo de números enteros, o sea que guarda una serie de variables de tipo INTEGER, todas agrupadas en una sola estructura.

Dr. Juan R. Mejías Ortiz 1

Transcripción:

Arreglos Algoritmos y Estructuras de Datos I Primer cuatrimestre 2007 Teórica de imperativo 3 Algoritmos de búsqueda secuencias de una cantidad fija de variables del mismo tipo se declaran con un nombre,, un tamaño y un tipo int a[10]; arreglo de 10 elementos enteros nos referimos a los elementos a través del nombre del arreglo y un índice entre corchetes a[0], a[1],..., a[9] solamente hay valores en las posiciones válidas de 0 a la dimensión menos uno una referencia a una posición fuera del rango da error (en ejecución) el tamaño se mantiene constante 1 2 Arreglos y listas Arreglos en C++ los arreglos en C++ son referencias ambos representan secuencias de elementos de un tipo los arreglos tienen longitud fija; las listas, no los elementos de un arreglo pueden accederse en forma independiente los de la lista se acceden secuencialmente, empezando por la cabeza para acceder al i-ésimo elemento de una lista, hay que obtener i veces la cola y luego la cabeza para acceder al i-ésimo elemento de un arreglo, simplemente se usa el índice 3 pueden modificarse cuando son pasados como argumentos no hay forma de averiguar su tamaño una vez que fueron creados el programa tiene que encargarse de almacenarlo de alguna forma en la declaración de un parámetro no se indica su tamaño problema ceroporuno(a : [Int], tam : Int){ requiere tam == a ; modifica a; asegura a == [if i == 0 then 1 else i i pre(a)[0..tam)]; void ceroporuno(int a[], int tam) { int j = 0; while (j < tam) { // invariante 0 j tam a[j..tam) == pre(a)[j..tam) // a[0..j) == [if i == 0 then 1 else i i pre(a)[0..j)]; // variante tam j; if (a[j] == 0) a[j] = 1; j++; 4

Búsqueda lineal sobre arreglos Especificación problema buscar (a : [Int], x : Int, n : Int) = res : Bool{ requiere a = n > 0; Implementación bool buscar (int a[], int x, int n) { int i = 0; while (i < n && a[i]!= x) { return i < n; El algoritmo de búsqueda lineal es el más ingenuo revisa los elementos del arreglo en orden en el peor caso realiza n operaciones Especificación del ciclo bool buscar(int a[], int x, int n) { int i = 0; // vale Pc : i = 0 while (i < n && a[i]!= x) { // invariante I : 0 i n x / a[0..i) // variante v : n i // vale Qc : i < n x a[0..n) return i < n; 5 6 Correctitud del ciclo // vale Pc // implica I while (i < n && a[i]!= x) { // estado E // vale I i < n a[i] x i = i+1; // vale I // vale v < v@e // vale I (i < n a[i] x) // implica Qc 1. El cuerpo del ciclo preserva el invariante 2. La función variante decrece 3. Si la función variante pasa la cota, el ciclo termina: v 0 (i < n a[i] x) 4. La precondición del ciclo implica el invariante 5. La poscondición vale al final El Teorema del Invariante nos garantiza que si valen 1, 2, 3, 4 y 5, el ciclo termina y es correcto con respecto a su especificación. 1. El cuerpo del ciclo preserva el invariante Recordar que el invariante es I : 0 i n x / a[0..i) la guarda B es i < n a[i] x // vale 0 i n x / a[0..i) i < n a[i] x // implica 0 i < n (juntando i n y i < n) // implica x / a[0..i] (juntando x / a[0..i) y a[i] x) // implica x / a[0..i + 1) (propiedad de listas) // vale i = i@e + 1 // implica 1 i@e + 1 < n + 1 (sumando 1 en cada término) // implica 0 i n (usando que i == i@e + 1 y propiedad de Z) // implica x / a[0..i@e + 1) (está en E; a no puede cambiar) // implica x / a[0..i) (usando que i == i@e + 1) // implica I (se reestablece el invariante) 7 8

2. La función variante decrece // vale I B // estado F // vale i == i@e + 1 Cuánto vale v = n i en el estado F? v@f == (n i)@f == n i@f == n (i@e + 1) == n i@e 1 < n i@e == v@e 5. La poscondición vale al final Quiero probar que: 1 {{ 0 i n Demostración: 2 {{ x / a[0..i) Qc : i < {{ n x a[0..n) {{ 3 4 5 {{ (i n x == a[i]) supongamos i n (i.e. 3 es falso). Por 1, i == n. Por 2, tenemos x / a[0..n). Luego 4 también es falso. supongamos i < n (i.e. 3 es verdadero). Por 5, x == a[i]. De 1 concluimos que 4 es verdadero. 9 10 3 y 4 son triviales Complejidad de un algoritmo 3. Si la función variante pasa la cota, el ciclo termina: n i 0 n i B 4. La precondición del ciclo implica el invariante i = 0 0 i n x / a[0..i) Entonces el ciclo es correcto con respecto a su especificación. Observar que // estado H // vale Qc : i < n x a[0..n) return i < n; // vale res == (i < n) i = i@h // implica res == x a[0..n) (esta es la poscondición del problema) máxima cantidad de operaciones que puede realizar el algoritmo hay que buscar los datos de entrada que lo hacen trabajar más se define como función del tamaño de la entrada T (n), donde n es la cantidad de datos recibidos notación O grande decimos que T (n) es O(f (n)) cuando T (n) es a lo sumo una constante por f (n) excepto para valores pequeños de n T (n) es O(f (n)) sii ( c, n0 )( n n 0 ) T (n) c f (n) se suele leer T (n) es del orden de f (n) 11 12

Complejidad de la búsqueda lineal Mejorando la búsqueda cuándo se da la máxima cantidad de pasos? cuando el elemento no está en la estructura cuántos pasos son? tantos como elementos tenga la estructura la complejidad del algoritmo es del orden del tamaño de la estructura en un arreglo o lista, hay que hacer tantas comparaciones (y sumas) como elementos tenga el arreglo o lista si llamamos n a la longitud de la estructura el algoritmo tiene complejidad O(n) en cada paso tengo cuatro operaciones (dos comparaciones, una conjunción y el incremento del índice), entonces c = 4 pero esto no es importante lo importante es cómo crece la complejidad cuando crece la estructura Supongamos que tenemos un diccionario y queremos buscar una palabra x. Cómo podemos mejorar la búsqueda? abrimos el diccionario a la mitad si x está en esa página, terminamos si x es menor (según el orden de diccionario) que las palabras de la página actual, x no puede estar en la parte derecha si x es mayor (según el orden de diccionario) que las palabras de la página actual, x no puede estar en la parte izquierda seguimos buscando solo en la parte izquierda o derecha (según sea el caso) 13 14 Búsqueda binaria - especificación del problema Supongamos que en lugar de un diccionario tenemos un arreglo ordenado y en lugar de buscar palabras buscamos números enteros. Podemos hacer una búsqueda más eficiente revisamos solo algunas posiciones del arreglo: en cada paso descartamos la mitad del espacio de búsqueda menos comparaciones Este tipo de algoritmo se llama búsqueda binaria. Tenemos un nuevo problema en donde mantenemos la poscondición reforzamos la precondición problema buscarbin (a : [Int], x : Int, n : Int) = res : Bool{ requiere a == n > 0; requiere ( j [0..n 1)) a[j] a[j + 1]; 15 El programa bool buscarbin(int a[], int x, int n) { int i = 0, d = n - 1; bool res; int m; if (x < a[i] x > a[d]) res = false; else { res = (a[i] == x a[d] == x); return res; 16

Especificación del ciclo bool buscarbin(int a[], int x, int n) { int i = 0, d = n - 1; bool res; int m; if (x < a[i] x > a[d]) res = false; else { // vale Pc : i == 0 d == n 1 a[i] x a[d] // invariante I : 0 i d < n a[i] x a[d] // variante v : d i 1 // vale Qc : I d i + 1 res = (a[i] == x a[d] == x); return res; 17 Correctitud del ciclo // vale Pc // implica I // estado E // vale I d > i + 1 // vale I // vale v < v@e // vale I d i + 1 // implica Qc 1. El cuerpo del ciclo preserva el invariante 2. La función variante decrece 3. Si la función variante pasa la cota, el ciclo termina: v 0 d i + 1 4. La precondición del ciclo implica el invariante 5. La poscondición vale al final El Teorema del Invariante nos garantiza que si valen 1, 2, 3, 4 y 5, el ciclo termina y es correcto con respecto a su especificación. 18 1. El cuerpo del ciclo preserva el invariante // vale 0 i i + 1 < d < n a[i] x a[d] // estado F // vale m = (i + d) div 2 i = i@e d = d@e // implica 0 i < m < d < n // vale m == m@f // vale x == a[m] i == d == m // vale x < a[m] (d == m i == i@e) // vale x > a[m] (i == m d == d@e) Falta ver que esto último implica el invariante 0 i d < n: sale del estado F a[i] x a[d]: caso x == a[m]: es trivial pues a[i] == a[m] == a[d] == x caso x < a[m]: tenemos a[i] x < a[m] == a[d] caso x > a[m]: tenemos a[i] == a[m] < x a[d] 19 2. La función variante decrece // vale 0 i i + 1 < d < n a[i] x a[d] // implica d i 1 > 0 // estado F // vale m == (i + d) div 2 i == i@e d == d@e // implica 0 i < m < d < n // vale m == m@e // vale x == a[m] i == d == m // vale x < a[m] (d == m i == i@e) // vale x > a[m] (i == m d == d@e) Cuánto vale v = d i 1? caso x == a[m]: es trivial pues v = 1 caso x < a[m]: d decrece pero i queda igual caso x > a[m]: i crece pero d queda igual 20

3, 4 y 5 son triviales 3. Si la función variante pasa la cota, el ciclo termina: d i 1 0 d i + 1 4. La precondición del ciclo implica el invariante Pc : i == 0 d == n 1 a[i] x a[d] I : 0 i d < n a[i] x a[d] 5. La poscondición vale al final Qc es idéntico a I d i + 1 Entonces el ciclo es correcto con respecto a su especificación. 21 Dónde se usa que el arreglo está ordenado? int i = 0, d = n - 1; bool res; int m; if (x < a[i] x > a[d]) res = false; else { // vale Pc : i = 0 d = n 1 a[i] x a[d] // vale Qc : 0 i d < n d i + 1 a[i] x a[d] res = (a[i] == x a[d] == x); Lo usamos para garantizar que res contiene el valor correcto si x < a[0] x > a[n 1], devolvemos falso (ok, por el orden) si a[i] == x a[d] == x, devolvemos verdadero (trivial) si a[i] x a[d] x: supongamos que a[j] == x para algún j i < j < d: no puede ser porque d i + 1 j < i: gracias al orden, x == a[j] < a[i]; contradice x a[i] j > d: gracias al orden, x == a[j] > a[d]; contradice x a[d] 22 Complejidad Conclusiones Cuántas comparaciones hacemos como máximo? en cada iteración me quedo con la mitad del espacio de búsqueda (tal vez uno más; no influye en el orden) paramos cuando el segmento de búsqueda tiene longitud 1 o 2 En total hacemos t iteraciones número de longitud del iteración espacio de búsqueda 1 n 2 n/2 3 (n/2)/2 = n/2 2 4 (n/2 2 )/2 = n/2 3 1 = n/2 t 1 2 t 1 = n t = 1 + log 2 n.. t. n/2 t 1 vimos dos algoritmos de búsqueda en general, más información algoritmos más eficientes problema buscar (a : [Int], x : Int, n : Int) = res : Bool requiere a == n > 0; problema buscarbin (a : [Int], x : Int, n : Int) = res : Bool requiere a == n > 0; requiere ( j [0..n 1)) a[j] a[j + 1]; Luego, la complejidad de la búsqueda binaria es O(log 2 n). Mucho mejor que la búsqueda lineal, que es O(n). la búsqueda binaria es esencialmente mejor que la búsqueda lineal - O(log 2 n) vs. O(n) 23 24