davidausubel.edu.ec

Anuncio
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
GUÍA DE ESTUDIO MODULAR
ESTRUCTURA DE DATOS II
TERCER NIVEL
TECNOLOGÍA EN:
INFORMÁTICA MENCIÓN: ANÁLISIS DE SISTEMAS
AUTOR:
RUDI FRANCISCO PUA
Corrección:
Comisión de Redacción
Aprobado:
Vicerrectorado Académico
Edición:
Instituto Superior Tecnológico “David Ausubel”
Periodo
Octubre 2015 – abril 2016
QUITO - ECUADOR
[email protected]
Página 1
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
PARA USTED APRECIADO ESTUDIANTE
LA DIRECCCIÓN ACADÉMICA A LA DISTANCIA LE ENVÍA EL MAS CORDIAL SALUDO Y ESPERA
QUE EN ESTE MODULO CUMPLA TODAS LAS ESPECTATIVAS PUESTAS EN NOSOTROS.
NO OLVIDE QUE EL ESTUDIAR Y TRABAJAR ENGRANDECE AL SER HUMANO
Y DE USTED DEPENDE EL ENGRANDECERSE.
El Instituto Tecnológico Superior “David Ausubel”, da la bienvenida a este
su módulo de ESTRUCTURA DE DATOS II y espera que el desarrollo del
mismo aporte para su vida profesional.
[email protected]
Página 2
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
NOTA:
EN ESTE TEXTO GUIA SE ENCUENTRA DESARROLLADOS LOS TEMAS QUE CORRESPONDEN A
ESTE MÓDULO, Y LAS TAREAS QUE USTED DEBE DESARROLLAR; CON LA AYUDA DEL TUTOR
USTED LLEGARÁ A DOMINAR EL CONOCIMIENTO.
1. EL ESTUDIANTE TIENE LAS OPORTUNIDADES QUE SEAN NECESARIAS PARA ACLARAR
LOS TEMAS QUE NO COMPRENDA MEDIANTE LA EXPLICACIÓN DEL TUTOR YA SEA DE
MANERA PRESENCIAL O MEDIANTE EL CORREO ELECTRONICO.
2. LAS TAREAS SERAN ENVIADAS POR EL TUTOR, DE ACUERDO A LAS FECHAS DEL
CALENDARIO Y DE ACUERDO AL DESARROLLO DEL MÓDULO.
3. ES OBLIGACION DEL ESTUDIANTE ASISTIR A CADA UNA DE LAS TUTORÍAS
PRESENCIALES PROGRAMADAS EN EL CALENDARIO DE ACTIVIDADES.
4. TODO TRABAJO DEL ESTUDIANTE SERÁ EVALUADO CUANTITATIVAMENTE.
5. AL FINAL EL TUTOR EVALUARA EL MÓDULO EN SU TOTALIDAD.
6. DE REQUERIR CUALQUIER INFORMACION DIRIGIRSE AL CORREO DE LA DIRECCION
ACADEMICA Y SERA ATENDIDO INMEDIATAMENTE EN SU CONSULTA.
[email protected]
GRACIAS.
[email protected]
Página 3
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
1.
PERFIL DE INFORMÁTICA MENCIÓN ANÁLISIS DE SISTEMAS
a)
OBJETIVO DE FORMACIÓN INTEGRAL DEL PROFESIONAL
Demostrar en el desempeño profesional de la informática un comportamiento ético que
se evidencie en el interés por la investigación e innovación tecnológica, con
responsabilidad social, espíritu empresarial y compromiso con el desarrollo sostenido y
sustentable del país.
b) PERFIL DEL TECNÓLOGO EN INFORMÁTICA
Es un profesional capaz de usar herramientas y técnicas para recolectar datos,
analizar, diseñar, desarrollar e implementar nuevos sistemas que permitan automatizar
los procedimientos de las empresas con fundamentos científicos, tecnológicos,
humanísticos y de gestión, demostrando sólidos valores ético-morales.
c) COMPETENCIAS PRINCIPALES POR DESARROLLAR
 Conducir el ciclo de vida de un sistema de información que permita automatizar
el manejo de los datos mediante un sistema de computadora, utilizando para
ello las diferentes herramientas informáticas existentes en el medio actual.
 Fundamentar cambios en la estructura organizacional, procedimientos, políticas
y funciones de una entidad que permitan optimizar el flujo de datos e
información, aumentando con ello la productividad y competitividad y
disminuyendo los costos operativos.
 Administrar las acciones para realizar un correcto análisis, diseño, desarrollo y
documentación de los sistemas informáticos de un centro de cómputo, que
cubran las expectativas de la institución y del medio en que se desenvuelve.
 Evaluar y seleccionar hardware y software, fundamentado en cuadros
comparativos técnicos que permitan satisfacer los requerimientos de las
empresas y organizaciones en general.
 Analizar de manera independiente e imparcial las bondades o defectos de un
sistema de información, mediante la valoración de todos los procesos que
intervienen, tomando en cuenta las necesidades y el presupuesto económico.
 Apoyar la toma de decisiones de la gerencia utilizando métodos matemáticos,
estadísticos, modelos de transporte y de investigación de operaciones.
SISTEMATIZACIÓN DE LAS COMPETENCIAS POR NIVELES
[email protected]
Página 4
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
d) NIVEL COMPETENCIA PRINCIPAL
 Instalar, operar y administrar programas utilitarios conociendo todos los
principios de la informática.
 Programar en lenguajes de tercera generación aplicando técnicas
especializadas y con pleno conocimiento de sistemas matemáticos y contables
 Conocer las acciones requeridas hacia la automatización de las empresas
mediante el análisis, diseño, desarrollo, documentación e implementación de
los sistemas.
 Diseñar y administrar Bases de datos, dominando la programación en
herramientas de cuarta generación y la programación orientada a objetos.
 Participar en el diseño de sistemas informáticos interactuando con plataformas
de internet y con pleno conocimiento de la administración de las redes y sus
sistemas operativos.
 Administrar las actividades de un departamento de cómputo con la aplicación
de herramientas informáticas y gerenciales incluyendo la creación de su propia
microempresa.
e) ESCENARIOS DE ACTUACIÓN
El Tecnólogo en Informática podrá desempeñarse en todo tipo de empresa pública o
Privada donde se requiera tratar de una manera especial a los datos y la información
que
Se generan dentro de la entidad, sea por procesos o por transacciones:
 ·Instituciones Bancarias
 Entidades Financieras
 Empresas Comerciales
 Empresas del estado
 Entes de servicio a la comunidad
 Instituciones de capacitación a nivel profesional, universitario o intermedio
 Empresas de Asesoría Informática
f) OCUPACIONES PROFESIONALES
El Tecnólogo en Informática podrá desempeñarse como:
 Gerente de Sistemas
[email protected]
Página 5
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
 Programador de computadoras
 Director de grupos de trabajo
 Administrador de Centros de Cómputo
 Asistente de gerencia
 Administrador de Bases de Datos
 Instructor de personal en el área informática
 Asesor organizacional de las empresas
 Asesor en el área informática
DESCRIPCIÓN DE LA ASIGNATURA
La materia esta orientada en cinco capítulos, los cuales están coordinados para que
el estudiante comprenda y relacione cada uno de sus contenidos en pro de una mejor
compresión y desarrollo; utilizando las diferentes opciones de programación que nos
ofrece el lenguaje de programación C++ y aplicando conceptos de árboles, grafos,
matriz dispersa con el fin de enriquecer su creatividad a la hora de aplicar la
programación
OBJETIVOS DE LA MATERIA
GENERAL:
Dotar al estudiante de los conocimientos necesarios para realizar programas y
consoliden un conocimiento básico en la programación, usando un medio de
resolución de problemas mediante técnicas de programación utilizando la herramienta
de programación denominada C++.
ESPECIFICOS:


Lograr que el estudiante adquiera, consolide y demuestre: conocimientos
profundos de la metodología de elaboración de programas; particularmente
mediante la utilización árboles; desarrollando conocimientos generales y
habilidades de conceptualización, compresión de análisis utilizan do
Lograr que el estudiante adquiera, consolide y demuestre: conocimientos
profundos en el análisis de estructuras; particularmente mediante la utilización
de árboles orientados.
[email protected]
Página 6
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
CONTENIDOS
CAPITULO I
1. ARBOLES BINARIOS
1.1 DEFINICIÓN
1.2 LOS ARBOLES TIENEN 3 RECORRIDOS DIFERENTES :
1.2.1 PRE-ORDEN
1.2.2 IN-ORDEN
1.2.3 BUSQUEDA
1.3 ARBOLES EN MONTON
1.3.1 INSERCIÓN
1.3.2 BUSQUEDA
1.3.3 ELIMINACIÓN
1.3.4 RECORRIDO(ORDENADO)
1.4 METODOS DE BUSQUEDAS
1.4.1 BUSQUEDA SECUENCIAL
1.4.2 BUSQUEDA BINARIA
1.4.3 BUSQUEDA POR HASH
CAPITULO II
2. MÉTODOS PARA RESOLVER EL PROBLEMA DE LAS COLISIONES
2.1.1 SONDEO LINEAL
2.1.2 DOBLE HASHING
2.2 ORDENAMIENTOS INTERNOS
2.2.1 BURBUJA
2.2.2 SHELLSORT
2.2.3 RADIXSORT
2.2.4 QUICKSORT
2.3 ORDENAMIENTOS EXTERNOS
2.3.1 MEZCLA DIRECTA
2.3.2 MEZCLA NATURAL
CAPITULO III
3. GRAFOS
2.1 OPERACIONES SOBRE GRAFOS
2.1.1 ALGORITMOS CREACIÓN
2.1.2 ALGORITMOS INSERCIÓN
2.1.3 ALGORITMOS BUSQUEDA
2.1.4 ALGORITMOS DE BORRADO
2.1.5 CAMINO MÍNIMO
2.2 MATRICES DISPERSAS
[email protected]
Página 7
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
DESARROLLO DEL CONTENIDO
CAPITULO I
1. ARBOLES BINARIOS
1.1 DEFINICIÓN:
Un Árbol Binario es un conjunto de finito de Elementos, de nombre Nodos de forma
que:
El Árbol Binario es Vació si no tiene ningún elemento en el.
El Árbol Binario contiene un Nodo Raíz y los dos que parten de él, llamados Nodo
Izquierdo y Nodo Derecho.
1.2 LOS ÁRBOLES TIENEN 3 RECORRIDOS DIFERENTES LOS CUALES SON:
1.2.1 Pre-Orden
1.2.1 In-Orden
1.2.3 Búsqueda
1.2.1 PRE-ORDEN
Definición:
El Recorrido “Pre-Orden” lo recorre de la siguiente manera, viaje a través del Árbol
Binario desplegando el Contenido en la Raíz, después viaje a través del Nodo
Izquierdo y después a través del Nodo Derecho.
Detalle:
Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra
manera Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos
dentro de él, lo recorrerá y viajara a través de los Arreglos Izq. y Der para determinar
que valor meter en la Pila y en Temp para de esta manera imprimir el siguiente
Elemento correspondiente.
Algoritmo:
Pre Ord (Árbol, Der, izq., Pila, Raíz)
Temp → Raiz
Top →
[email protected]
Página 8
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Pila [Top] → Nulo
Si Raíz = Nulo
Imprimir “Árbol Vació…” y Salir
Repetir mientras Temp ≠ Nulo
Imprimir Árbol [Temp]
Si Der [Temp] ≠ Nulo
Top → Top + 1
Pila [Top] → Der [Temp]
Si izq. [Temp] ≠ Nulo
Temp → izq.[Temp]
Si no:
Temp → Pila [Top];
Top → Top - 1
Fin del ciclo
Salir
DIAGRAMA:
[email protected]
Página 9
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
CORRIDA:
1.2.2 IN-ORDEN
Definición:
El Recorrido “In-Orden” lo recorre de la siguiente manera, viaje a través del Árbol
Binario desplegando el Contenido en el Nodo Izquierdo después la Raíz y finalmente
viaja a través del Nodo Derecho.
Detalle:
Temp toma el Valor de la Raíz y compara si el Árbol tiene algún Elemento, de otra
manera Desplegara “Árbol Vació…” y terminara el método. Si el Árbol tiene elementos
dentro de él, lo recorrerá y viajara a través de los Arreglos izq. y Der para determinar
que valor meter en la Pila y en Temp para de esta manera imprimir el siguiente
Elemento correspondiente.
Algoritmo:
Pre Ord (Árbol, Der, izq., Pila, Raíz)
Temp → Raiz
Top →
Pila [Top] → Nulo
Si Raíz = Nulo
Imprimir “Árbol Vacio…” y Salir
Etiqueta:
Mientras Temp ≠ Nulo
[email protected]
Página 10
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Top → Top + 1
Pila [Top] → Temp
Temp → izq. [Temp]
Fin del ciclo
Temp → Pila [Top]
Top → Top - 1
Mientras Temp ≠ Nulo
Imprimir Árbol [Temp]
Si Der [Temp] ≠ Nulo
Temp → Der [Temp]
Ir a Etiqueta
Temp → Pila [Top]
Top → Top - 1
Fin del ciclo
Salir
DIAGRAMA:
[email protected]
Página 11
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
CORRIDA:
1.2.3 BÚSQUEDA
Definición:
La Búsqueda es Similar a todas los Métodos anteriores de Búsqueda, simplemente
efectúa un recorrido comparando el Elemento que deseas encontrar contra cada uno
de los Elementos en los Arreglos.
Detalle:
El Algoritmo de Búsqueda compara el Elemento a buscar con cada uno de los datos
de nuestro Árbol, compara si el Elemento con el Nodo Raíz, si no se encuentra en la
Raíz… compara Elemento contra la Raíz para empezar a viajar por el Árbol
respectivamente, usa un método similar al anterior hasta encontrar el Elemento. De
otra forma la búsqueda es fallida.
Algoritmo:
Búsqueda (Árbol, Der, izq., Pila, Raíz, Elemí)
Si Raíz = Nulo
Imprimir “Árbol Vacío”
Pos → Nulo
Par → Nulo
Regresar Pos y Par
Salir
Si Elemí = Árbol [Raíz]
Imprimir “Elemento Encontrado”
Pos → Raíz
[email protected]
Página 12
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Par → Nulo
Regresar Pos y Par
Salir
Si Elemí < Árbol [Raíz]
Temp → izq. [Raíz]
Temp2 → Raíz
Si no:
Temp → Der [Raíz]
Temp2 → Raíz
Mientras Temp ≠ Nulo
Si Elemí = Árbol [Temp]
Imprimir “Elemento Encontrado…”
Pos → Temp
Par → Temp2
Regresar Pos y Par
Salir
Si Elemí < Árbol [Temp]
Temp2 → Temp
Temp → izq. [Temp]
Si no:
Temp2 → Temp
Temp → Der [Temp]
Fin del ciclo
Imprimir “Elemento no Encontrado…”
Pos → Nulo
Par → Temp2
Regresar Pos y Par
Salir
[email protected]
Página 13
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
DIAGRAMA:
CORRIDA:
1.3 PROGRAMA ARBOLES BINARIOS
#incluye <conio.h>
#include <iostream.h>
class Arbol
{
private:
int Top,Pila[10];
int Info[10],Izq[10],Der[10],Raiz,Disp;
public:
[email protected]
Página 14
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Arbol()
{
int in[10]={0,0,0,0,0,0,0,0,0,0};
For (int i=0; i<10; i++)
{
Info [I] =0;
Is [I] =i+1;
Der [I] =-999;
Pila [I] =0;
}
Top=0;
Dips=0;
Raiz=-999;
Is [9] =-999;
}
Void Preorder (void)
{
In Temp=Raiz;
Top=0;
Pila [0] =-999;
If (Raiz==-999)
{
Court<<"Arbor Macio..."<<end;
Return;
}
While (Temp! =-999)
{
Court<<Info [Temp] <<end;
If (Der [Temp]! =-999)
[email protected]
Página 15
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
{
Top++;
Pila [Top] =Der [Temp];
}
If (Is [Temp]! =-999)
{
Temp=Is [Temp];
}
Else
{
Temp=Pila [Top];
Top--;
}
}
}
Void in Ord (void)
{
In Temp=Raiz,
Top=0;
Pila [0] =-999;
If (Raiz==-999)
{
Court<<"Arbor Macio..."<<end;
Return;
}
Back:
While (Temp! =-999)
{
Top++;
[email protected]
Página 16
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Pila [Top] =Temp;
Temp=Is [Temp];
}
Temp=Pila [Top];
Top--;
While (Temp! =-999)
{
Court<<Info [Temp] <<end;
If (Der [Temp]! =-999)
{
Temp=Der [Temp];
Got Back;
}
Temp=Pila [Top];
Top--;
}
}
Void Post Ord (void)
{
In Temp=Raiz;
Top=0;
Pila [0] =-999;
If (Raiz==-999)
{
Court<<"Arbor Macio..."<<end;
Return;
}
Back1:
While (Temp! =-999)
[email protected]
Página 17
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
{
Top++;
Pila [Top] =Temp;
If (Der [Temp]! =-999)
{
Top++;
Pila [Top] =-Der [Temp];
}
Temp=Is [Temp];
}
Temp=Pila [Top];
Top--;
While (Temp>=0)
{
cout<<Info[Temp]<<endl;
if(Info[Temp]==Info[Raiz])
return;
Temp=Pila[Top];
Top--;
}
if(Temp<0)
{
Temp=-Temp;
goto Back1;
}
}
void Busqueda(int PosPad[2],int Elem)
{
int Temp,Temp2;
[email protected]
Página 18
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
if(Raiz==-999)
{
PosPad[0]=-999;
PosPad[1]=-999;
cout<<"Arbol Vacio..."<<endl;
return;
}
if(Elem==Info[Raiz])
{
PosPad[0]=Raiz;
PosPad[1]=-999;
cout<<"Elemento Encontrado..."<<endl;
return;
}
if(Elem<Info[Raiz])
{
Temp=Izq[Raiz];
Temp2=Raiz;
}
else
{
Temp=Der[Raiz];
Temp2=Raiz;
}
while(Temp!=-999)
{
if(Elem==Info[Temp])
{
cout<<"Elemento Encontrado..."<<endl;
[email protected]
Página 19
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
PosPad[0]=Temp;
PosPad[1]=Temp2;
return;
}
if(Elem<Info[Temp])
{
Temp2=Temp;
Temp=Izq[Temp];
}
else
{
Temp2=Temp;
Temp=Der[Temp];
}
}
PosPad[0]=-999;
PosPad[1]=Temp2;
cout<<"Elemento no Encontrado..."<<endl;
}
void InsOrd(int Elem)
{
int PosPad[2],Temp;
if(Disp!=-999)
{
Busqueda(PosPad,Elem);
clrscr();
if(PosPad[0]!=-999)
{
cout<<"Elemento Existente... Imposible Insertar..."<<endl;
[email protected]
Página 20
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
return;
}
Temp=Disp;
Disp=Izq[Disp];
Info[Temp]=Elem;
PosPad[0]=Temp;
Izq[Temp]=-999;
Der[Temp]=-999;
if(PosPad[1]==-999)
Raiz=Temp;
else if(Elem<Info[PosPad[1]])
Izq[PosPad[1]]=Temp;
else
Der[PosPad[1]]=Temp;
cout<<"Elemento Insertado..."<<endl;
return;
}
cout<<"Arbol Lleno... Imposible Insertar..."<<endl;
}
void Eliminar(int Elem)
{
int PosPad[2];
Busqueda(PosPad,Elem);
clrscr();
if(PosPad[0]==-999)
{
cout<<"El Elemento no se Encuentra en el Arbol... Imposible Eliminar..."<<endl;
return;
}
[email protected]
Página 21
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
if(Der[PosPad[0]]!=-999&&Izq[PosPad[0]]!=-999)
CasoB(PosPad);
else
CasoA(PosPad);
Izq[PosPad[0]]=Disp;
Disp=PosPad[0];
}
void CasoA(int PosPad[2])
{
int Temp;
if(Izq[PosPad[0]]==-999&&Der[PosPad[0]]==-999)
Temp=-999;
else if(Izq[PosPad[0]]!=-999)
Temp=Izq[PosPad[0]];
else
Temp=Der[PosPad[0]];
if(PosPad[1]!=-999)
{
if(PosPad[0]==Izq[PosPad[1]])
Izq[PosPad[1]]=Temp;
else
Der[PosPad[1]]=Temp;
}
else
Raiz=Temp;
}
void CasoB(int PosPad[2])
{
int PosPad2[2],Temp=Der[PosPad[0]],Temp2=PosPad[0];
[email protected]
Página 22
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
while(Izq[Temp]!=-999)
{
Temp2=Temp;
Temp=Izq[Temp];
}
PosPad2[0]=Temp;
PosPad2[1]=Temp2;
CasoA(PosPad2);
if(PosPad[1]!=-999)
{
if(PosPad[0]==Izq[PosPad[1]])
Izq[PosPad[1]]=PosPad2[0];
else
Der[PosPad[1]]=PosPad2[0];
}
else
Raiz=PosPad2[0];
Izq[PosPad2[0]]=Izq[PosPad[0]];
Der[PosPad2[0]]=Der[PosPad[0]];
}
}tec;
main()
{
int PosPad[2],res,op=0;
while(op!=7)
{
clrscr();
cout<<"\n1) Pre-Orden\n2) In-Orden\n3) Post-Orden\n4) Busqueda\n5) Insercion\n6)
Eliminar\n7) Salir"<<endl;
[email protected]
Página 23
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
gotoxy(1,1);
cout<<"Que deseas hacer?: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.PreOrd();
break;
case 2:
tec.InOrd();
break;
case 3:
tec.PostOrd();
break;
case 4:
cout<<"Que Numero deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(PosPad,res);
break;
case 5:
cout<<"Que Numero quieres Insertar?"<<endl;
cin>>res;
tec.InsOrd(res);
break;
case 6:
cout<<"Que Numero quieres Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
[email protected]
Página 24
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
break;
case 7:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}
1.3 ARBOLES EN MONTON
Definición:
El Árbol en Montón consiste en el ordenamiento de un conjunto de Elemento en un
solo arreglo.
Trabajaremos sobre la siguientes Operaciones en este Tema:
1.3.1
1.3.2
1.3.3
1.3.4
Inserción
Búsqueda
Eliminación
Recorrido (Ordenado)
1.3.1 Inserción
Definición:
El Concepto de Inserción ya es familiar para nosotros y sabemos que para realizar el
mismo no resulta complejo el procedimiento.
Pero en los Árboles en Montón es uno de los Métodos más largos para efectuarlo.
Detalle:
Básicamente lo que hace estos Algoritmos es la Inserción Ordenada. Primero
comparan si es posible insertar algún Elemento al Arreglo, si es posible hacerlo
Ingresa el Elemento a la Ultima posición.
Después básicamente acomoda el Arreglo con el Método de la Burbuja llamando a
otra serie de Métodos.
[email protected]
Página 25
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Algoritmos:
Insertar(Arbol, N, Elemento)
Si N<25
Arbol[N] -> a
N -> N + 1
OrdMon(Arbol, N)
Salir
//Fin de la condición//
Imprimir "Árbol Lleno..."
Salir
OrdMon(Arbol, Total)
ConstMon(Arbol, Total)
Mientras Total > 1
Total -> Total - 1
Burbuja(0, Total)
RecMon(Total, 0)
//Fin del ciclo//
Salir
ConstMon(Arbol, Total)
v -> (Total/2) - 1
Mientras v ≥ 0
RecMon(Arbol, Total, v)
v -> v - 1
//Fin del ciclo//
Salir
---RecMon(Arbol, Total, v)
w -> 2*v+1
Mientras w < Total
[email protected]
Página 26
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Si (w+1) < Total
Si Arbol[w+1] > Arbol[w]
w++
//Fin de la condición//
Fin de la condición
Si Arbol[v] ≥ Arbol[w]
Salir
//Fin de la condición//
Burbuja(Arbol, v, w)
v -> w
w -> 2*v+1
//Fin del ciclo//
Salir
---Burbuja(Arbol, v, w)
t -> Arbol[v]
Arbol[v] -> Arbol[w]
Arbol[w] -> t
Salir
Diagrama:
[email protected]
Página 27
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
CORRIDA:
1.3.2 Búsqueda
Definición:
El Concepto de Búsqueda es sencillo, simplemente es un método de búsqueda lineal.
Existen 3 posible resultados:
1. Que el Árbol este Vació y no se puede realizar la búsqueda.
2. Que el Elemento sea encuentre en el Árbol
3. Que el Elemento no este dentro del Árbol
Detalle:
Se manda al Método Búsqueda el Dato que se desea buscar, se acomoda el Árbol en
Orden en caso que no estuviera Ordenado y después compara con cada uno de los
datos.
Algoritmos:
**Busqueda(Arbol, N, Elemento)**
Si N ≠ 0
OrdMon(Arbol, N)
i ->
Mientras i < N;i++)
Si Arbol[i] = Elemento
Imprimir "Elemento Encontrado..."
Salir
//Fin de la condición//
i -> i + 1
[email protected]
Página 28
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
//Fin del ciclo//
Imprimir "El Elemento no esta en el Árbol..."
Salir
//Fin de la condición//
Imprimir "Árbol Vació..."
Salir
DIAGRAMA:
CORRIDA:
1.3.3 Eliminación
Definición:
El Concepto de Eliminación consiste en la búsqueda de un Elemento y sacarlo del
Arreglo. Existen 3 casos Diferentes;
1. Que el Árbol este Vació y no se puede realizar la eliminación
[email protected]
Página 29
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
2. Que el Elemento sea encuentre en el Árbol y sea eliminado
3. Que el Elemento no este dentro del Árbol por lo tanto no se elimina
Detalle:
Vemos si el Árbol tiene Elementos insertados en el, de otra forma será imposible
realizar la Eliminación ya que esta Vació. Después si el Árbol tiene Elementos lo
ordenamos y hacemos un búsqueda lineal para encontrar el dato. Después usamos el
método de la Burbuja para dejar el Elemento Eliminado hasta el final y le Restamos a
N un Elemento.
Algoritmo:
Eliminar (Arbol, N, Elemento)
Si N ≠ 0
OrdMon (Arbol, N)
I ->
Mientras I < N
Si Arbol[i] = Elemento
J -> i + 1
Mientras j < N
t -> Arbol[i]
Arbol[i] -> Arbol[j]
Arbol[j] -> t
j -> j + 1
//Fin del ciclo//
N -> n - 1
Imprimir "Elemento Eliminado..."
Salir
//Fin de la condición//
i -> i + 1
//Fin del ciclo//
Fin de la condición
Imprimir "Arbol Vacio... Imposible Eliminar..."
Salir
[email protected]
Página 30
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
DIAGRAMA:
CORRIDA:
1.3.4 Recorrido (Ordenado)
Definición:
El Recorrido simplemente ira desplegando cada uno de los Elementos del Árbol. Solo
existen 2 posibles casos:
1. Que el Árbol este Vació y no se pueda recorrer
2. El Árbol tenga Elementos para desplegar
Detalle:
Comparamos para comprobar que el Árbol tiene Elementos dentro de el, de ser así
Desplegamos cada uno de ellos. De otra manera Desplegamos Árbol Vació.
Algoritmo:
[email protected]
Página 31
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Recorrido(Arbol, N)
Si N ≠ 0
i ->
Mientras i < N
Imprimir Arbol[i]
i -> i + 1
//Fin del ciclo//
Salir
//Fin de la condición//
Imprimir "Arbol Vacio..."
Salir
CORRIDA:
PROGRAMA
#include <conio.h>
#include <iostream.h>
class Arbol_Monton
{
private:
int Arbol[25];
int N;
public:
[email protected]
Página 32
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Arbol_Monton()
{
for(int i=0;i<25;i++)
Arbol[i]=0;
N=0;
}
void Insertar(int a)
{
if (N<25)
{
Arbol[N]=a;
N++;
OrdMon(N);
return;
}
cout<<"Arbol Lleno..."<<endl;
}
void Eliminar(int a)
{
int t;
if(N!=0)
{
OrdMon(N);
for(int i=0;i<N;i++)
{
if(Arbol[i]==a)
{
for(int j=i+1;j<N;j++)
{
[email protected]
Página 33
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
t=Arbol[i];
Arbol[i]=Arbol[j];
Arbol[j]=t;
}
N--;
cout<<"Elemento Eliminado..."<<endl;
return;
}
}
}
cout<<"Arbol Vacio... Imposible Eliminar..."<<endl;
}
void Busqueda(int a)
{
if(N!=0)
{
OrdMon(N);
for(int i=0;i<N;i++)
if(Arbol[i]==a)
{
cout<<"Elemento Encontrado..."<<endl;
return;
}
cout<<"El Elemento no esta en el Arbol..."<<endl;
return;
}
cout<<"Arbol Vacio..."<<endl;
}
void OrdMon(int n)
[email protected]
Página 34
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
{
ConstMon(n);
while(n>1)
{
n--;
Burbuja(0,n);
RecMon(n,0);
}
}
void ConstMon(int n)
{
for(int v=n/2-1;v>=0;v--)
RecMon(n,v);
}
void RecMon(int n,int v)
{
int w=2*v+1;
while(w<n)
{
if(w+1<n)
if (Arbol[w+1]>Arbol[w])
w++;
if(Arbol[v]>=Arbol[w])
return;
Burbuja(v,w);
v=w;
w=2*v+1;
}
}
[email protected]
Página 35
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
void Burbuja(int i,int j)
{
int t=Arbol[i];
Arbol[i]=Arbol[j];
Arbol[j]=t;
}
void Recorrido()
{
if(N!=0)
{
for(int i=0;i<N;i++)
cout<<Arbol[i]<<endl;
return;
}
cout<<"Arbol Vacio..."<<endl;
}
}tec;
main()
{
int res,op=0;
while(op!=5)
{
clrscr();
cout<<"\n1) Recorrido\n2) Busqueda\n3) Insercion\n4) Eliminar\n5) Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer?: ";
cin>>op;
gotoxy(1,10);
switch (op)
[email protected]
Página 36
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
{
case 1:
tec.Recorrido();
break;
case 2:
cout<<"Que Numero deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 3:
cout<<"Que Numero quieres Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 4:
cout<<"Que Numero quieres Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 5:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}
[email protected]
Página 37
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
1.4 METODOS DE BUSQUEDAS
1.4.1 BUSQUEDA SECUENCIAL
DEFINICION:
La búsqueda es el proceso de localizar un registro (elemento) con un valor de llave
particular. La búsqueda termina exitosamente cuando se localiza el registro que
contenga la llave buscada, o termina sin éxito, cuando se determina que no aparece
ningún registro con esa llave.
Búsqueda secuencial, también se le conoce como búsqueda lineal. Supongamos una
colección de registros organizados como una lista lineal. El algoritmo básico de
búsqueda secuencial consiste en empezar al inicio de la lista e ir a través de cada
registro hasta encontrar la llave indicada (k), o hasta al final de la lista.
La situación óptima es que el registro buscado sea el primero en ser examinado. El
peor caso es cuando las llaves de todos los n registros son comparados con k (lo que
se busca). El caso promedio es n/2 comparaciones.
Este método de búsqueda es muy lento, pero si los datos no están en orden es el
único método que puede emplearse para hacer las búsquedas. Si los valores de la
llave no son únicos, para encontrar todos los registros con una llave particular, se
requiere buscar en toda la lista.
MEJORAS EN LA EFICIENCIA DE LA BÚSQUEDA SECUENCIAL
1) MUESTREO DE ACCESO
Este método consiste en observar que tan frecuentemente se solicita cada registro y
ordenarlos de acuerdo a las probabilidades de acceso detectadas.
2) MOVIMIENTO HACIA EL FRENTE
Este esquema consiste en que la lista de registros se reorganice dinámicamente. Con
este método, cada vez que búsqueda de una llave sea exitosa, el registro
correspondiente se mueve a la primera posición de la lista y se recorren una posición
hacia abajo los que estaban antes que el.
3) TRANSPOSICIÓN
Este es otro esquema de reorganización dinámica que consiste en que, cada vez que
se lleve a cabo una búsqueda exitosa, el registro correspondiente se intercambia con
el anterior. Con este procedimiento, entre más accesos tenga el registro, mas
rápidamente avanzara hacia la primera posición. Comparado con el método de
movimiento al frente, el método requiere más tiempo de actividad para reorganizar al
conjunto de registros. Una ventaja de método de transposición es que no permite que
el requerimiento aislado de un registro, cambie de posición todo el conjunto de
registros. De hecho, un registro debe ganar poco a poco su derecho a alcanzar el
inicio de la lista.
[email protected]
Página 38
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
4) ORDENAMIENTO
Una forma de reducir el numero de comparaciones esperadas cuando hay una
significativa frecuencia de búsqueda sin éxito es la de ordenar los registros en base al
valor de la llave. Esta técnica es útil cuando la lista es una lista de excepciones, tales
como una lista de decisiones, en cuyo caso la mayoría de las búsquedas no tendrán
éxito. Con este método una búsqueda sin éxito termina cuando se encuentra el primer
valor de la llave mayor que el buscado, en lugar de la final de la lista.
Programa:
#include <conio.h>
#include <iostream.h>
class Lista
{
private:
int Lista[10],N;
public:
Lista()
{
for(int i=0;i<10;i++)
Lista[i]=0;
N=0;
}
void Busqueda(int Elem)
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El "<<Elem<<" esta en la Lista"<<endl;
return;
}
[email protected]
Página 39
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
cout<<"El "<<Elem<<" no esta en la Lista"<<endl;
return;
}
cout<<"Lista Vacia..."<<endl;
return;
}
void Insertar(int Elem)
{
if(N<10)
{
Lista[N]=Elem;
N++;
cout<<"El "<<Elem<<" fue Insertado"<<endl;
return;
}
cout<<"Lista Llena... Imposible Insertar"<<endl;
return;
}
void Eliminar(int Elem)
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
N--;
return;
}
[email protected]
Página 40
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
}
cout<<"Lista Vacia... Imposible Eliminar..."<<endl;
return;
}
void Recorrido()
{
if(N!=0)
{
for(int i=0;i<N;i++)
cout<<Lista[i]<<endl;
}
cout<<"Lista Vacia..."<<endl;
}
}tec;
main()
{
int op=0,res;
while(op!=5)
{
clrscr();
cout<<"\n1) Recorrido\n2) Busqueda\n3) Insercion\n4) Eliminar un Dato\n5) Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
[email protected]
Página 41
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
break;
case 2:
cout<<"Que Numero de Control deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 3:
cout<<"Que Numero Deseas Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 4:
cout<<"Que Numero de Control deseas Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 5:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}
[email protected]
Página 42
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
CORRIDA:
1.4.2 BÚSQUEDA BINARIA
Definicion:
Se puede aplicar tanto a datos en listas lineales como en árboles binarios de
búsqueda. Los prerrequisitos principales para la búsqueda binaria son:
La lista debe estar ordenada en un orden especifíco de acuerdo al valor de la llave.
Debe conocerse el número de registros.
Algoritmo:
Se compara la llave buscada con la llave localizada al centro del arreglo.
Si la llave analizada corresponde a la buscada fin de búsqueda si no.
Si la llave buscada es menor que la analizada repetir proceso en mitad superior, sino
en la mitad inferior.
[email protected]
Página 43
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
El proceso de partir por la mitad el arreglo se repite hasta encontrar el registro o hasta
que el tamaño de la lista restante sea cero, lo cual implica que el valor de la llave
buscada no esta en la lista.
El esfuerzo máximo para este algoritmo es de log2n.
El mínimo de 1 y en promedio ½ log2 n.
Programa:
#include <conio.h>
#include <iostream.h>
class Lista
{
private:
int Lista[10],N;
public:
Lista()
{
for(int i=0;i<10;i++)
Lista[i]=0;
N=0;
}
void Busqueda(int Elem)
{
if(N!=0)
{
int inicio=0,medio,final=9;
while(inicio<=final)
{
medio=(inicio+final)/2;
if(Elem==Lista[medio])
[email protected]
Página 44
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
{
cout<<"El "<<Elem<<" esta en la Lista"<<endl;
return;
}
else if(Elem<Lista[medio])
{
final=medio-1;
}
else
{
inicio=medio+1;
}
}
cout<<"El "<<Elem<<" no esta en la Lista"<<endl;
return;
}
cout<<"Lista Vacia..."<<endl;
return;
}
void Insertar(int Elem)
{
if(N<10)
{
Lista[N]=Elem;
N++;
cout<<"El "<<Elem<<" fue Insertado"<<endl;
return;
}
cout<<"Lista Llena... Imposible Insertar"<<endl;
[email protected]
Página 45
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
return;
}
void Eliminar(int Elem)
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
N--;
return;
}
}
cout<<"Lista Vacia... Imposible Eliminar..."<<endl;
return;
}
void Recorrido()
{
if(N!=0)
{
for(int i=0;i<N;i++)
cout<<Lista[i]<<endl;
}
cout<<"Lista Vacia..."<<endl;
}
}tec;
main()
{
[email protected]
Página 46
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
int op=0,res;
while(op!=5)
{
clrscr();
cout<<"\n1) Recorrido\n2) Busqueda\n3) Insercion\n4) Eliminar un Dato\n5) Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
cout<<"Que Numero de Control deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 3:
cout<<"Que Numero Deseas Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 4:
cout<<"Que Numero de Control deseas Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
[email protected]
Página 47
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
case 5:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
CORRIDA
}
1.4.3 BÚSQUEDA POR HASH
Definición:
[email protected]
Página 48
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Hasta ahora las técnicas de localización de registros vistas, emplean un proceso de
búsqueda que implica cierto tiempo y esfuerzo. El siguiente método nos permite
encontrar directamente el registro buscado.
La idea básica de este método consiste en aplicar una función que traduce un conjunto
de posibles valores llave en un rango de direcciones relativas. Un problema potencial
encontrado en este proceso, es que tal función no puede ser uno a uno; las
direcciones calculadas pueden no ser todas únicas, cuando R (k1)= R (k2)
Pero: K1 diferente de K2 decimos que hay una colisión. A dos llaves diferentes que les
corresponda la misma dirección relativa se les llama sinónimos.
A las técnicas de cálculo de direcciones también se les conoce como:






Técnicas de almacenamiento disperso
Técnicas aleatorias
Métodos de transformación de llave - a- dirección
Técnicas de direccionamiento directo
Métodos de tabla Hash
Métodos de Hastings
Pero el término mas usado es el de Hastings. Al cálculo que se realiza para obtener
una dirección a partir de una llave se le conoce como función hash.
Ventaja
1. Se pueden usar los valores naturales de la llave, puesto que se traducen
internamente a direcciones fáciles de localizar
2. Se logra independencia lógica y física, debido a que los valores de las llaves
son independientes del espacio de direcciones
3. No se requiere almacenamiento adicional para los índices.
Desventajas
1.
2.
3.
4.
No pueden usarse registros de longitud variable
El archivo no esta clasificado
No permite llaves repetidas
Solo permite acceso por una sola llave
Costos


Tiempo de procesamiento requerido para la aplicación de la función hash
Tiempo de procesamiento y los accesos E/S requeridos para solucionar las
colisiones.
La eficiencia de una función hash depende de:
1. La distribución de los valores de llave que realmente se usan
2. El numero de valores de llave que realmente están en uso con respecto al
tamaño del espacio de direcciones
[email protected]
Página 49
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
3. El numero de registros que pueden almacenarse en una dirección dad sin
causar una colisión
4. La técnica usada para resolver el problema de las colisiones
Las funciones hash más comunes son:



Residuo de la división
Medio del cuadrado
Pliegue
HASHING POR RESIDUO DE LA DIVISIÓN
La idea de este método es la de dividir el valor de la llave entre un numero apropiado,
y después utilizar el residuo de la división como dirección relativa para el registro
(dirección = llave módulo divisor).
Mientras que el valor calculado real de una dirección relativa, dados tanto un valor de
llave como el divisor, es directo; la elección del divisor apropiado puede no ser tan
simple. Existen varios factores que deben considerarse para seleccionar el divisor:
1) El rango de valores que resultan de la operación “llave % divisor”, va desde
cero hasta el divisor 1. Luego, el divisor determina el tamaño del espacio de
direcciones relativas. Si se sabe que el archivo va a contener por lo menos n
registros, entonces tendremos que hacer que divisor > n, suponiendo que
solamente un registro puede ser almacenado en una dirección relativa dada.
2) El divisor deberá seleccionarse de tal forma que la probabilidad de colisión sea
minimizada. ¿Como escoger este numero? Mediante investigaciones se ha
demostrado que los divisores que son números pares tienden a comportase
pobremente, especialmente con los conjuntos de valores de llave que son
predominantemente impares. Algunas investigaciones sugieren que el divisor
deberá ser un número primo. Sin embargo, otras sugieren que los divisores no
primos trabajan también como los divisores primos, siempre y cuando los
divisores no primos no contengan ningún factor primo menor de 20. Lo más
común es elegir el número primo más próximo al total de direcciones.
Ejemplo:
Independientemente de que tan bueno sea el divisor, cuando el espacio de direcciones
de un archivo está completamente lleno, la probabilidad de colisión crece
dramáticamente. La saturación de archivo de mide mediante su factor de carga, el cual
se define como la relación del número de registros en el archivo contra el número de
registros que el archivo podría contener si estuviese completamente lleno.
Todas las funciones hash comienzan a trabajar probablemente cuando el archivo está
casi lleno. Por lo general el máximo factor de carga que puede tolerarse en un archivo
para un rendimiento razonable es de entre el 70 % y 80 %.
HASHING POR MEDIO DEL CUADRADO
En esta técnica, la llave es elevada al cuadrado, después algunos dígitos específicos
se extraen de la mitad del resultado para constituir la dirección relativa. Si se desea
[email protected]
Página 50
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
una dirección de n dígitos, entonces los dígitos se truncan en ambos extremos de la
llave elevada al cuadrado, tomando n dígitos intermedios. Las mismas posiciones de n
dígitos deben extraerse para cada llave.
Ejemplo:
Utilizando esta función Hastings el tamaño del archivo resultante es de 10n donde n es
el número de dígitos extraídos de los valores de la llave elevada al cuadrado.
HASHING POR PLIEGUE
En esta técnica el valor de la llave es particionada en varias partes, cada una de las
cuales
(Excepto la última) tiene el mismo número de dígitos que tiene la dirección relativa
objetivo. Estas particiones son después plegadas una sobre otra y sumadas. El
resultado, es la dirección relativa. Igual que para el método del medio del cuadrado, el
tamaño del espacio de direcciones relativas es una potencia de 10.
Ejemplo:
COMPARACIÓN ENTRE LAS FUNCIONES HASH
Aunque alguna otra técnica pueda desempeñarse mejor en situaciones particulares, la
técnica del residuo de la división proporciona el mejor desempeño. Ninguna función
hash se desempeña siempre mejor que las otras. El método del medio del cuadrado
puede aplicarse en archivos con factores de cargas bastantes bajas para dar
generalmente un buen desempeño. El método de pliegues puede ser la técnica más
fácil de calcular pero produce resultados bastante erráticos, a menos que la longitud
de la llave se aproximadamente igual a la longitud de la dirección.
Si la distribución de los valores de llaves no es conocida, entonces el método del
residuo de la división es preferible. Note que el Hastings puede ser aplicado a llaves
no numéricas. Las posiciones de ordenamiento de secuencia de los caracteres en un
valor de llave pueden ser utilizadas como sus equivalentes “numéricos”.
Alternativamente, el algoritmo hash actúa sobre las representaciones binarias de los
caracteres.
Todas las funciones hash presentadas tienen destinado un espacio de tamaño fijo.
Aumentar el tamaño del archivo relativo creado al usar una de estas funciones, implica
cambiar la función hash, para que se refiera a un espacio mayor y volver a cargar el
nuevo archivo.
[email protected]
Página 51
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
CAPITULO II
2. MÉTODOS PARA RESOLVER EL PROBLEMA DE LAS COLISIONES
Considere las llaves K1 y K2 que son sinónimas para la función hash R. Si K1 es
almacenada primero en el archivo y su dirección es R (K1), entonces se dice que K1
está almacenado en su dirección de origen.
Existen dos métodos básicos para determinar dónde debe ser alojado K2 :


Direccionamiento abierto.- Se encuentra entre dirección de origen para K2
dentro del archivo.
Separación de desborde (Área de desborde).- Se encuentra una dirección
para K2 fuera del área principal del archivo, en un área especial de desborde,
que es utilizada exclusivamente para almacenar registro que no pueden ser
asignados en su dirección de origen
Los métodos más conocidos para resolver colisiones son:
2.1.1 SONDEO LINEAL
Que es una técnica de direccionamiento abierto. Este es un proceso de búsqueda
secuencial desde la dirección de origen para encontrar la siguiente localidad vacía.
Esta técnica es también conocida como método de desbordamiento consecutivo.
Para almacenar un registro por Hastings con sondeo lineal, la dirección no debe caer
fuera del límite del archivo, En lugar de terminar cuando el límite del espacio de
dirección se alcanza, se regresa al inicio del espacio y sondeamos desde ahí. Por lo
que debe ser posible detectar si la dirección base ha sido encontrada de nuevo, lo cual
indica que el archivo está lleno y no hay espacio para la llave.
Para la búsqueda de un registro por Hastings con sondeo lineal, los valores de llave de
los registros encontrados en la dirección de origen, y en las direcciones alcanzadas
con el sondeo lineal, deberá compararse con el valor de la llave buscada, para
determinar si el registro objetivo ha sido localizado o no.
El sondeo lineal puede usarse para cualquier técnica de Hastings. Si se emplea
sondeo lineal para almacenar registros, también deberá emplearse para recuperarlos.
2.1.2 DOBLE HASHING
En esta técnica se aplica una segunda función hash para combinar la llave original con
el resultado del primer hash. El resultado del segundo hash puede situarse dentro del
mismo archivo o en un archivo de sobre flujo independiente; de cualquier modo, será
necesario algún método de solución si ocurren colisiones durante el segundo hash.
La ventaja del método de separación de desborde es que reduce la situación de una
doble colisión, la cual puede ocurrir con el método de direccionamiento abierto, en el
cual un registro que no está almacenado en su dirección de origen desplazara a otro
[email protected]
Página 52
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
registro, el que después buscará su dirección de origen. Esto puede evitarse con
direccionamiento abierto, simplemente moviendo el registro extraño a otra localidad y
almacenando al nuevo registro en la dirección de origen ahora vacía.
Puede ser aplicado como cualquier direccionamiento abierto o técnica de separación
de desborde.
Para ambas métodos para la solución de colisiones existen técnicas para mejorar su
desempeño como:
1.- ENCADENAMIENTO DE SINÓNIMOS
Una buena manera de mejorar la eficiencia de un archivo que utiliza el cálculo de
direcciones, sin directorio auxiliar para guiar la recuperación de registros, es el
encadenamiento de sinónimos. Mantener una lista ligada de registros, con la misma
dirección de origen, no reduce el número de colisiones, pero reduce los tiempos de
acceso para recuperar los registros que no se encuentran en su localidad de origen. El
encadenamiento de sinónimos puede emplearse con cualquier técnica de solución de
colisiones.
Cuando un registro debe ser recuperado del archivo, solo los sinónimos de la llave
objetivo son accesados.
2.- Direccionamiento por cubetas
Otro enfoque para resolver el problema de las colisiones es asignar bloques de
espacio (cubetas), que pueden acomodar ocurrencias múltiples de registros, en lugar
de asignar celdas individuales a registros. Cuando una cubeta es desbordada, alguna
nueva localización deberá ser encontrada para el registro. Los métodos para el
problema de sobrecupo son básicamente los mismos que los métodos para resolver
colisiones.
COMPARACIÓN ENTRE SONDEO LINEAL Y DOBLE HASHING
De ambos métodos resultan distribuciones diferentes de sinónimos en un archivo
relativo. Para aquellos casos en que el factor de carga es bajo (< 0.5), el sondeo lineal
tiende a agrupar los sinónimos, mientras que el doble Hastings tiende a dispersar los
sinónimos más ampliamente a través del espacio de direcciones.
El doble Hastings tiende a comportarse casi también como el sondeo lineal con
factores de carga pequeños (< 0.5), pero actúa un poco mejor para factores de carga
mayores. Con un factor de carga > 80 %, el sondeo lineal por lo general resulta tener
un comportamiento terrible, mientras que el doble Hastings es bastante tolerable para
búsquedas exitosas pero no así en búsquedas no exitosas.
[email protected]
Página 53
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
2.2 ORDENAMIENTOS INTERNOS
Introducción:
En esta Unidad explicaremos 4 algoritmos para el Ordenamiento de Arreglos en
Memoria RAM.
A continuación mencionaremos los diferentes métodos para ordenar:
1.
2.
3.
4.
Burbuja
ShellSort
RadixSort
QuickSort
2.2.1 BURBUJA
DEFINICIÓN:
El método de la burbuja es una comparación lineal con cada uno de los elementos, el
elemento que sea menor contra el que se está comparado intercambiaran posiciones.
Este método no es recomendado para grandes comparaciones, ya que es un proceso
muy lento y requiere de una gran cantidad de Memoria RAM.
Programa:
#include <conio.h>
#include <iostream.h>
class Lista
{
private:
int Lista[10],N;
public:
Lista()
{
for(int i=0;i<10;i++)
Lista[i]=0;
N=0;
}
[email protected]
Página 54
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
void Burbuja(void)
{
if(N!=0)
{
int i,j,aux;
for(i=0;i<9;i++)
for(j=i+1;j<10;j++)
if(Lista[i]<Lista[j])
{
aux=Lista[i];
Lista[i]=Lista[j];
Lista[j]=aux;
}
cout<<"Lista Ordenada..."<<endl;
return;
}
cout<<"Lista Vacia..."<<endl;
}
void Busqueda(int Elem)
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El "<<Elem<<" esta en la Lista"<<endl;
return;
}
}
[email protected]
Página 55
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
cout<<"Lista Vacia..."<<endl;
return;
}
void Insertar(int Elem)
{
if(N<10)
{
Lista[N]=Elem;
N++;
cout<<"El "<<Elem<<" fue Insertado"<<endl;
return;
}
cout<<"Lista Llena... Imposible Insertar"<<endl;
return;
}
void Eliminar(int Elem)
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
Burbuja();
N--;
return;
}
}
cout<<"Lista Vacia... Imposible Eliminar..."<<endl;
[email protected]
Página 56
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
return;
}
void Recorrido()
{
if(N!=0)
{
for(int i=0;i<N;i++)
cout<<Lista[i]<<endl;
}
cout<<"Lista Vacia..."<<endl;
}
}tec;
main()
{
int op=0,res;
while(op!=6)
{
clrscr();
cout<<"\n1) Recorrido\n2) Ordenar\n3) Busqueda\n4) Insercion\n5) Eliminar un Dato\n6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
[email protected]
Página 57
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
tec.Burbuja();
break;
case 3:
cout<<"Que Numero de Control deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 4:
cout<<"Que Numero Deseas Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 5:
cout<<"Que Numero de Control deseas Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}
[email protected]
Página 58
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
2.2.2 SHELLSORT
Definición:
Esta forma de ordenación es muy parecida a la ordenación con burbuja. La diferencia
es que no es una comparación lineal, sino que trabaja con una segmentación entre los
datos. Por lo tanto es un buen método, pero no el mejor para implementarlos en
grandes arreglos.
Programa:
#include <conio.h>
#include <iostream.h>
class Lista
{
private:
int Lista[10],N;
public:
Lista()
{
for(int i=0;i<10;i++)
Lista[i]=0;
N=0;
}
void ShellSort(void)
{
if(N!=0)
{
int salto,aux,i;
for(salto=6/2;salto!=0;salto/=2)
{
for(i=salto;i<6;i++)
if(Lista[i-salto]<Lista[i])
{
[email protected]
Página 59
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
aux=Lista[i];
Lista[i]=Lista[i-salto];
Lista[i-salto]=aux;
}
}
cout<<"Lista Ordenada..."<<endl;
return;
}
cout<<"Lista Vacia..."<<endl;
}
void Busqueda(int Elem)
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El "<<Elem<<" esta en la Lista"<<endl;
return;
}
}
cout<<"Lista Vacia..."<<endl;
return;
}
void Insertar(int Elem)
{
if(N<10)
{
Lista[N]=Elem;
[email protected]
Página 60
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
N++;
cout<<"El "<<Elem<<" fue Insertado"<<endl;
return;
}
cout<<"Lista Llena... Imposible Insertar"<<endl;
return;
}
void Eliminar(int Elem)
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
ShellSort();
N--;
return;
}
}
cout<<"Lista Vacia... Imposible Eliminar..."<<endl;
return;
}
void Recorrido()
{
if(N!=0)
{
for(int i=0;i<N;i++)
cout<<Lista[i]<<endl;
[email protected]
Página 61
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
}
cout<<"Lista Vacia..."<<endl;
}
}tec;
main()
{
int op=0,res;
while(op!=6)
{
clrscr();
cout<<"\n1) Recorrido\n2) Ordenar\n3) Busqueda\n4) Insercion\n5) Eliminar un Dato\n6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
tec.ShellSort();
break;
case 3:
cout<<"Que Numero de Control deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
[email protected]
Página 62
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
case 4:
cout<<"Que Numero Deseas Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 5:
cout<<"Que Numero de Control deseas Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}
2.2.3 RADIXSORT
Definición:
Este ordenamiento se basa en los valores de los dígitos reales en las
representaciones de posiciones de los números que se ordenan. Es decir… toma un
número y lo descompone en sus unidades, decenas, centenas, etc… de esta manera
va determinando las posiciones de cada uno de ellos.
Programa:
#include <math.h>
#include <conio.h>
[email protected]
Página 63
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
#include <iostream.h>
class Lista
{
private:
int Lista[10],Temp[10],Elementos,N;
public:
Lista()
{
for(int i=0;i<10;i++)
Lista[i]=0;
N=9;
Elementos=0;
}
void Ordenar()
{
if(N!=9)
{
RadixSort(0,Elementos,Lista,Temp);
RadixSort(1,Elementos,Temp,Lista);
RadixSort(2,Elementos,Lista,Temp);
RadixSort(3,Elementos,Temp,Lista);
cout<<"Lista Ordenada..."<<endl;
return;
}
cout<<"Lista Vacia..."<<endl;
}
void RadixSort (int byte, int N, int *fuente, int *dest)
{
int cont[256];
[email protected]
Página 64
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
int ind[256];
int i;
memset(cont,0,sizeof(cont));
for(i=0;i<10;i++)
cont[((fuente[i])>>(byte*8))&0xff]++;
ind[0]=0;
for(i=1;i<256;i++)
ind[i]=ind[i-1]+cont[i-1];
for(i=0;i<10;i++)
dest[ind[((fuente[i])>>(byte*8))&0xff]++]=fuente[i];
}
void Busqueda(int Elem)
{
if(N!=9)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El "<<Elem<<" esta en la Lista"<<endl;
return;
}
}
cout<<"Lista Vacia..."<<endl;
return;
}
void Insertar(int Elem)
{
if(N!=-1)
{
[email protected]
Página 65
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
Elementos++;
Lista[N]=Elem;
N--;
cout<<"El "<<Elem<<" fue Insertado"<<endl;
return;
}
cout<<"Lista Llena... Imposible Insertar"<<endl;
return;
}
void Eliminar(int Elem)
{
if(N!=9)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
Ordenar();
N++;
Elementos--;
return;
}
}
cout<<"Lista Vacia... Imposible Eliminar..."<<endl;
return;
}
void Recorrido()
{
if(N!=9)
[email protected]
Página 66
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
{
for(int i=9;i!=N;i--)
cout<<Lista[i]<<endl;
return;
}
cout<<"Lista Vacia..."<<endl;
}
}tec;
main()
{
int op=0,res;
while(op!=6)
{
clrscr();
cout<<"\n1) Recorrido\n2) Ordenar\n3) Busqueda\n4) Insercion\n5) Eliminar un Dato\n6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
tec.Ordenar();
break;
case 3:
cout<<"Que Numero de Control deseas buscar?"<<endl;
[email protected]
Página 67
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
cin>>res;
tec.Busqueda(res);
break;
case 4:
cout<<"Que Numero Deseas Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 5:
cout<<"Que Numero de Control deseas Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 6:
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}
[email protected]
Página 68
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
2.2.4 QUICKSORT
Definición:
Probablemente este será el mejor de los métodos que mencionamos en esta unidad.
Este divide aleatoriamente el arreglo para comparar si un elemento es mayor o menor.
Dependiendo el resultado lo partirá ya sea por la izquierda o derecha, de esta forma se
repite el procedimiento para ordenarlos.
Programa:
#include <conio.h>
#include <iostream.h>
class Lista
{
private:
int Lista[10],N;
public:
Lista()
{
for(int i=0;i<10;i++)
Lista[i]=0;
N=1;
}
int Dividir(int menor,int mayor)
{
int izq,dch,temp;
izq=menor;
dch=mayor;
while(izq<dch)
{
while(Lista[dch]>Lista[menor])
dch--;
while((izq<dch)&&(Lista[izq]<=Lista[menor]))
[email protected]
Página 69
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
izq++;
if(izq<dch)
{
temp=Lista[izq];
Lista[izq]=Lista[dch];
Lista[dch]=temp;
}
}
temp=Lista[dch];
Lista[dch]=Lista[menor];
Lista[menor]=temp;
return dch;
}
void QuickSort(int menor,int mayor)
{
if(N!=1)
{
int medio;
if(menor<mayor)
{
medio=Dividir(menor,mayor);
QuickSort (menor,medio-1);
QuickSort (medio+1,mayor);
}
cout<<"Lista Ordenada..."<<endl;
}
cout<<"Lista Vacia..."<<endl;
}
void Busqueda(int Elem)
[email protected]
Página 70
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
{
if(N!=0)
{
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
cout<<"El "<<Elem<<" esta en la Lista"<<endl;
return;
}
}
cout<<"Lista Vacia..."<<endl;
return;
}
void Insertar(int Elem)
{
if(N<11)
{
Lista[10-N]=Elem;
N++;
cout<<"El "<<Elem<<" fue Insertado"<<endl;
return;
}
cout<<"Lista Llena... Imposible Insertar"<<endl;
return;
}
void Eliminar(int Elem)
{
if(N!=0)
{
[email protected]
Página 71
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
for(int i=0;i<N;i++)
if(Lista[i]==Elem)
{
Lista[i]=0;
QuickSort(0,9);
N--;
return;
}
}
cout<<"Lista Vacia... Imposible Eliminar..."<<endl;
return;
}
void Recorrido()
{
if(N!=1)
{
for(int i=1;i!=N;i++)
cout<<Lista[10-i]<<endl;
}
cout<<"Lista Vacia..."<<endl;
}
}tec;
main()
{
int op=0,res;
while(op!=6)
{
clrscr();
[email protected]
Página 72
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
cout<<"\n1) Recorrido\n2) Ordenar\n3) Busqueda\n4) Insercion\n5) Eliminar un Dato\n6)
Salir"<<endl;
gotoxy(1,1);
cout<<"Que deseas hacer: ";
cin>>op;
gotoxy(1,10);
switch (op)
{
case 1:
tec.Recorrido();
break;
case 2:
tec.QuickSort(0,9);
break;
case 3:
cout<<"Que Numero de Control deseas buscar?"<<endl;
cin>>res;
tec.Busqueda(res);
break;
case 4:
cout<<"Que Numero Deseas Insertar?"<<endl;
cin>>res;
tec.Insertar(res);
break;
case 5:
cout<<"Que Numero de Control deseas Eliminar?"<<endl;
cin>>res;
tec.Eliminar(res);
break;
case 6:
[email protected]
Página 73
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
cout<<"Salida...";
break;
default:
cout<<"Opcion Erronea"<<endl;
break;
}
getch();
}
}
2.3 ORDENAMIENTOS EXTERNOS
Introducción:
En esta Unidad explicaremos 2 algoritmos para el Ordenamiento de Archivos. A
continuación mencionaremos los diferentes métodos para ordenar:
1. Mezcla Directa
2. Mezcla Natural
2.3.1 MEZCLA DIRECTA
Definición:
Este algoritmo consiste en tener un archivo A desordenado. Este archivo se ordenara
haciendo los siguientes pasos:
1.- Definir tamaño de tramo igual a 1
2.- Repartir el archivo A en dos archivos B y C escribiendo alternadamente un tramo
en cada uno
3.- Aplicar el algoritmo de mezcla simple a cada par de tramos correspondiente de los
archivos B y C guardando el resultado en el archivo A
4.- Duplicar el tamaño del tramo
5.- Regresar al paso 2 si el tamaño del tramo es menor que la cantidad de elementos a
ordenar
Programa:
#include <stdio.h>
[email protected]
Página 74
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
class Archivos
{
public:
void Mostrar(FILE *fich)
{
char linea[128];
rewind(fich);
fgets(linea, 128, fich);
while(!feof(fich))
{
puts(linea);
fgets(linea, 128, fich);
}
}
void Mezcla(FILE *fich)
{
int ordenado;
FILE *aux[2];
do
{
aux[0] = fopen("aux1.txt", "w+");
aux[1] = fopen("aux2.txt", "w+");
rewind(fich);
Separar(fich, aux);
rewind(aux[0]);
[email protected]
Página 75
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
rewind(aux[1]);
rewind(fich);
ordenado = Mezclar(fich, aux);
fclose(aux[0]);
fclose(aux[1]);
}while(!ordenado);
remove("aux1.txt");
remove("aux2.txt");
}
void Separar(FILE *fich, FILE **aux)
{
char linea[128], anterior[2][128];
int salida = 0;
strcpy(anterior[0], "");
strcpy(anterior[1], "");
fgets(linea, 128, fich);
while(!feof(fich))
{
if(salida == 0 && strcmp(linea, anterior[0]) < 0)
salida = 1;
else if(salida == 1 && strcmp(linea, anterior[1]) < 0)
salida = 0;
strcpy(anterior[salida], linea);
fputs(linea, aux[salida]);
fgets(linea, 128, fich);
}
}
int Mezclar(FILE *fich, FILE **aux)
{
[email protected]
Página 76
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
char ultima[128], linea[2][128], anterior[2][128];
int entrada;
int tramos = 0;
fgets(linea[0], 128, aux[0]);
fgets(linea[1], 128, aux[1]);
strcpy(ultima, "");
strcpy(anterior[0], "");
strcpy(anterior[1], "");
while(!feof(aux[0]) && !feof(aux[1]))
{
if(strcmp(linea[0], linea[1]) <= 0)
entrada = 0;
else
entrada = 1;
strcpy(anterior[entrada], linea[entrada]);
fputs(linea[entrada], fich);
fgets(linea[entrada], 128, aux[entrada]);
if(strcmp(anterior[entrada], linea[entrada]) >= 0)
{
if(!entrada)
entrada = 1;
else
entrada = 0;
tramos++;
do
{
strcpy(anterior[entrada], linea[entrada]);
fputs(linea[entrada], fich);
fgets(linea[entrada], 128, aux[entrada]);
[email protected]
Página 77
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
}while(!feof(aux[entrada]) && strcmp(anterior[entrada], linea[entrada]) <= 0);
}
}
if(!feof(aux[0]))
tramos++;
while(!feof(aux[0]))
{
fputs(linea[0], fich);
fgets(linea[0], 128, aux[0]);
}
if(!feof(aux[1]))
tramos++;
while(!feof(aux[1]))
{
fputs(linea[1], fich);
fgets(linea[1], 128, aux[1]);
}
return(tramos == 1);
}
}tec;
main()
{
FILE *fichero;
int res,op=0,b=0;
while(op!=3)
{
clrscr();
cout<<"\n1) Recorrido Desordenado\n2) Recorrido Ordenado\n3) Salir"<<endl;
gotoxy(1,1);
[email protected]
Página 78
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
cout<<"Que deseas hacer?: ";
cin>>op;
gotoxy(1,10);
fichero = fopen("mezcla.txt", "r+");
switch (op)
{
case 1:
if(b!=1)
{
b=1;
tec.Mostrar(fichero);
}
else
cout<<"El Archivo ya esta Ordenado..."<<endl;
break;
case 2:
tec.Mezcla(fichero);
tec.Mostrar(fichero);
break;
case 3:
cout<<"Salir..."<<endl;
break;
default:
cout<<"Opcion Erronea..."<<endl;
break;
}
fclose(fichero);
getch();
}
[email protected]
Página 79
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
}
2.3.2 MEZCLA DIRECTA
Definición:
Es una mejora del algoritmo de mezcla directa puesto que en vez de considerar
tramos de tamaño fijo se toman en cuenta para la ordenación en todo momento tramos
de longitud máxima.
Al igual que la mezcla directa se debe hacer un proceso de partir el archivo original
para mezclarlo, posteriormente mientras en el archivo C haya elementos a mezclar.
Programa:
#include <conio.h>
#include <stdio.h>
#include <iostream.h>
#include <string.h>
void mezcla_directa(char *);
void mezclar(char *, int );
void partir(char *, int );
void mezcla_simple(char *,char *,char *);
void main(){
char n[10]="mezcla.txt";
mezcla_directa(n);
getch();
}
void mezcla_simple(char *A,char *B,char *C)
{
FILE *a,*b,*c;
int ra,rb;
a=fopen(A,"rb");
b=fopen(B,"rb");
c=fopen(C,"rb");
[email protected]
Página 80
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
if(a&&b&&c)
{
fread(&ra,sizeof(ra),1,a);
fread(&rb,sizeof(rb),1,b);
while(!feof(a)&&!feof(b))
{
if(ra<=rb)
{
fwrite(&ra,sizeof(ra),1,c);
fread(&ra,sizeof(ra),1,a);
}
else
{
fwrite(&rb,sizeof(rb),1,c);
fread(&ra,sizeof(ra),1,b);
}
}
while(!feof(a))
{
fwrite(&ra,sizeof(ra),1,c);
fread(&ra,sizeof(ra),1,a);
}
while(!feof(a))
{
fwrite(&rb,sizeof(rb),1,c);
fread(&rb,sizeof(rb),1,b);
}
fclose(a);
fclose(b);
[email protected]
Página 81
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
fclose(c);
}
}
void mezcla_directa(char *nom){
int t=1, n=5;
FILE *a,*b,*c;
a=fopen(nom,"r+");
b=fopen("m1.txt","r+");
c=fopen("m2.txt","r+");
while(t<n){
partir(nom,t);
mezcla_simple("m1.txt","m2.txt",nom);
mezclar(nom,t);
t = t* 2;
}
}
void partir(char *nom, int t){
FILE *a,*b,*c;
int reg, cont, sw=1;
a=fopen(nom,"r+");
b=fopen("m1.txt","a+");
c=fopen("m2.txt","a+");
if(a&&b&&c){
fread(&reg,sizeof(reg),1,a);
while(!feof(a)){
for(cont=0;cont<t && !feof(a);cont++){
if(sw)
fwrite(&reg,sizeof(reg),1,b);
else
[email protected]
Página 82
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
fwrite(&reg,sizeof(reg),1,c);
fread(&reg,sizeof(reg),1,a);
}
sw=!sw ;
}
}
fclose(a);
fclose(b);
fclose(c);
}
void mezclar(char *nom, int t){
FILE *a,*b,*c;
int rb,rc,ctb,ctc;
a= fopen(nom,"w+");
b= fopen("m1","r+");
c= fopen("m2","r+");
if(a&&b&&c){
fread(&rb,sizeof(rb),1,b);
fread(&rc,sizeof(rb),1,c);
while(!feof(b) && !feof(c)){
ctb=ctc=t;
while(ctb && ctc && !feof(b) && !feof(c)){
if(rb<rc){
fwrite(&rb,sizeof(rb),1,a);
fread(&rb,sizeof(rb),1,b);
ctb--;
}
else{
fwrite(&rc,sizeof(rc),1,a);
[email protected]
Página 83
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
fread(&rc,sizeof(rc),1,c);
ctc--;
}
}
while(ctb && !feof(b)){
fwrite(&rb,sizeof(rb),1,a);
fread(&rb,sizeof(rb),1,b);
ctb--;
}
while(ctc && !feof(c)){
fwrite(&rc,sizeof(rc),1,a);
fread(&rc,sizeof(rc),1,c);
ctc--;
}
}
while(!feof(b)){
fwrite(&rb,sizeof(rb),1,a);
fread(&rb,sizeof(rb),1,b);
}
while(!feof(c)){
fwrite(&rc,sizeof(rc),1,a);
fread(&rc,sizeof(rc),1,c);
}
}
fclose(a);
fclose(b);
fclose(c);
remove("m1");
remove("m2");
}
[email protected]
Página 84
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
CAPITULO III
3. GRAFOS
Definición:
Un grafo dirigido G consiste en un conjunto de vértices V y un conjunto de arcos o
aristas A. Los vértices 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értices 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.
2.1 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.
[email protected]
Página 85
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
2.1.1 ALGORITMO DE CREACION.
repite
si top=NIL entonces
new(top)
top(la)←NIL
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)
[email protected]
Página 86
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
lee(q(dato))
q(ld)←p(ld)
p(ld)←q
mensaje(otro vértice ?)
lee(respuesta2)
hasta respuesta2=no
p←p(la)
2.1.2 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
[email protected]
Página 87
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
new(p)
lee(p(dato))
q(ld)←p
q←q(ld)
en caso contrario
mensaje(no existe lista)
2.1.3 ALGORITMO DE BUSQUEDA
mensaje(vértice a buscar)
lee(vértice_a_buscar)
p←top
repite
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
2.1.4 ALGORITMOS DE BORRADO
mensaje(vértice a borrar ?)
lee(vértice_a_borrar)
[email protected]
Página 88
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
p←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
[email protected]
Página 89
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
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
2.1.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:
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])
[email protected]
Página 90
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
2.2 MATRICES DISPERSAS
La computación paralela es una herramienta esencial para la industria y la
investigación, que demandan ingentes cantidades de procesamiento. Entre la gran
variedad de campos que requieren computaciones de alto rendimiento, el álgebra
lineal es un área de especial interés porque constituye el núcleo computacional de
muchos problemas científicos y de ingeniería. Esta tesis se va a centrar en técnicas de
paralelización de algoritmos para la factorización de matrices, concretamente para la
factorización QR. El ámbito de la tesis es más específico todavía porque nos vamos a
limitar a matrices que tienen una gran cantidad de elementos nulos (matrices
dispersas). Consideraremos la paralelización de estos algoritmos a nivel de lazo y
siguiendo diversos enfoques que van a depender del grado de esfuerzo del
programador para desarrollar códigos paralelos.
La factorización QR consiste en la descomposición de una matriz A en el producto de
dos matrices: Q y R, donde Q es una matriz ortogonal y R una matriz triangular
superior. Hemos utilizado los tres métodos habituales que realizan la factorización QR:
el algoritmo de Gram-Schmidt modificado (GSM), las transformaciones de
Householder y las rotaciones de Givens. Esta factorización, que presenta una buena
estabilidad numérica, tiene diversas
aplicaciones en álgebra lineal: resolución de sistemas de ecuaciones lineales,
problemas de mínimos cuadrados, cálculo de autovalores y autovectores, problemas
de optimización, etc. Los algoritmos QR que hemos implementados incorporan un
pivotaje por columnas para preservar la estabilidad numérica y para revelar el rango
de la matriz a factorizar en el caso de que ésta no tenga rango máximo (QR rankrevealing).
En numerosas aplicaciones científicas, la matriz que se va a descomponer es
dispersa, es decir, tiene un gran número de ceros. En estas situaciones puede resultar
conveniente variar los algoritmos de la QR para tener en cuenta esa característica, con
el fin de ahorrar espacio de almacenamiento de las matrices en memoria, así como
una gran cantidad de computaciones, ya que éstas se van a realizar solamente con los
elementos no nulos. La elección de una estructura de almacenamiento apropiada para
la matriz dispersa es muy importante.
Durante la factorización de la matriz se produce un llenado (fill-in) de la misma, es
decir, se generan nuevos elementos no nulos, por lo que deberemos utilizar
estructuras de datos dinámicas. Concretamente, en nuestros algoritmos hemos
utilizado listas enlazadas y vectores comprimidos para almacenar la matriz dispersa.
Debido a que en estos algoritmos la matriz es accedida por columnas principalmente,
las estructuras de datos tienen una orientación por columnas, de tal forma que cada
columna de la matriz se va a representar mediante una lista enlazada o un vector
comprimido.
Uno de los principales inconvenientes de la factorización QR para matrices dispersas
es el llenado apuntado anteriormente, que requiere memoria y computaciones para los
nuevos elementos. Con el fin de reducir la generación de nuevos elementos no nulos,
hemos propuesto una estrategia que aprovecha el pivotaje por columnas.
Básicamente, este nuevo criterio consiste en seleccionar como columna pivote aquella
que contiene el menor número de elementos no nulos. Para probar esta estrategia,
hemos utilizado matrices dispersas de la
colección Harwell-Boeing y hemos conseguido reducir su llenado, por término medio,
en un 77% para el algoritmo GSM, 65% para Householder y 78% para Givens.
También hemos comprobado que el error numérico de los resultados se mantiene
utilizando este criterio.
Una vez estudiados los algoritmos QR secuenciales y su adaptación para matrices
dispersas, abordamos su paralización manual sobre sistemas multiprocesador de
[email protected]
Página 91
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
memoria distribuida considerando una topología de malla y un paradigma de
programación de paso de mensajes. Un factor fundamental en la paralelización es la
elección de una distribución adecuada para los datos. Para todos nuestros algoritmos
hemos elegido una distribución cíclica de la matriz a factorizar, por filas y por
columnas, como si la matriz fuese densa, pero solamente los elementos no nulos son
almacenados utilizando las estructuras de datos mencionadas anteriormente. Las
ventajas de esta distribución para nuestros algoritmos es que proporciona, en general,
un buen equilibrio de los datos y de las computaciones entre los diversos
procesadores.
Los algoritmos paralelos implantados van a tratar de reducir dos parámetros: las
Computaciones locales y las comunicaciones entre procesadores.
Con respecto a la reducción de computaciones locales, hemos incorporado a los
algoritmos paralelos la estrategia descrita anteriormente para reducir el llenado de la
matriz; además, hemos desarrollado operaciones optimizadas entre matrices
dispersas y vectores, para distintas estructuras de almacenamiento, con el fin de
reducir los tiempos de ejecución. En cuanto a la reducción de comunicaciones, en
algunas ocasiones utilizamos replicación de datos (principalmente vectores) sobre los
procesadores para favorecer la localidad de las computaciones. También hemos
diseñado operaciones optimizadas de reducción y radiación (broadcast) específicas
para los algoritmos paralelos con el fin de reducir las latencias de los mensajes
enviados entre los procesadores. con la misma finalidad, hemos intentado además
agrupar las comunicaciones para tratar de enviar pocos mensajes grandes en vez de
muchos mensajes de pequeño tamaño. Por último, proponemos una estrategia de
pivotaje local para eliminar las comunicaciones asociadas a esta fase durante la
ejecución de los
Algoritmos.
Los multiprocesadores sobre los que hemos ejecutado los algoritmos paralelos son el
Fujitsu AP1000 y el Cray T3D. Estos algoritmos incluyen, además de la factorización
QR, su aplicación a la resolución del problema de mínimos cuadrados. El lenguaje de
programación es C extendido con la librería de paso de mensajes PVM (Parallel Virtual
Machine) en el Cray y con las rutinas nativas CellOS en el AP1000. Los experimentos,
con matrices Harwell- Boeing, incluyen tiempos de ejecución, eficiencias, errores
numéricos y análisis del llenado de la matriz. Como conclusiones, estos algoritmos
presentan unas eficiencias bastante aceptables. Además, los algoritmos paralelos
presentan unos errores numéricos similares a los correspondientes algoritmos
secuenciales, siendo GSM el algoritmo con mayor error numérico. Los mayores
tiempos de ejecución corresponden a la algoritmo de Householder, debido a que
presenta un mayor llenado de la matriz mientras que Givens es el más rápido.
Las versiones de algoritmos que utilizan vectores comprimidos son más rápidas que
las que utilizan listas enlazadas debido a la mayor localidad espacial del vector
comprimido.
El siguiente paso consiste en aprovechar la experiencia obtenida en la paralelización
manual de los algoritmos e incorporar esas técnicas en una librería. Concretamente,
hemos desarrollado 3LM (Linked List Management Library), una librería para realizar
computaciones con matrices dispersas (principalmente factorizaciones) en paralelo. Su
objetivo es ayudar al programador a implementar de forma rápida y sencilla algoritmos
dispersos sobre multiprocesadores. La idea básica consiste en que el usuario escribe
programas pseudo-secuenciales y la librería se encarga de insertar las
comunicaciones necesarias, de forma totalmente transparente al usuario.
También se oculta al usuario la estructura interna de los esquemas de
almacenamiento de las matrices dispersas, para facilitar su manejo. 3LM está
disponible para lenguaje C en un entorno PVM. La librería incorpora un conjunto
completo de rutinas para realizar fácilmente distribuciones y redistribuciones de
[email protected]
Página 92
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
matrices dispersas (utilizando las estructuras de datos dinámicas ya mencionadas),
operaciones que soportan el llenado de una matriz, operaciones de reducción
predefinidas o definidas por el usuario, rutinas de pivotaje, etc. En el caso de que
estas rutinas de alto nivel no sean suficientes para implementar un algoritmo paralelo
determinado, 3LM también proporciona un conjunto de rutinas de bajo nivel que
permiten acceder directamente a los procesadores de la malla, así como a las
estructuras de datos dispersas. Estas rutinas permiten una mayor flexibilidad de
programación, pero como contrapartida con más difíciles de programar porque exigen
al usuario un conocimiento detallado de la estructura y distribución de los datos,
características que ya no son transparentes al programador.
Para probar la librería 3LM hemos implementado con sus rutinas de alto nivel los
algoritmos para la factorización QR. La reducción del esfuerzo de desarrollo (en
número de líneas de código) ha sido enorme con respecto a los códigos manuales
anteriormente descritos. Sin embargo, los tiempos de ejecución no son tan buenos
debido a que las rutinas de esta librería son genéricas, no son particulares para los
algoritmos QR y, obviamente, 3LM no pueden competir con el conocimiento profundo
que tiene el programador sobre los algoritmos, conocimiento que le permite desarrollar
códigos paralelos manuales muy optimizados.
Un paso más adelante en la reducción del esfuerzo de programación de algoritmos
dispersos paralelos consiste en la extensión de un lenguaje de paralelismo de datos
(data-parallel), para que incorpore estructuras de datos y distribuciones adecuadas
para computaciones dispersas. En un paradigma de programación de paralelismo de
datos, el usuario escribe un programa secuencial y añade un conjunto de directivas de
compilación para ayudar al compilador a generar código paralelo eficiente
(paralelización semiautomática).
Los lenguajes de paralelismo de datos están orientados principalmente a
computaciones con matrices densas y, generalmente, no soportan directivas para
optimizar la generación de códigos paralelos para matrices dispersas. Nuestro objetivo
es incorporar en el lenguaje de paralelismo de datos estándar HPF (High Performance
Fortran), cuyo lenguaje base en Frotran 90, un soporte de códigos dispersos. Para
ello, hemos extendido la sintaxis de HPF con una nueva directiva que hemos
denominado SPARSE. Mediante esta directiva podremos incorporar en HPF
esquemas de almacenamiento apropiados para matrices y vectores dispersos (listas,
vectores comprimidos), así como distribuciones de los mismos.
La inclusión de la nueva directiva SPARSE supone una extensión de la sintaxis de
HPF. Para ello, hemos desarrollado un módulo de compilación que funciona como un
preprocesador del código HPF extendido. La función de este módulo va a ser
reconocer los objetos (matrices, vectores) definidos por la directiva SPARSE e insertar
el soporte de ejecución necesario para realizar las comunicaciones pertinentes en el
código paralelo generado. El módulo de compilación se ha diseñado con la
herramienta de construcción de compiladores Cocktail. El soporte de ejecución
insertado por el módulo de compilación realiza funciones de comunicación asociadas a
la distribución y alineamiento de las estructuras de datos dispersas, gestión de
entrada/salida de dichas estructuras y comunicaciones necesarias para la obtención
de datos no locales. Este soporte de ejecución se ha desarrollado en Frotran 90 como
lenguaje base y las rutinas de comunicación SHMEM (Shared Memory), nativas de los
multiprocesadores Cray. También se ha desarrollado otra versión utilizando la librería
de paso de mensajes estándar MPI (Message Passing Interface) para garantizar la
portabilidad del soporte de ejecución.
Para comprobar la calidad de nuestro compilador de HPF extendido para
computaciones dispersas, hemos utilizado el código paralelo generado por este
compilador para algoritmos QR dispersos. Este código se ha ejecutado en un
multiprocesador Cray T3E y se obtuvieron unas eficiencias muy buenas del código
[email protected]
Página 93
INSTITUTO TECNOLÓGICO SUPERIOR
“DAVID AUSUBEL”
SEMIPRESENCIAL
VICERRECTORADO ACADÉMICO
paralelo, alcanzando la superlinealidad en algunas ocasiones para un determinado
número de procesadores. Estos resultados ratifican la idoneidad de extender el
lenguaje HPF con funcionalidades específicas para matrices dispersas.
A pesar de todos estos soportes para facilitar la programación de multiprocesadores,
los usuarios no expertos en supercomputación demandan herramientas de
paralelización automáticas para facilitar todavía más la programación de
supercomputadores. Por lo tanto, el paradigma de programación deseable sería que el
usuario escribiera programas secuenciales y que un reestructurador de código
generara el correspondiente código paralelo de forma totalmente automática.
Actualmente existen reestructuradores como SUIF y Polaris que realizan esta labor,
basándose en técnicas de análisis de dependencias. Sin embargo, sólo funcionan de
forma eficiente para un conjunto determinado de problemas regulares. Su labor se
complica enormemente para códigos que utilizan matrices dispersas, debido a la
aparición de una gran cantidad de direcciones en el programa que hace muy difícil su
análisis. Estas paralelizadas reses automáticas siguen una aproximación
conservadora, de tal forma que si tienen duda sobre si un lazo se puede paralelizar, no
lo paralelizan.
En esta tesis, como introducción a técnicas de paralelización automática, proponemos
un par de sencillos test en tiempos de ejecución para detectar paralelismo en códigos
que utilizan matrices dispersas. Estos dos test son la prueba de mono tonicidad en los
vectores de índices y la prueba de no solapamiento en los rangos de variables de
inducción. Estas pruebas son apropiadas para las estructuras de datos comprimidas
utilizadas y para los algoritmos de factorización QR, entre otros. La sobrecarga en el
tiempo de ejecución de estos test es mínima y sus beneficios son evidentes, ya que
permiten detectar automáticamente paralelismo en lazos a priori no paralelizadles.
Como conclusiones finales, esta tesis ha descubierto un amplio espectro de técnicas y
paradigmas de programación de arquitecturas multiprocesador. Se han realizado
diversas aportaciones en el campo de la paralelización manual de algoritmos para
matrices dispersas, en la paralelización semiautomáticas a través de la extensión de
un lenguaje de paralelismo de datos y en la paralelización automática de códigos
dispersos. Para ilustrar estas aportaciones se han utilizado, a lo largo de toda la tesis,
algoritmos para la factorización QR, aunque las ideas presentadas podrían aplicarse,
sin pérdida de generalidad, a una amplia variedad de algoritmos dispersos.
[email protected]
Página 94
Descargar