Algoritmos y estructuras de datos
Tipos de datos abstractos y concretos
Francisco Javier Zaragoza Mart´ınez
Universidad Aut´onoma Metropolitana Unidad Azcapotzalco Departamento de Sistemas
4 de mayo de 2015
Tipos de datos
Abstractos
Un tipo de datos abstractoes un modelo matem´atico que se define mediante las operaciones permitidas en ciertos datos, incluyendo las precondiciones, restricciones y efectos de dichas operaciones.
Concretos
Un tipo de datos concretoes una implementaci´on de un tipo de datos abstracto en un programa de computadora.
Tipos de datos
Abstractos
Un tipo de datos abstractoes un modelo matem´atico que se define mediante las operaciones permitidas en ciertos datos, incluyendo las precondiciones, restricciones y efectos de dichas operaciones. Concretos
Un tipo de datos concretoes una implementaci´on de un tipo de datos abstracto en un programa de computadora.
Ejemplos de tipos de datos
Tipos de datos simples Tipos de datos num´ericos en C.
Abstracto Concreto Restricci´on
car´acter char ASCII
entero char 8 bits
entero short 16 bits con signo
entero int 32 bits con signo
entero long long 64 bits con signo natural unsigned 32 bits sin signo real float precisi´on simple real double precisi´on doble real long double precisi´on extendida
Ejemplo de tipo de datos abstracto y concreto
Operaciones de enteros con signo
entero int suma + resta -producto * cociente / residuo % igualdad == desigualdad != menor < mayor >
Tipo de datos abstracto conjunto
Operaciones de conjuntos
Operaciones matem´aticas de conjuntos: pertenencia ∈ igualdad = inclusi´on ⊂ uni´on ∪ intersecci´on ∩ diferencia \ sim´etrica ∆ cardinalidad | · | complemento ¯·
Adicionalmente queremos crear y destruir conjuntos, agregar o eliminar elementos de un conjunto, iterar sobre los elementos de un conjunto, etc.
Tipo de datos concreto: Arreglos de bits
¿C´omo representar un conjunto?
Si queremos representar un conjunto en un programa debemos saber: 1 La cantidad de elementos (digamos int n).
2 El tipo de sus elementos (digamos intde0a n-1). 3 D´onde almacenar el conjunto (digamos int a[n]).
4 C´omo guardar los elementos (ceros y unos ena[0..n-1]).
Ejemplo de un conjunto
int n = 10; /* h a s t a d i e z e l e m e n t o s en el c o n j u n t o */ int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0};
int c[ 1 0 ] ; /* c o n j u n t o sin i n i c i a l i z a r */
Tipo de datos concreto: Arreglos de bits
¿C´omo representar un conjunto?
Si queremos representar un conjunto en un programa debemos saber: 1 La cantidad de elementos (digamos int n).
2 El tipo de sus elementos (digamos intde0a n-1). 3 D´onde almacenar el conjunto (digamos int a[n]).
4 C´omo guardar los elementos (ceros y unos ena[0..n-1]).
Ejemplo de un conjunto
int n = 10; /* h a s t a d i e z e l e m e n t o s en el c o n j u n t o */ int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0};
Construir y destruir un conjunto
Crear un conjunto vac´ıo
v o i d c r e a(int n, int a[]) { int i; for (i = 0; i < n; i++) a[i] = 0; /* i no e s t a */ } Destruir un conjunto No es necesario hacer nada.
Construir y destruir un conjunto
Crear un conjunto vac´ıo
v o i d c r e a(int n, int a[]) { int i; for (i = 0; i < n; i++) a[i] = 0; /* i no e s t a */ } Destruir un conjunto No es necesario hacer nada.
Agregar elementos
Agregar un elemento
v o i d a g r e g a(int n, int a[] , int x) {
a[x] = 1; /* e s t o p u e d e f a l l a r */
}
Agregar un elemento
v o i d a g r e g a(int n, int a[] , int x) {
if (0 <= x && x < n)
a[x] = 1; }
Agregar elementos
Agregar un elemento
v o i d a g r e g a(int n, int a[] , int x) {
a[x] = 1; /* e s t o p u e d e f a l l a r */
}
Agregar un elemento
v o i d a g r e g a(int n, int a[] , int x) {
if (0 <= x && x < n)
a[x] = 1; }
Eliminar elementos
Eliminar un elemento
v o i d e l i m i n a(int n, int a[] , int x) {
a[x] = 0; /* e s t o p u e d e f a l l a r */
}
Eliminar un elemento
v o i d e l i m i n a(int n, int a[] , int x) {
if (0 <= x && x < n)
a[x] = 0; }
Eliminar elementos
Eliminar un elemento
v o i d e l i m i n a(int n, int a[] , int x) {
a[x] = 0; /* e s t o p u e d e f a l l a r */
}
Eliminar un elemento
v o i d e l i m i n a(int n, int a[] , int x) {
if (0 <= x && x < n)
a[x] = 0; }
Pertenencia de elementos
Pertenencia de un elemento
int p e r t e n e c e(int n, int a[] , int x) {
r e t u r n a[x]; /* e s t o p u e d e f a l l a r */
}
Pertenencia de un elemento
int p e r t e n e c e(int n, int a[] , int x) { if (0 <= x && x < n) r e t u r n a[x]; e l s e r e t u r n 0; }
Pertenencia de elementos
Pertenencia de un elemento
int p e r t e n e c e(int n, int a[] , int x) {
r e t u r n a[x]; /* e s t o p u e d e f a l l a r */
}
Pertenencia de un elemento
int p e r t e n e c e(int n, int a[] , int x) { if (0 <= x && x < n) r e t u r n a[x]; e l s e r e t u r n 0; }
Ejercicios
Ejercicios
1 Reescribe agrega,eliminaypertenecepara que informen de alguna manera razonable six est´a fuera de rango.
2 Reescribe agrega,eliminaypertenecepara que usen arreglos de char en lugar de arreglos deint. ¿Qu´e se gana?
3 Reescribe agrega,eliminaypertenecepara que usen un bit por elemento. ¿Qu´e se gana? ¿Qu´e se pierde? Pista: Deber´as estudiar los operadores de bits de C (~ & | ^ << >>).
Igualdad
Ejemplo: A y B no son iguales
int n = 10;
int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0};
Ejemplo: A y B s´ı son iguales
int n = 10;
int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
Igualdad
Ejemplo: A y B no son iguales
int n = 10;
int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0};
Ejemplo: A y B s´ı son iguales
int n = 10;
int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
int b[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
Igualdad
Igualdad A = B
int i g u a l(int n, int a[] , int b[]) { int i; for (i = 0; i < n; i++) if (a[i] != b[i]) r e t u r n 0; r e t u r n 1; }
Inclusi´
on
Ejemplo: A no es subconjunto de B int n = 10; int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1}; int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0}; Ejemplo: A s´ı es subconjunto de B int n = 10; int a[ 1 0 ] = {0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0}; int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0};Inclusi´
on
Ejemplo: A no es subconjunto de B int n = 10; int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1}; int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0}; Ejemplo: A s´ı es subconjunto de B int n = 10; int a[ 1 0 ] = {0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0}; int b[ 1 0 ] = {1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0};Inclusi´
on
Subconjunto A ⊂ B
int s u b c o n j u n t o(int n, int a[] , int b[]) { int i; for (i = 0; i < n; i++) if (a[i] == 1 && b[i] == 0) r e t u r n 0; r e t u r n 1; }
Uni´
on
Uni´on destructiva A ← A ∪ B
Esta funci´on agrega el contenido del segundo conjunto al primero. v o i d une(int n, int a[] , int b[])
{ int i; for (i = 0; i < n; i++) a[i] = a[i] || b[i]; } Ejemplo int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1}; int b[ 1 0 ] = {0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 1}; int a[ 1 0 ] = {0 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
Uni´
on
Uni´on destructiva A ← A ∪ B
Esta funci´on agrega el contenido del segundo conjunto al primero. v o i d une(int n, int a[] , int b[])
{ int i; for (i = 0; i < n; i++) a[i] = a[i] || b[i]; } Ejemplo int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1}; int b[ 1 0 ] = {0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 1}; int a[ 1 0 ] = {0 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
Uni´
on
Uni´on no destructiva C ← A ∪ B Esta funci´on construye un tercer conjunto.
v o i d une(int n, int a[] , int b[] , int c[]) { int i; for (i = 0; i < n; i++) c[i] = a[i] || b[i]; } Ejemplo int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1}; int b[ 1 0 ] = {0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 1}; int c[ 1 0 ] = {0 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
Uni´
on
Uni´on no destructiva C ← A ∪ B Esta funci´on construye un tercer conjunto.
v o i d une(int n, int a[] , int b[] , int c[]) { int i; for (i = 0; i < n; i++) c[i] = a[i] || b[i]; } Ejemplo int a[ 1 0 ] = {0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1}; int b[ 1 0 ] = {0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 1}; int c[ 1 0 ] = {0 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1};
Ejercicios
Ejercicios
1 Escribe cardinalidad, que diga cu´antos elementos tiene un conjunto. 2 Escribe complemento, que invierta los elementos de un conjunto. 3 Escribe intersecta,diferencia ysimetricadestructivas. 4 Escribe intersecta,diferencia ysimetricano destructivas, es
decir, el resultado debe quedar en un tercer conjunto. M´ınimo y m´aximo
Escribe funciones int min(int n, int a[])e int max(int n, int a[])
que regresen el menor y mayor elementos de un conjunto, respectivamente. Multiconjuntos
En unmulticonjunto cada elemento puede aparecer una o m´as veces. ¿C´omo modificar lo que vimos hoy para implementar multiconjuntos?
Conjuntos como arreglos de bits
Resumen de resultados
Operaciones sobre un conjunto A de hasta n elementos. Operaci´on S´ımbolo Tiempo
crear ∅ n
destruir 1
agregar A ∪ x 1
eliminar A \ x 1
pertenencia x ∈ A 1
Conjuntos como arreglos de bits
Resumen de resultados
Operaciones sobre dos conjuntos A y B de hasta n elementos. Operaci´on S´ımbolo Tiempo
igualdad A = B n
inclusi´on A ⊂ B n
uni´on A ∪ B n
intersecci´on A ∩ B n
diferencia A \ B n
sim´etrica A4B n
cardinalidad |A| n
Problemas y soluciones
Problemas
1 Todos los elementos deben ser del mismo tipo.
2 Todos los elementos deben ser enteros en el rango 0 a n − 1. 3 Debemos saber al principio la cantidad m´axima de elementos. 4 No podemos cambiar esa cantidad en tiempo de ejecuci´on. 5 Algunas funciones comouneycardinalidad sonmuy lentas.
6 Las funciones requieren pasar al menos dos par´ametros por conjunto.
Soluciones
En este curso resolveremos todos estos problemas (excepto el primero).
Problemas y soluciones
Problemas
1 Todos los elementos deben ser del mismo tipo.
2 Todos los elementos deben ser enteros en el rango 0 a n − 1. 3 Debemos saber al principio la cantidad m´axima de elementos. 4 No podemos cambiar esa cantidad en tiempo de ejecuci´on. 5 Algunas funciones comouneycardinalidad sonmuy lentas.
6 Las funciones requieren pasar al menos dos par´ametros por conjunto.
Soluciones