690 likes | 853 Views
Introducción. Estructuras de datos. PROPÓSITO DEL CURSO. Estudiar las estructuras de datos básicas utilizadas en la resolución de problemas de cómputo. Utilizar algoritmos recursivos como una técnica de control de flujo en la solución de problemas.
E N D
Introducción Estructuras de datos
PROPÓSITO DEL CURSO Estudiar las estructuras de datos básicas utilizadas en la resolución de problemas de cómputo. Utilizar algoritmos recursivos como una técnica de control de flujo en la solución de problemas. Conocer y utilizar las técnicas de ordenación más comunes. Utilizar las estructuras y algoritmos estudiados para elaborar un proyecto de programación.
Temario UNIDAD 1: INTRODUCCION A LAS ESTRUCTURAS DE DATOS DEFINICIÓN DE TIPO DE DATOS TIPOS DE DATOS ABSTRACTOS TIPOS DE DATOS EN C UNIDAD 2: PILAS DEFINICIÓN Y REPRESENTACIÓN DE PILAS APLICACIONES UNIDAD 3: RECURSIÓN DEFINICIÓN DE FUNCIONES RECURSIVAS APLICACIONES DE LA RECURSIÓN UNIDAD 4: ESTRUCTURAS LINEALES DEFINICIÓN Y REPRESENTACIÓN DE LISTAS Y COLAS APLICACIONES DEFINICIÓN Y REPRESENTACIÓN DE LISTAS CIRCULARES APLICACIONES
Temario cont. UNIDAD 5: ÁRBOLES DEFINICIÓN Y REPRESENTACIÓN DE ÁRBOLES BINARIOS APLICACIONES ÁRBOLES GENERALES APLICACIONES UNIDAD 6: ORDENAMIENTO ALGORITMOS SIMPLES DE ORDENACIÓN ALGORITMOS AVANZADOS DE ORDENACIÓN UNIDAD 7: BUSQUEDA BÚSQUEDA LINEAL Y BINARIA HASH
Bibliografía ESTRUCTURAS DE DATOS EN C. Aaron M. Tenenbaum y Moshe A. Augenstein, Prentice Hall. ESTRUCTURA DE DATOS. Cairó y Guardati, Mc Graw Hill ALGORITMOS Y ESTRUCTURAS DE DATOS. Nicklaus Wirth, Prentice Hall. ALGORITMOS + ESTRUCTURAS DE DATOS = PROGRAMAS. Nicklaus Wirth, Prentice Hall.
Evaluación La evaluación se realizará por lo menos con tres exámenes y/o proyectos, los cuales medirán principalmente la habilidad de aplicar cada uno de los elementos vistos en clase, codificando programas que resuelvan un problema particular, preferentemente con un enfoque orientado a objetos. Forma de calificar: Exámenes Parciales 40 % Examen Final 20 % Prácticas 20 % Proyecto Final 20 %
TIPOS DE DATOS • Cualquier significado puede ser asignado a un patrón de bits en particular siempre y cuando sea hecho de forma consistente. • Es la interpretación del patrón de bits la que da el significado. • El método utilizado para interpretar un patrón de bits se denomina TIPO DE DATO.
ENTEROS BINARIOS Y DECIMALES Un entero binario se representa como una secuencia de 1’s y 0’s. Ejemplos: 00110100 = 0x28+0x27+1x26+1x25 +0x24+0x23+1x22+0x21+0x20 = 32 + 16 + 4 = 52 Un entero negativo se puede representar en complemento de 1 o de 2. Ejemplo: complemento de 1 complemento de 2 -52= 11001011 11001100 En BCD cada dígito decimal se representa con 4 binarios. Ejemplo: 3478 = 0011 0100 0111 1000 3 4 7 8
NÚMEROS REALES Los reales se representan en notación de punto flotante. Se utiliza una mantisa y una base elevada a un exponente. Usando 24 bits para la mantisa y 8 bits para el exponente, ambas en complemento de 2, tendríamos como ejemplo: el número 387.53 = 38753 x 10–2, se representa por 38753 = 0000 0000 1001 0111 0110 0001(mantisa) –2 = 1111 1110 (exponente) 387.53 = 0000 0000 1001 0111 0110 0001 1111 1110 Note que el exponente es de la base 10.
Otros ejemplos 0 0000 0000 0000 0000 0000 0000 0000 0000 100 0000 0000 0000 0000 0000 0001 0000 0010 0.5 0000 0000 0000 0000 0000 0101 1111 1111 0.000005 0000 0000 0000 0000 0000 0101 1111 1010 12000 0000 0000 0000 0000 0000 1100 0000 0011 -387.53 1111 1111 0110 1000 1001 1111 1111 1110 -12000 1111 1111 1111 1111 1111 0100 0000 0011
Límites El mayor número representable en esta notación es (223–1)x10127 El menor número representable en esta notación es 10–128
Actividad Escriba (si es posible) los siguientes números enteros como secuencias binarias de 8 y 16 bits. 105 –15 2748 Escriba los siguientes números reales como secuencias de bits usando 32 bits. 450.3 1.6x10–19 15x10–80 2.7182818284590
IMPLANTACIÓN DE DATOS Un tipo de datos se puede implantar por hardware o por software. Implantación por hardware es aquella en la que se construyen circuitos para realizar la operaciones. Implantación por software es aquella en la que las operaciones se realizan mediante programas con instrucciones del hardware.
Implementación de cadenas Suponga la existencia en el hardware de la operación: MOVER(fuente, destino, longitud) Así también las operaciones aritméticas comunes y saltos normales. Deseamos representar cadenas de longitud variable donde el primer carácter se la longitud de la cadena. Haciendo uso de MOVER deseamos implementar la operación MOVERVAR(fuente, destino) Donde “fuente” designa la cadena que se moverá y “destino” el lugar donde se moverá.
MOVERVAR MOVER(fuente, destino, 1); for(i = 1; i<destino; i++) MOVER(fuente[i], destino[i], 1) var[i] denota la posición i-ésima a partir de var.
CONCATVAR La operación CONCATVAR concatena dos cadenas. 4 H o l a 7 a t o d o s 11 H o l a a t o d o s
Código de CONCATVAR z = c1 + c2;//mueve la longitud MOVER(z, c3, 1); for(i = 1; i<=c1; i++)//mueve primera cadena MOVER(c1[i], c3[i], 1); for(i = 1; i<=c2; i++){//mueve segunda cadena x = c1 + i; MOVER(c2[i], c3[x], 1); }
Operación de CONCATVAR c1 4 H o l a c2 7 a t o d o s c3 mueve la longitud 11 mueve primera cadena c3 11 H o l a mueve segunda cadena c3 11 H o l a a t o d o s
Otra forma MOVERVAR(c2, c3[c1]); MOVERVAR(c1, c3); z = c1 + c2; MOVER(z, c3, 1);
c1 o l a 4 H c2 7 a t o d o s c3 MOVERVAR(c2,c3[c1]) c3[c1] 7 a t o d o s MOVERVAR(c1,c3) c3 H o l a a t o d o s c3 z = c1+c2;MOVER(z,c3,1); 11 H o l a a t o d o s
Cadenas terminadas en nulo En C las cadenas se terminan por un nulo (‘\0’). La implementación de MOVERVAR es en ese caso: i = 0; while(fuente[i]){ MOVER(fuente[i],destino[i],1); i++; }
La implementación de CONCATVAR es en ese caso: i = 0; while(c1[i]){//mover primera cadena MOVER(c1[i],c3[i],1); i++; } j = 0; while(c2[j]){//mover segunda cadena MOVER(c1[j++],c3[i++],1); }
Tipos de datos abstractos ADT Un Tipo de Datos Abstracto (ADT) consta de dos partes: Definición de valor Definición de operador Definición de valor: Definición de operador Cláusula de definición Encabezado Condición Precondiciones Postcondiciones
Números racionales como ADT /* definición de valores */ abstract typedef <integer, integer> RACIONAL; condition RACIONAL[1] <> 0; /* definición de operadores */ abstract RACIONAL makeRacional(int a, int b) precondition b <> 0; postcondition makeRacional[0] == a; makeRacional[1] == b;
Números racionales como ADTcont. abstract RACIONAL add(RACIONAL a, RACIONAL b) postcondition add[1] == a[1]*b[1]; add[0] == a[0]*b[1]+a[1]*b[0]; /* written a+b */ abstract RACIONAL mult(RACIONAL a, RACIONAL b) postcondition mult[0] == a[0]*b[0]; mult[1] == a[1]*b[1]; /* written a*b */ abstract equal(RACIONAL a, RACIONAL b) postcondition equal == (a[0]*b[1] == a[1]*b[0]); /* written a == b */
Secuencias como definición de valor Una secuencia es un conjunto ordenado de elementos. Se puede representar enumerando los elementos: S = <s0, s1, …, sn–1> Se definen funciones: first(S) – primero de la secuencia S. last(S) – último de la secuencia S. Las secuencias de elementos de tipo tp se definen como abstract typedef <<tp>> stp1;
Secuencias como definición de valor(cont.) Enumerando los tipos de cada elemento: abstract typedef <<tp1, tp2, ..,tpn>> stp2; Secuencias con n elementos del mismo tipo se definen: abstract typedef <<tp,n>> stp3;
Ejemplos Secuencia de enteros de cualquier longitud. abstract typedef <<integer>> intsec; Secuencia de 3 elementos uno entero, uno real y uno carácter abstract typedef <<integer,float,char>> stp3; Secuencia de 10 enteros abstract typedef <<integer,10>> intsec;
ADT para cadenas de longitud variable abstract typedef <<char>> STRING; abstract length(STRING s) postcondition length = len(s); abstract STRING concat(STRING s1, s2) postcondition concat = s1 + s2; abstract STRING substr(STRING s, int i,j) precondition 0<=i<len(s); 0<=j<=len(s)-i; postcondition substr = sub(s,i,j);
ADT para cadenas de longitud variable (cont.) abstract pos(STRING s1, s2) postcondition /* lastpos = len(s1)-len(s2)*/ ((pos==-1)&&(for(i=0;i<lastpos;i++) (s2<>sub(s1,i,len(s2))))) || ((pos>=0)&&(pos<=lastpos) &&(s==sub(s1,pos,len(s2))) &&(for(i=1;i<pos;i++) (s2<>sub(s1,i,len(s2))))) El for es verdadero si se cumple para toda i o si el límite inferior es mayor que el superior.
Tarea Escriba funciones en C que acepten dos cadenas de 0s y 1s que representen enteros binarios no negativos e imprima la cadena representando su suma y su producto, respectivamente. Escriba una especificación de ADT para números complejos a + bi, donde abs(a + bi) es sqrt(a2 + b2), (a + bi) + (a + bi) es (a + c) + (b + d)i, (a + bi) * (a + bi) es (a*c – bd) + (ad + bc)i y –(a + bi) es (– a) + (–b) i
Tipos básicos en C int - Enteros, pueden ser short (corto), long (largo) o usigned (sin signo). El tamaño real depende de la implementación. float - números reales de 4 bytes. char - caracteres de un byte. double - reales de doble precisión. Apuntadores - Un apuntador puede señalar a cualquier tipo de datos pero debe indicarse a que tipo señala.
Tamaño de los datos en C Tipo Rango unsigned char 0 a 255 char -128 a 127 enum -32,768 a 32,767 unsigned int 0 a 65,535 short int -32,768 a 32,767 int -32,768 a 32,767 unsigned long 0 a 4,294,967,295 Long -2,147,483,648 a 2,147,483,647 float 3.4x10-38 a 3.4x10+38 double 1.7x10-308 a 1.7x10+308 long double 3.4x10-4932 a 1.1x10+4932
Estructuras de datos en C Existen dos estructuras básicas en C: arreglos – estructura homogenea estructuras – estructuras heterogeneas. Se pueden combinar libremente estructuras y arreglos para construir tipos de datos más complejos.
Arreglos en C Declaración tipo identificador[tamaño]; Ejemplo int a[100]; Las dos operaciones básicas son la extracción y el almacenamiento. Extracción – acepta una arreglo y un índice y regresa un elemento del arreglo: a[i] Almacenamiento – acepta una arreglo, un índice y una variable x y asigna el valor de x a un elemento del arreglo: a[i] = x; Los arreglos en C inician siempre con el subíndice 0.
Arreglos como ADT abstract typedef <<eltype, ub>> ARRTYPE(ub, eltype); condition type(ub) == int; abstract eltype extract(ARRTYPE(ub,eltype) a,int i); /* written a[i] */ precondition 0<=i<ub; postcondition extract ai; abstract store(ARRTYPE(ub,eltype) a,int i,eltype elt); /* written a[i] = elt */ precondition 0<=i<ub; postcondition a[i] == elt;
Implantación de arreglos unidimensionales La declaración int b[100]; Reserva 100 localidades sucesivas en la memoria para almacenar cada una un valor entero. Al elemento b[0] lo denominamos base(b). Si esize es el tamaño de un entero, entonces para localizar al alemento i-ésimo se calcula la dirección base(b) + esize*i En C se expresa por b[i] o *(b + i)
Arreglos con elementos de tamaño variable 4 H o l a 7 a t o d o s 10 c o m o e s t a n 10 c o m p u t a d o r
Arreglos con elementos de tamaño variable H o l a \0 a t o d o s \0 c o m o e s t a n \0 c o m p u t a d o r \0
Arreglos con elementos de tamaño variable H o l a 4 a t o d o s 7 c o m o e s t a n 10 10 c o m p u t a d o r
Cadenas en C Las cadenas en C son secuencias de caracteres terminadas con el carácter nulo (‘\0’). Las funciones para manipular cadenas se encuentran en la biblioteca strinh.h. Algunas funciones de esta biblioteca se revisan a continuación.
int strlen(char s[]) int strlen(char s[]){ int i; for(i = 0; s[i] != ‘\0’; i++); return i; }
int strpos(char s1[], char s2[]) int strpos(char s1[], char s2[]){ int len1,len2,i,j1,j2; len1 = strlen(s1); len2 = strlen(s2); for(i = 0; i+len2<len1; i++); for(j1=i,j2=0;j2<=len2&&s1[j1]==s2[j2];j1++,j2++) if(j2==len2) return i; return -1; }
int strcat(char s1[], char s2[]) int strcat(char s1[], char s2[]){ int i, j; for(i = 0; s[i] != ‘\0’; i++); for(j = 0; s[j] != ‘\0’; s1[i++]=s2[j++]); }
int substr(char s1[], i, j, char s2[]) int substr(char s1[], int i, int j ,char s2[]){ int k, m; for(k = i, m = 0; m<j; s2[m++] = s1[k++]); s2[m] = ‘\0’; }
Arreglos bidimensionales Un arreglo bidimensional es un arreglo en el que los cada elemento es a su un arreglo. La siguiente declaración en C, declara un arreglo de 6 elementos en donde cada elemento es a su vez un arreglo de 4 elementos: int c[6][4]; La representación que se utiliza normalmente es la de renglón-mayor. El primer renglón ocupa la primer tira de elementos, el segundo renglón la segunda, y así sucesivamente.
Columna 0 Columna 1 Columna 2 Columna 3 Renglón 0 Renglón 1 Renglón 2 Renglón 3 Renglón 4 Renglón 5 { { { A[0][0] A[2][0] A[4][0] A[0][1] A[2][1] A[4][1] Renglón 0 Renglón 4 Renglón 2 A[0][2] A[2][2] A[4][2] { { { A[0][3] A[2][3] A[4][3] A[1][0] A[3][0] A[5][0] A[1][1] A[3][1] A[5][1] Renglón 5 Renglón 1 Renglón 3 A[1][2] A[3][2] A[5][2] A[1][3] A[3][3] A[5][3]
Cálculo de dirección Dada la declaración ar[r1][r2] La dirección de un elemento ar[i1][i2] se calcula mediante base(a) + (i1*r2 + i2)*esize Arreglos de más dimensiones se manejas de manera similar
Estructuras Una estructura identifica cada uno de los objetos que la forman mediante un identificador. A cada objeto de le llama miembro de la estructura. En algunos lenguajes se les llama campos y a la estructura se le llama registro.
Declaración de estructuras en C La declaración define sname y ename como variables de estructura struct nametype{ char first[10]; char midinit; char last[20]; }; struct nametype sname, ename; struct{ char first[10]; char midinit; char last[20]; }sname, ename;