Sei sulla pagina 1di 69

Introduccin

Estructuras de datos

PROPSITO DEL CURSO


Estudiar las estructuras de datos bsicas utilizadas en la
resolucin de problemas de cmputo.
Utilizar algoritmos recursivos como una tcnica de control de
flujo en la solucin de problemas.
Conocer y utilizar las tcnicas de ordenacin ms comunes.
Utilizar las estructuras y algoritmos estudiados para elaborar un
proyecto de programacin.

Temario
UNIDAD 1: INTRODUCCION A LAS ESTRUCTURAS DE DATOS
DEFINICIN DE TIPO DE DATOS
TIPOS DE DATOS ABSTRACTOS
TIPOS DE DATOS EN C
UNIDAD 2: PILAS
DEFINICIN Y REPRESENTACIN DE PILAS
APLICACIONES
UNIDAD 3: RECURSIN
DEFINICIN DE FUNCIONES RECURSIVAS
APLICACIONES DE LA RECURSIN
UNIDAD 4: ESTRUCTURAS LINEALES
DEFINICIN Y REPRESENTACIN DE LISTAS Y COLAS
APLICACIONES
DEFINICIN Y REPRESENTACIN DE LISTAS CIRCULARES
APLICACIONES

Temario cont.
UNIDAD 5: RBOLES
DEFINICIN Y REPRESENTACIN DE RBOLES BINARIOS
APLICACIONES
RBOLES GENERALES
APLICACIONES
UNIDAD 6: ORDENAMIENTO
ALGORITMOS SIMPLES DE ORDENACIN
ALGORITMOS AVANZADOS DE ORDENACIN
UNIDAD 7: BUSQUEDA
BSQUEDA LINEAL Y BINARIA
HASH

Bibliografa
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.

Evaluacin
La evaluacin se realizar por lo menos con tres exmenes y/o
proyectos, los cuales medirn 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: Exmenes Parciales
Examen Final
Prcticas
Proyecto Final

40 %
20 %
20 %
20 %

TIPOS DE DATOS
Cualquier significado puede ser asignado a un patrn de
bits en particular siempre y cuando sea hecho de forma
consistente.
Es la interpretacin del patrn de bits la que da el
significado.
El mtodo utilizado para interpretar un patrn de bits se
denomina TIPO DE DATO.

ENTEROS BINARIOS Y
DECIMALES
Un entero binario se representa como una secuencia de 1s y 0s.
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 dgito decimal se representa con 4 binarios.
Ejemplo:
3478 = 0011 0100 0111 1000
3
4
7
8

NMEROS REALES
Los reales se representan en notacin 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, tendramos como ejemplo:
el nmero 387.53 = 38753 x 102, 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

Lmites
El mayor nmero representable en esta notacin es
(2231)x10127
El menor nmero representable en esta notacin es
10128

Actividad
Escriba (si es posible) los siguientes nmeros enteros como
secuencias binarias de 8 y 16 bits.
105
15
2748
Escriba los siguientes nmeros reales como secuencias de bits
usando 32 bits.
450.3

1.6x1019

15x1080

2.7182818284590

IMPLANTACIN DE DATOS
Un tipo de datos se puede implantar por hardware o por
software.
Implantacin por hardware es aquella en la que se
construyen circuitos para realizar la operaciones.
Implantacin por software es aquella en la que las
operaciones se realizan mediante programas con
instrucciones del hardware.

Implementacin de cadenas
Suponga la existencia en el hardware de la operacin:
MOVER(fuente, destino, longitud)
As tambin las operaciones aritmticas comunes y saltos
normales.
Deseamos representar cadenas de longitud variable donde el
primer carcter se la longitud de la cadena.
Haciendo uso de MOVER deseamos implementar la operacin
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 posicin i-sima a partir de var.

CONCATVAR
La operacin CONCATVAR concatena dos cadenas.

H o

11 H o

Cdigo 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);
}

Operacin de CONCATVAR

c1
4

H o

c2
d

c3

mueve la longitud
11
mueve primera cadena

c3
11 H o

a
mueve segunda cadena

c3
11 H o

Otra forma
MOVERVAR(c2, c3[c1]);
MOVERVAR(c1, c3);
z = c1 + c2;
MOVER(z, c3, 1);

c1
4

c2
c3

s
MOVERVAR(c2,c3[c1])

c3[c1]
7

MOVERVAR(c1,c3)

c3
H o

c3

z = c1+c2;MOVER(z,c3,1);
11 H o

Cadenas terminadas en nulo


En C las cadenas se terminan por un nulo (\0).
La implementacin de MOVERVAR es en ese caso:
i = 0;
while(fuente[i]){
MOVER(fuente[i],destino[i],1);
i++;
}

La implementacin 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:
Definicin de valor
Definicin de operador

Definicin de valor:

Definicin de operador

Clusula de definicin
Encabezado
Condicin

Precondiciones
Postcondiciones

Nmeros racionales como ADT


/* definicin de valores */
abstract typedef <integer, integer> RACIONAL;
condition RACIONAL[1] <> 0;

/* definicin de operadores */
abstract RACIONAL makeRacional(int a, int b)
precondition b <> 0;
postcondition makeRacional[0] == a;
makeRacional[1] == b;

Nmeros racionales como ADT


cont.
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 definicin de valor


Una secuencia es un conjunto ordenado de elementos.
Se puede representar enumerando los elementos:
S = <s0, s1, , sn1>
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 definicin 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 carcter
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 lmite 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 especificacin de ADT para nmeros 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 bsicos en C
int

float

- Enteros, pueden ser short (corto), long (largo)


o usigned (sin signo). El tamao real depende de
la implementacin.
- nmeros reales de 4 bytes.

char

- caracteres de un byte.

double

- reales de doble precisin.

Apuntadores - Un apuntador puede sealar a cualquier tipo de


datos pero debe indicarse a que tipo seala.

Tamao 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 bsicas en C:
arreglos estructura homogenea
estructuras estructuras heterogeneas.

Se pueden combinar libremente estructuras y arreglos para


construir tipos de datos ms complejos.

Arreglos en C
Declaracin
tipo identificador[tamao];
Ejemplo
int a[100];
Las dos operaciones bsicas son la extraccin y el
almacenamiento.
Extraccin 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 subndice 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;

Implantacin de arreglos
unidimensionales
La declaracin
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
tamao de un entero, entonces para localizar al alemento isimo se calcula la direccin
base(b) + esize*i
En C se expresa por
b[i]

*(b + i)

Arreglos con elementos de tamao


variable
4 H o

7 a

o d o s

10 c o m o

a n

10 c o m p u

a d o

Arreglos con elementos de tamao


variable
H o

a \0

o d o s \0

c o m o

a n \0

c o m p u

a d o

r \0

Arreglos con elementos de tamao


variable
4

H o

o d o s

10

c o m o

c o m p u

a d o

10

a n
r

Cadenas en C
Las cadenas en C son secuencias de caracteres terminadas con
el carcter nulo (\0).
Las funciones para manipular cadenas se encuentran en la
biblioteca strinh.h.
Algunas funciones de esta biblioteca se revisan a continuacin.

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 declaracin 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 representacin que se utiliza normalmente es la de renglnmayor.
El primer rengln ocupa la primer tira de elementos, el segundo
rengln la segunda, y as sucesivamente.

Rengln
Rengln
Rengln
Rengln
Rengln
Rengln

{
{

A[0][1]
A[0][2]
A[0][3]
A[1][0]

Rengln 1

Columna

Columna Columna
2

0
1
2
3
4
5

A[0][0]

Rengln 0

Columna

A[1][1]
A[1][2]
A[1][3]

{
{

A[2][0]
A[2][1]

Rengln 2

A[2][2]
A[2][3]
A[3][0]

Rengln 3

A[3][1]
A[3][2]
A[3][3]

{
{

A[4][0]
A[4][1]

Rengln 4

A[4][2]
A[4][3]
A[5][0]

Rengln 5

A[5][1]
A[5][2]
A[5][3]

Clculo de direccin
Dada la declaracin
ar[r1][r2]
La direccin de un elemento ar[i1][i2] se calcula mediante
base(a) + (i1*r2 + i2)*esize
Arreglos de ms 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.

Declaracin de estructuras en C
La declaracin define sname y ename como variables de estructura
struct nametype{
struct{

char first[10];

char first[10];

char midinit;

char midinit;

char last[20];

char last[20];
}sname, ename;

};
struct nametype sname,
ename;

Acceso a miembros
Para acceder a los miembros de una estructura se utiliza el
operador punto.
printf(%s,sname.first);
ename.midinit = M;
for(i=0; i<20; i++)
sname.last[i] = ename.last[i];

Estructuras anidadas
struct addstype{

struct nmadtype{

char straddr[40];

struct nametype name;

char city[10];

struct addrtype add;

char state[2];

};

char zip[5];
};
nmadtype nmad1,nmad2;
nmad1.name.midini = nmad2.name.midini;
nmad2.add.city[4] = nmad1.name.first[1];
for(i = 1; i<10 ;i++)
nmad1.name. first[i] = nmad2.name. first[i];

Ejemplo: nmeros racionales


Los nmeros racionales se pueden declarar como un estructura:

#include <stdio.h>
#include <conio.h>
struct racional{
int num, den;
};

Algoritmo de Euclides
para reducir un
racional

racional reduce(racional r){


racional s;
int a,b,t;
if(r.num>r.den){
a = r.num;
b = r.den;
}
else {
b = r.num;
a = r.den;
}
while(b!=0){
t = a % b;
a = b;
b = t;
}
s.num = r.num / a;
s.den = r.den / a;
return s;
}

racional mult(racional a, racional b){


racional c;
c.num = a.num*b.num;
c.den = a.den*b.den;
return reduce(c);
}
racional divi(racional a, racional b){
racional c;
c.num = a.num*b.den;
c.den = a.den*b.num;
return reduce(c);
}

racional suma(racional a,racional b){


racional c;
c.num = a.num*b.den+a.den*b.num;
c.den = a.den*b.den;
return reduce(c);
}
racional resta(racional a,racional b){
racional c;
c.num = a.num*b.den-a.den*b.num;
c.den = a.den*b.den;
return reduce(c);
}
void imprime(racional a){
printf("%d/%d\n",a.num,a.den);
}

Uniones
Una unin es una estructura en la que una misma rea de
memoria se comparte entre varias variables.
union nombre{
tipo nombre1;
tipo nombre1;
...
};
Solo se puede acceder a una variable a la vez.

ejemplo
union prueba{
a= 5, b= 0.000000, c=
int a;
double b;
a= 0, b= 5.000000, c=
char c;
a= 53, b= 5.000000, c= 5
};
main(){
prueba x;
x.a = 5;
printf("a= %d, b= %f, c= %c\n",x.a,x.b,x.c);
x.b = 5.0;
printf("a= %d, b= %f, c= %c\n",x.a,x.b,x.c);
x.c = '5';
printf("a= %d, b= %f, c= %c\n",x.a,x.b,x.c);
getch();
}

Ejemplo 2
struct fecha{
int dia,mes,anyo;
};
struct persona{
char nombre[20],apellido[20];
fecha nacimiento;
char sexo;
union{
struct {
float peso,estatura;
}varon;
struct {
int medidas[3];
}hembra;
};
};

void escribePersona(persona p){


printf("nombre: %s %s\n",p.nombre,p.apellido);
printf("fecha de nacimiento: %d/%d/%d\n",
p.nacimiento.dia,p.nacimiento.mes,p.nacimiento.anyo);
if(p.sexo=='H'){
printf("sexo: masculino\n");
printf("peso: %.1f, estatura: %.1f\n",
p.varon.peso,p.varon.estatura);
}
else{
printf("sexo: femenino\n");
printf("medidas: %d, %d, %d\n",p.hembra.medidas[0],
p.hembra.medidas[1],p.hembra.medidas[2]);
}
}

main(){
persona a = {"Juan","Perez",
{3,4,1980},'H',80,1.83},
b = {"Luisa","Lane",
{16,7,1990},'M',90,60};
escribePersona(a);
escribePersona(b);
b.hembra.medidas[0]=90;
b.hembra.medidas[1]=60;
b.hembra.medidas[2]=90; nombre: Juan Perez
fecha de nacimiento: 3/4/1980
escribePersona(b);
sexo: masculino
getch();
peso: 80.0, estatura: 1.8
}
nombre: Luisa Lane
fecha de nacimiento: 16/7/1990
sexo: femenino
medidas: 1119092736, 1114636288, 0
nombre: Luisa Lane
fecha de nacimiento: 16/7/1990
sexo: femenino
medidas: 90, 60, 90

Tipo coordenada
struct coordenada{
int tipo;
union {
struct{double x,y;}rect;
struct{double r,theta;}pol;
};
};

a.rect.x - componente x de a
a.rect.y - componente y de a
a.pol.r - distancia al origen de a
a.pol.theta - ngulo con eje x de a

Calculo de distancia
#define CARTESIANA 0
#define POLAR 1
double distancia(coordenada a,coordenada b){
double d;
switch(a.tipo){
case CARTESIANA:switch(b.tipo){
case CARTESIANA:
d = sqrt((a.rect.x-b.rect.x)*(a.rect.x-b.rect.x)+
(a.rect.y-b.rect.y)*(a.rect.y-b.rect.y));
break;
case POLAR:
d = sqrt((a.rect.x-b.pol.r*cos(b.pol.theta))*
(a.rect.x-b.pol.r*cos(b.pol.theta))+
(a.rect.y-b.pol.r*sin(b.pol.theta))*
(a.rect.y-b.pol.r*sin(b.pol.theta)));
break;
}break;

case POLAR:switch(b.tipo){
case CARTESIANA:
d = sqrt((a.pol.r*sin(a.pol.theta)-b.rect.x)*
(a.pol.r*sin(a.pol.theta)-b.rect.x)+
(a.pol.r*cos(a.pol.theta)-b.rect.y)*
(a.pol.r*cos(a.pol.theta)-b.rect.y));
break;
case POLAR:d =
sqrt(a.pol.r*a.pol.r+b.pol.r*b.pol.r2*a.pol.r*b.pol.r*cos(a.pol.thetab.pol.theta));
break;
}
}
return d;
}

Enumeraciones
Para definir una enumeracin se utiliza la palabra reservada
enum.
C asigna enteros consecutivos (comenzando por 0) a los valores
de las etiquetas a menos que se asignen valores explcitamente.
La sintaxis es la siguiente:
enum nombre {etiquetas};

ejemplo
#include <stdio.h>
#include <conio.h>
enum diaSemana {lunes, martes, miercoles, jueves,
viernes,sabado, domingo};
char dias[7][10] ={"lunes","martes","miercoles",
"jueves","viernes","sabado","domingo"};
main(){
diaSemana dia;
do{
printf("Teclee el numero del dia (0 a 6): ");
scanf("%d",&dia);
}while(dia<lunes || dia>domingo);
printf("El dia es: %s",dias[dia]);
getch();
}

#include <stdio.h>
#include <conio.h>
/* enum para definir constantes de tipo entero */
enum {SEC = 1, MIN = 60, HORA = 60*60, DIA =
24*60*60};
main(){
int segundos;
printf("Escriba numero de segundos: ");
scanf("%d",&segundos);
printf("%d segundos = %d minutos = %d horas"
" = %d dias\n", segundos, segundos/MIN,
segundos/HORA, segundos/DIA);
getch();
}

enum escapes{BELL='\a', BACKSPACE='\b',


HTAB='\t', RETURN = '\r', NEWLINE
=
'\n', VTAB = '\v' };
enum boolean { FALSE = 0, TRUE };
enum days {Jan=31, Feb=28, Mar=31,
Apr=30, May=31, Jun=30,
Jul=31, Aug=31, Sep=30,
Oct=31, Nov=30, Dec=31};

tarea
Se desea manejar la informacin de libros, revistas y pelculas.
De los libros se quiere mantener la siguiente informacin:
cdigo, autor, ttulo, editorial, ao; de las revistas la siguiente
informacin: cdigo, nombre, mes, ao; de las pelculas la
siguiente informacin: cdigo, ttulo, director, productora, ao.
Declare estructuras para cada elemento de informacin. Luego
declare una unin para representar los tres tipos de elementos.
Declare un arreglo llamado tabla que contenga 100 elementos
del tipo unin.
Escriba una funcin para desplegar la informacin de un
elemento de la tabla del problema anterior, ya sea libro, revista
o pelcula.

Potrebbero piacerti anche