Está en la página 1de 67

Introduccin

En este documento encontraremos informacin hacerca de la materia de Algoritmos, el cual nos


ser de mucha ayuda al momento de estudiar o buscar informacin hacerca de algn tema referente
a la materia, adems de darnos muchas facilidades que un cuaderno fsico no las tiene.

Marco Terico

Introduccin al estudio de algoritmos


QU ES ALGORITMO?

La palabra algoritmo se deriva de la traduccin al latn de la palabra rabe alkhowarizmi, nombre de


un matemtico y astrnomo rabe que escribi un tratado sobre manipulacin de nmeros y
ecuaciones en el siglo IX.

Un algoritmo es una serie de pasos organizados que describe el proceso que se debe seguir, para
dar solucin a un problema especfico.

TIPOS DE ALGORITMOS?

Existen dos tipos y son llamados as por su naturaleza:


Cualitativos: Son aquellos en los que se describen los pasos utilizando palabras.
Cuantitativos: Son aquellos en los que se utilizan clculos numricos para definir los pasos del
proceso.

Lenguajes Algortmicos

Un Lenguaje algortmico es una serie de smbolos y reglas que se utilizan para describir de manera
explcita un proceso.

Tipos de Lenguajes Algortmicos

Grficos: Es la representacin grfica de las operaciones que realiza un algoritmo (diagrama de


flujo).

4
No Grficos: Representa en forma descriptiva las operaciones que debe realizar un algoritmo
(pseudocodigo).

INICIO
Edad: Entero
ESCRIBA cul es tu edad?
Lea Edad
SI Edad >=18 entonces
ESCRIBA Eres mayor de Edad
FINSI
ESCRIBA fin del algoritmo
FIN

Metodologa para la creacin de algoritmos

Ahora que ya sabemos qu es un algoritmo, vamos a estudiar la metodologa para la solucin de un


problema mediante un ordenador. La creacin de un algoritmo y su programacin es una etapa, pero
como programador debes realizar varios pasos antes y despus.

El computador es una mquina que por s sola no puede hacer nada, necesita ser programada, es
decir, introducirle instrucciones u rdenes que le digan lo que tiene que hacer. Un programa es la
solucin a un problema inicial, as que todo comienza all: en el Problema. El proceso de
programacin es el siguiente: Dado un determinado problema el programador debe idear una solucin
y expresarla usando un algoritmo (aqu es donde entra a jugar); luego de esto, debe codificarlo en un
determinado lenguaje de programacin y por ltimo ejecutar el programa en el computador el cual
refleja una solucin al problema inicial. Esto es a grandes rasgos lo que hace el programador de
computadores.

La parte que corresponde a este manual es la de: Dado un determinado problema debemos idear una
solucin y expresarla usando un ALGORITMO!

5
Metodologa para la solucin de problemas por medio de computadora

DEFINICIN DEL PROBLEMA

Esta fase est dada por el enunciado del problema, el cual requiere una definicin clara y precisa.
Es importante que se conozca lo que se desea que realice la computadora; mientras esto no se
conozca del todo no tiene mucho caso continuar con la siguiente etapa.

ANLISIS DEL PROBLEMA

Una vez que se ha comprendido lo que se desea de la computadora, es necesario definir:


o Los datos de entrada.
o Cul es la informacin que se desea producir (salida)
o Los mtodos y frmulas que se necesitan para procesar los datos.
Una recomendacin muy prctica es el de colocarse en el lugar de la computadora y analizar qu
es lo que se necesita que se ordene y en qu secuencia para producir los resultados esperados.

DISEO DEL ALGORITMO

Las caractersticas de un buen algoritmo son:


o Debe tener un punto particular de inicio.
o Debe ser definido, no debe permitir dobles interpretaciones.
o Debe ser general, es decir, soportar la mayora de las variantes que se puedan presentar en la
definicin del problema.
o Debe ser finito en tamao y tiempo de ejecucin.
o Diseo del Algoritmo
o Prueba de escritorio o Depuracin

Se denomina prueba de escritorio a la comprobacin que se hace de un algoritmo para saber si est
bien hecho. Esta prueba consiste en tomar datos especficos como entrada y seguir la secuencia
indicada en el algoritmo hasta obtener un resultado, el anlisis de estos resultados indicar si el
algoritmo est correcto o si por el contrario hay necesidad de corregirlo o hacerle ajustes.

Los algoritmos conforman un conjunto de pasos que permiten llegar a la solucin del problema. Son
por naturaleza secuenciales, aunque varias tcnicas y herramientas aplicables a ellos ofrecen
mecanismos de repeticin. Son herramientas que tomamos prestadas de las matemticas para poder
dar soluciones computacionales a problemas cotidianos. En la prctica la solucin de un problema no

6
est compuesta por uno, sino por muchos algoritmos, cada uno encargado de resolver una porcin
del problema planteado.

En la vida cotidiana, se emplean algoritmos frecuentemente para resolver problemas. Algunos


ejemplos son los manuales de usuario, que muestran algoritmos para usar un aparato, o las
instrucciones que recibe un trabajador por parte de su patrn. Algunos ejemplos en matemtica son el
algoritmo de la divisin para calcular el cociente de dos nmeros, el algoritmo de Euclidespara
obtener el mximo comn divisor de dos enteros positivos, o el mtodo de Gauss para resolver
un sistema lineal de ecuaciones.

Caractersticas que Definen a Los Algoritmos

Tiempo secuencial. Un algoritmo funciona en tiempo discretizado paso a paso, definiendo as una
secuencia de estados "computacionales" por cada entrada vlida (la entrada son los datos que se le
suministran al algoritmo antes de comenzar).

Estado abstracto. Cada estado computacional puede ser descrito formalmente utilizando
una estructura de primer orden y cada algoritmo es independiente de su implementacin (los
algoritmos son objetos abstractos) de manera que en un algoritmo las estructuras de primer orden
son invariantes bajo isomorfismo.

Exploracin acotada. La transicin de un estado al siguiente queda completamente determinada por


una descripcin fija y finita; es decir, entre cada estado y el siguiente solamente se puede tomar en
cuenta una cantidad fija y limitada de trminos del estado actual.

Robustez: Un algoritmo debe cubrir todos los casos posibles de acuerdo a las alternativas de
seleccin. Debe funcionar para todos los casos esperados y no esperados.

Determinados: Los algoritmos tienen un inicio o fin determinados. No son infinitos.

Como Expresar Algoritmos

7
Los algoritmos pueden ser expresados de muchas maneras, incluyendo allenguaje
natural, pseudocdigo, diagramas de flujo y lenguajes de programacin entre otros. Las descripciones
en lenguaje natural tienden a ser ambiguas y extensas. El usar pseudocdigo y diagramas de flujo
evita muchas ambigedades del lenguaje natural. Dichas expresiones son formas ms estructuradas
para representar algoritmos; no obstante, se mantienen independientes de un lenguaje de
programacin especfico.

Diagramas de Flujo:

Los diagramas de flujo son descripciones grficas de algoritmos; usan smbolos conectados con
flechas para indicar la secuencia de instrucciones y estn regidos por ISO.

Los diagramas de flujo son usados para representar algoritmos pequeos, ya que abarcan mucho
espacio y su construccin es laboriosa. Por su facilidad de lectura son usados como introduccin a los
algoritmos, descripcin de un lenguaje y descripcin de procesos a personas ajenas a la
computacin.

Los algoritmos pueden ser expresados de muchas maneras,


incluyendo al lenguaje natural, pseudocdigo, diagramas de
flujo y lenguajes de programacin entre otros. Las
descripciones en lenguaje natural tienden a ser ambiguas y
extensas. El usar pseudocdigo y diagramas de flujo evita
muchas ambigedades del lenguaje natural. Dichas
expresiones son formas ms estructuradas para representar
algoritmos; no obstante, se mantienen independientes de un
lenguaje de programacin especfico.

Pseudocdigo:

El pseudocdigo (falso lenguaje, el prefijo pseudo significa falso) es una descripcin de alto nivel de
un algoritmo que emplea una mezcla de lenguaje natural con algunas convenciones sintcticas

8
propias de lenguajes de programacin, como asignaciones, ciclos y condicionales, aunque no est
regido por ningn estndar. Es utilizado para describir algoritmos en libros y publicaciones cientficas,
y como producto intermedio durante el desarrollo de un algoritmo, como los diagramas de flujo,
aunque presentan una ventaja importante sobre estos, y es que los algoritmos descritos en
pseudocdigo requieren menos espacio para representar instrucciones complejas.

El pseudocdigo est pensado para facilitar a las personas el entendimiento de un algoritmo, y por lo
tanto puede omitir detalles irrelevantes que son necesarios en una implementacin. Programadores
diferentes suelen utilizar convenciones distintas, que pueden estar basadas en la sintaxis de
lenguajes de programacin concretos. Sin embargo, el pseudocdigo, en general, es comprensible
sin necesidad de conocer o utilizar un entorno de programacin especfico, y es a la vez
suficientemente estructurado para que su implementacin se pueda hacer directamente a partir de l.

As el pseudodocdigo cumple con las funciones antes mencionadas para representar algo abstracto
los protocolos son los lenguajes para la programacin. Busque fuentes ms precisas para tener
mayor comprensin del tema

9
Fases de Desarrollo de un Algoritmo

Anlisis: es tomar el problema y construir los pasos.

Programacin: es realizar el algoritmo con la informacin del anlisis.

Codificacin: es generar el cdigo fuente tomando el algoritmo como base.

Edicin: se genera el programa fuente en un lenguaje de programacin.

Compilacin: se genera el programa objeto (escrito en lenguaje binario, lenguaje de maquina)

Enlace: se establece una relacin entre el programa objeto con otras aplicaciones adicionales.

Prueba: se maneja la aplicacin y se revisa si existen errores que incumplan con la robustez y
eficiencia del programa.

Algoritmos simples ejercicios

ALGORITMO #1

ALGORITMO: Promedio

DESCRIPCIN: Calcular la media (promedio) de 3 nmeros

CONSTANTES: --------------------------------

VARIABLES: Entero: N1, N2, N3 Real: Prom

INICIO

1. Leer N1, N2, N3


2. Prom= (N1+ N2+ N3)/3
3. Escribir Prom
FIN

10
ALGORITMO #2

ALGORTMO: Promedio final

DESCRIPCCION: Elaborar un algoritmo para calcular el promedio final de la materia de algoritmos.


Dicha calificacin se compone de los siguientes porcentajes.

55% -----del promedio final de sus calificaciones parciales (3)

30% ----- de la calificacin de promedio

15% ----- de la calificacin de un trabajo final

CONSTANTE: ----------------------------------

VARIABLE: Real: P1, P2, P3, Prom., Examen, TrabajoF, Prom. Final

INICIO

1. Leer P1, P2, P3


2. Prom=(( P1+ P2+ P3 )/3)*0.55
3. Leer Examen
4. Leer TrabajoF
5. Prom. Final= (Prom + (Examen*0.30) + (TrabajoF *0.15) )
6. Escribir Prom. Final
FIN

ALGORITMO #3

ALGORITMO: Sueldo

DESCRIPCCION: Calcular el sueldo de un empleado dados como datos de entrada: el nombre, hrs.
De trabajo y el pago en hr.

CONSTANTE: Real: Pagohr=50.30

VARIABLE: Cadena: nombre Entero: hrs. Real: Sueldo

INICIO

11
1. Leer nombre
2. Leer hrs.
3. Sueldo= Pagohr*hrs
4. Escribir Sueldo, nombre
FIN

ALGORITMO #4

ALGORITMO: Evaluacin

DESCRIPCCION: Elaborar un algoritmo que obtenga e imprima el valor de Y a partir de la ecuacin.

Y= 3*X2 + 7X - 15

CONATANTE: ------------------

VARIABLE: Real: X, Y

INICIO

1. Leer X
2. Y= (3*X*X)+(7*x) -15
3. Escribir Y
FIN

ALGORITMO #5

12
ALGORITMO: Sistema de ecuaciones

DECRIPCCION: El sistema de ecuaciones lineales:

ax + by= C

dx + dy= f

Se puede resolver con las formulas:

X= ce bf

ae bd

y= af cd

ae bd

Si ae bd 0

Elabore un algoritmo que lea los coeficientes a, b, c. e, f, y calcule los valores de x,, y.

CONSTANTE: ------------------------

VARIABLE: Real: a, b, c. d, e, f, x, y

INICIO

1. Leer a, b, c, d, e, f
2. x=(c*e) (b*f) /(a*e) (b*d)
3. y=(a*f) (c*d) / (a*e) (b*d)
4. Escribir x, y
FIN

ALGORITMO #6

ALGORITMO: Valor absoluto

DESCRIPCCION: Calcular el valor absoluto de un numero

x x Si x>0

-x Si x <o

CONSTANTES: ----------------------

VARIABLES: Entero: x

13
INICIO

1. Leer x
2. Si (x<0) entonces
X= x*(-1)

Fin_si

3. Escribir x
FIN

ALGORITMO: Par o impar

DESCRIPPCION: Elabora un algoritmo para leer un numero y determinar si es par o impar.

CONSTANTE: ---------------------------

VARIABLE: Entero: N

INICIO

1. Leer N
2. Si (N%2=0) entonces
Escribir N en par

Si no Escribir N es impar

Fin _ s

FIN

ALGORITMO #8

ALGORITMO: Nmeros

DESCRIPCCION: Elaborar un algoritmo para leer 3 nmeros y determinar s uno es la suma de los
otros dos.

CONSTANTES: -----------------------------

14
VARIABLES: entero: N1, N2, N3

INICIO

1. Leer N1, N2, N3


2. S (N1=N2 + N3) entonces
Escribir N1 es la suma de N2 + N3

S no s (N2=N1 + N3) entonces

Escribir N2 es la suma de N1 + N3

S ni s (N3= N1 + N2) entonces

Escribir N3 es la suma de N1 + N2)

S no Escribir Ningn es la suma de los otros dos

Fin _ s

Fin _ s

Fin _ s

FIN

ALGORITMO #9

ALGORITMO: Mltiplo de 3

DESCRIPCCION: Solicitar un entero y determinar s es mltiplo de 3 y adems que se encuentre en


el rango (100-200).

CONSTANTE: -------------------

VARIABLE: Entero: N

INICIO

1. Leer N
15
2. S (N>=100 y N<=200) entonces
S (N%3=0) entonces

Escribir N es mltiplo de 3 y esta dentro del rango

S no Escribir N no es mltiplo de 3 pero esta dentro del rango

Fin _s

S no Escribir N no esta en el rango

Fin _s

FIN

ALGORITMO #10

ALGORITMO: Signo zodiacal

DESCRIPCCION: Elaborar un algoritmo para leer la fecha de nacimiento de una persona y muestre
su signo zodiacal.

CONTANTES: ------------------

VARIABLES: Cadena: x Entero: w

INICIO

1. Leer x, y
2. S (x= marzo y w>= 21) y (x= abril y w<=20) entonces
Escribir Eres Aries

Fin _ s

S no s (x= abril y w>= 21) y (x= mayo y w<= 20) entonces

Escribir Eres Tauro

Fin _ s

S no s (x= mayo y w>= 21) y (x= junio y w<= 20) entonces

Escribir Eres Gminis

Fin _ s

16
S no s (x= junio y w>= 21) y (x= julio y w<= 20) entonces

Escribir Eres Cncer

Fin _ s

S no s (x= julio y w>= 21) y (x= agosto y w<= 20) entonces

Escribir Eres Leo

Fin _ s

S no s (x= agosto y w>= 21) y (x= septiembre y w<= 20) entonces

Escribir Eres Virgo

Fin _ s

S no s (x= septiembre y w>= 21) y (x= octubre y w<= 20) entonces

Escribir Eres Libra

Fin _ s

S no s (x= octubre y w>= 21) y (x= noviembre y w<= 20) entonces

Escribir Eres Escorpin

Fin _ s

S no s (x= noviembre y w>= 21) y (x= diciembre y w<= 20) entonces

Escribir Eres Sagitario

Fin _ s

S no s (x= diciembre y w>= 21) y (x= enero y w<= 20) entonces

Escribir Eres Capricornio

Fin _ s

S no s (x= enero y w>= 21) y (x= febrero y w<= 20) entonces

Escribir Eres Acuario

Fin _ s

S no s (x= febrero y w>= 21) y (x= marzo y w<= 20) entonces

Escribir Eres Picis

Fin _ s

17
S no Escribir Fecha no reconocida

Fin _s

FIN

Algoritmos para rboles y grafos

Definicin de rbol

Un rbol es una estructura de datos, que puede definirse de forma recursiva como:

- Una estructura vaca o un elemento o clave de informacin (nodo) ms un nmero finito de


estructuras tipo rbol, disjuntos, llamados subrboles. Si dicho nmero de estructuras es inferior o
igual a 2, se tiene un rbol binario.

Es, por tanto, una estructura no secuencial.

Otra definicin nos da el rbol como un tipo de grafo (ver grafos): un rbol es un grafo acclico,
conexo y no dirigido. Es decir, es un grafo no dirigido en el que existe exactamente un camino entre
todo par de nodos. Esta definicin permite implementar un rbol y sus operaciones empleando las
representaciones que se utilizan para los grafos. Sin embargo, en esta seccin no se tratar esta
implementacin.

18
Formas de representacin

- Mediante un grafo:

Figura 1

En la computacin se utiliza mucho una estructura de datos, que son los rboles binarios. Estos
rboles tienen 0, 1 2 descendientes como mximo. El rbol de la figura anterior es un ejemplo vlido
de rbol binario.

Nomenclatura sobre rboles

Raz: es aquel elemento que no tiene antecesor; ejemplo:

Rama: arista entre dos nodos.

Antecesor: un nodo X es es antecesor de un nodo Y si por alguna de las ramas de X se puede llegar
a Y.

Sucesor: un nodo X es sucesor de un nodo Y si por alguna de las ramas de Y se puede llegar a X.
- Grado de un nodo: el nmero de descendientes directos que tiene. Ejemplo: c tiene grado 2, d tiene
grado 0, a tiene grado 2.
- Hoja: nodo que no tiene descendientes: grado 0. Ejemplo: d
- Nodo interno: aquel que tiene al menos un descendiente.
- Nivel: nmero de ramas que hay que recorrer para llegar de la raz a un nodo. Ejemplo: el nivel del

19
nodo a es 1 (es un convenio), el nivel del nodo e es 3.
- Altura: el nivel ms alto del rbol. En el ejemplo de la figura 1 la altura es 3.
- Anchura: es el mayor valor del nmero de nodos que hay en un nivel. En la figura, la anchura es 3.

Aclaraciones: se ha denominado a a la raz, pero se puede observar segn la figura que cualquier
nodo podra ser considerado raz, basta con girar el rbol. Podra determinarse por ejemplo
que b fuera la raz, y a y d los sucesores inmediatos de la raz b. Sin embargo, en las
implementaciones sobre un computador que se realizan a continuacin es necesaria una jerarqua, es
decir, que haya una nica raz.

Declaracin de rbol binario

Se definir el rbol con una clave de tipo entero (puede ser cualquier otra tipo de datos) y dos hijos:
izquierdo (izq) y derecho (der). Para representar los enlaces con los hijos se utilizan punteros. El rbol
vaco se representar con un puntero nulo.

Un rbol binario puede declararse de la siguiente manera:

typedef struct tarbol


{
int clave;
struct tarbol *izq,*der;
} tarbol;

Otras declaraciones tambin aaden un enlace al nodo padre, pero no se estudiarn aqu.

Recorridos sobre rboles binarios

Se consideran dos tipos de recorrido: recorrido en profundidad y recorrido en anchura o a nivel.


Puesto que los rboles no son secuenciales como las listas, hay que buscar estrategias alternativas
para visitar todos los nodos.

20
- Recorridos en profundidad:

* Recorrido en preorden: consiste en visitar el nodo actual (visitar puede ser simplemente mostrar la
clave del nodo por pantalla), y despus visitar el subrbol izquierdo y una vez visitado, visitar el
subrbol derecho. Es un proceso recursivo por naturaleza.
Si se hace el recorrido en preorden del rbol de la figura 1 las visitas seran en el orden siguiente:
a,b,d,c,e,f.

void preorden(tarbol *a)


{
if (a != NULL) {
visitar(a);
preorden(a->izq);
preorden(a->der);
}
}

* Recorrido en inorden u orden central: se visita el subrbol izquierdo, el nodo actual, y despus se
visita el subrbol derecho. En el ejemplo de la figura 1 las visitas seran en este orden: b,d,a,e,c,f.

void inorden(tarbol *a)


{
if (a != NULL) {
inorden(a->izq);
visitar(a);
inorden(a->der);
}
}

* Recorrido en postorden: se visitan primero el subrbol izquierdo, despus el subrbol derecho, y


por ltimo el nodo actual. En el ejemplo de la figura 1 el recorrido quedara as: d,b,e,f,c,a.

void postorden(arbol *a)


{
if (a != NULL) {

21
postorden(a->izq);
postorden(a->der);
visitar(a);
}
}

La ventaja del recorrido en postorden es que permite borrar el rbol de forma consistente. Es decir, si
visitar se traduce por borrar el nodo actual, al ejecutar este recorrido se borrar el rbol o subrbol
que se pasa como parmetro. La razn para hacer esto es que no se debe borrar un nodo y despus
sus subrboles, porque al borrarlo se pueden perder los enlaces, y aunque no se perdieran se rompe
con la regla de manipular una estructura de datos inexistente. Una alternativa es utilizar una variable
auxiliar, pero es innecesario aplicando este recorrido.

- Recorrido en amplitud:

Consiste en ir visitando el rbol por niveles. Primero se visitan los nodos de nivel 1 (como mucho hay
uno, la raz), despus los nodos de nivel 2, as hasta que ya no queden ms.
Si se hace el recorrido en amplitud del rbol de la figura una visitara los nodos en este orden:
a,b,c,d,e,f
En este caso el recorrido no se realizar de forma recursiva sino iterativa, utilizando una cola. El
procedimiento consiste en encolar (si no estn vacos) los subrboles izquierdo y derecho del nodo
extrado de la cola, y seguir desencolando y encolando hasta que la cola est vaca.
En la codificacin que viene a continuacin no se implementan las operaciones sobre colas.

void amplitud(tarbol *a)


{
tCola cola; /* las claves de la cola sern de tipo rbol binario */
arbol *aux;

if (a != NULL) {
CrearCola(cola);
encolar(cola, a);
while (!colavacia(cola)) {
desencolar(cola, aux);
visitar(aux);
if (aux->izq != NULL) encolar(cola, aux->izq);
if (aux->der != NULL) encolar(cola, aux->der);

22
}
}
}

Por ltimo, considrese la sustitucin de la cola por una pila en el recorrido en amplitud. Qu tipo de
recorrido se obtiene?

Construccin de un rbol binario

Hasta el momento se ha visto la declaracin y recorrido de un rbol binario. Sin embargo no se ha


estudiado ningn mtodo para crearlos. A continuacin se estudia un mtodo para crear un rbol
binario que no tenga claves repetidas partiendo de su recorrido en preorden e inorden, almacenados
en sendos arrays.

Antes de explicarlo se recomienda al lector que lo intente hacer por su cuenta, es sencillo cuando uno
es capaz de construir el rbol viendo sus recorridos pero sin haber visto el rbol terminado.

Partiendo de los recorridos preorden e inorden del rbol de la figura 1 puede determinarse que la raz
es el primer elemento del recorrido en preorden. Ese elemento se busca en el array inorden. Los
elementos en el array inorden entre izq y la raz forman el subrbol izquierdo. Asimismo los
elementos entre der y la raz forman el subrbol derecho. Por tanto se tiene este rbol:

A continuacin comienza un proceso recursivo. Se procede a crear el subrbol izquierdo, cuyo


tamao est limitado por los ndices izq y der. La siguiente posicin en el recorrido en preorden es la
raz de este subrbol. Queda esto:

23
El subrbol b tiene un subrbol derecho, que no tiene ningn descendiente, tal y como indican los
ndices izq y der. Se ha obtenido el subrbol izquierdo completo de la raz a, puesto queb no tiene
subrbol izquierdo:

Despus seguir construyndose el subrbol derecho a partir de la raz a.

rbol binario de bsqueda

Un rbol binario de bsqueda es aquel que es:

24
- Una estructura vaca o
- Un elemento o clave de informacin (nodo) ms un nmero finito -a lo sumo dos- de estructuras tipo
rbol, disjuntos, llamados subrboles y adems cumplen lo siguiente:

* Todas las claves del subrbol izquierdo al nodo son menores que la clave del nodo.
* Todas las claves del subrbol derecho al nodo son mayores que la clave del nodo.
* Ambos subrboles son rboles binarios de bsqueda.

Un ejemplo de rbol binario de bsqueda:

Figura 5

Al definir el tipo de datos que representa la clave de un nodo dentro de un rbol binario de bsqueda
es necesario que en dicho tipo se pueda establecer una relacin de orden. Por ejemplo, suponer que
el tipo de datos de la clave es un puntero (da igual a lo que apunte). Si se codifica el rbol en Pascal
no se puede establecer una relacin de orden para las claves, puesto que Pascal no admite
determinar si un puntero es mayor o menor que otro.

En el ejemplo de la figura 5 las claves son nmeros enteros. Dada la raz 4, las claves del subrbol
izquierdo son menores que 4, y las claves del subrbol derecho son mayores que 4. Esto se cumple
tambin para todos los subrboles. Si se hace el recorrido de este rbol en orden central se obtiene
una lista de los nmeros ordenada de menor a mayor.
Cuestin: Qu hay que hacer para obtener una lista de los nmeros ordenada de mayor a menor?

Una ventaja fundamental de los rboles de bsqueda es que son en general mucho ms rpidos para
localizar un elemento que una lista enlazada. Por tanto, son ms rpidos para insertar y borrar
elementos. Si el rbol est perfectamente equilibrado -esto es, la diferencia entre el nmero de
nodos del subrbol izquierdo y el nmero de nodos del subrbol derecho es a lo sumo 1, para todos
los nodos- entonces el nmero de comparaciones necesarias para localizar una clave es

25
aproximadamente de logN en el peor caso. Adems, el algoritmo de insercin en un rbol binario de
bsqueda tiene la ventaja -sobre los arrays ordenados, donde se empleara bsqueda dicotmica
para localizar un elemento- de que no necesita hacer una reubicacin de los elementos de la
estructura para que esta siga ordenada despus de la insercin. Dicho algoritmo funciona avanzando
por el rbol escogiendo la rama izquierda o derecha en funcin de la clave que se inserta y la clave
del nodo actual, hasta encontrar su ubicacin; por ejemplo, insertar la clave 7 en el rbol de la figura 5
requiere avanzar por el rbol hasta llegar a la clave 8, e introducir la nueva clave en el subrbol
izquierdo a 8.
El algoritmo de borrado en rboles es algo ms complejo, pero ms eficiente que el de borrado en un
array ordenado.

Ahora bien, suponer que se tiene un rbol vaco, que admite claves de tipo entero. Suponer que se
van a ir introduciendo las claves de forma ascendente. Ejemplo: 1,2,3,4,5,6
Se crea un rbol cuya raz tiene la clave 1. Se inserta la clave 2 en el subrbol derecho de 1. A
continuacin se inserta la clave 3 en el subrbol derecho de 2.
Continuando las inserciones se ve que el rbol degenera en una lista secuencial, reduciendo
drsticamente su eficacia para localizar un elemento. De todas formas es poco probable que se de un
caso de este tipo en la prctica. Si las claves a introducir llegan de forma ms o menos aleatoria
entonces la implementacin de operaciones sobre un rbol binario de bsqueda que vienen a
continuacin es en general suficiente.

Existen variaciones sobre estos rboles, como los AVL o Red-Black (no se tratan aqu), que sin llegar
a cumplir al 100% el criterio de rbol perfectamente equilibrado, evitan problemas como el de obtener
una lista degenerada.

Operaciones bsicas sobre rboles binarios de bsqueda

- Bsqueda

Si el rbol no es de bsqueda, es necesario emplear uno de los recorridos anteriores sobre el rbol
para localizarlo. El resultado es idntico al de una bsqueda secuencial. Aprovechando las
propiedades del rbol de bsqueda se puede acelerar la localizacin. Simplemente hay que
descender a lo largo del rbol a izquierda o derecha dependiendo del elemento que se busca.

boolean buscar(tarbol *a, int elem)


{
if (a == NULL) return FALSE;
else if (a->clave < elem) return buscar(a->der, elem);

26
else if (a->clave > elem) return buscar(a->izq, elem);
else return TRUE;
}

- Insercin

La insercin tampoco es complicada. Es ms, resulta practicamente idntica a la bsqueda. Cuando


se llega a un rbol vaco se crea el nodo en el puntero que se pasa como parmetro por referencia,
de esta manera los nuevos enlaces mantienen la coherencia. Si el elemento a insertar ya existe
entonces no se hace nada.

void insertar(tarbol **a, int elem)


{
if (*a == NULL) {
*a = (arbol *) malloc(sizeof(arbol));
(*a)->clave = elem;
(*a)->izq = (*a)->der = NULL;
}
else if ((*a)->clave < elem) insertar(&(*a)->der, elem);
else if ((*a)->clave > elem) insertar(&(*a)->izq, elem);
}

- Borrado

La operacin de borrado si resulta ser algo ms complicada. Se recuerda que el rbol debe seguir
siendo de bsqueda tras el borrado. Pueden darse tres casos, una vez encontrado el nodo a borrar:
1) El nodo no tiene descendientes. Simplemente se borra.
2) El nodo tiene al menos un descendiente por una sola rama. Se borra dicho nodo, y su primer
descendiente se asigna como hijo del padre del nodo borrado. Ejemplo: en el rbol de la figura 5 se
borra el nodo cuya clave es -1. El rbol resultante es:

27
3) El nodo tiene al menos un descendiente por cada rama. Al borrar dicho nodo es necesario
mantener la coherencia de los enlaces, adems de seguir manteniendo la estructura como un rbol
binario de bsqueda. La solucin consiste en sustituir la informacin del nodo que se borra por el de
una de las hojas, y borrar a continuacin dicha hoja. Puede ser cualquier hoja? No, debe ser la que
contenga una de estas dos claves:
la mayor de las claves menores al nodo que se borra. Suponer que se quiere borrar el nodo 4 del
rbol de la figura 5. Se sustituir la clave 4 por la clave 2.
la menor de las claves mayores al nodo que se borra. Suponer que se quiere borrar el nodo 4 del
rbol de la figura 5. Se sustituir la clave 4 por la clave 5.

El algoritmo de borrado que se implementa a continuacin realiza la sustitucin por la mayor de las
claves menores, (aunque se puede escoger la otra opcin sin prdida de generalidad). Para lograr
esto es necesario descender primero a la izquierda del nodo que se va a borrar, y despus avanzar
siempre a la derecha hasta encontrar un nodo hoja. A continuacin se muestra grficamente el
proceso de borrar el nodo de clave 4:

Codificacin: el procedimiento sustituir es el que desciende por el rbol cuando se da el caso del nodo
con descencientes por ambas ramas.

28
void borrar(tarbol **a, int elem)
{
void sustituir(tarbol **a, tarbol **aux);
tarbol *aux;

if (*a == NULL) /* no existe la clave */


return;

if ((*a)->clave < elem) borrar(&(*a)->der, elem);


else if ((*a)->clave > elem) borrar(&(*a)->izq, elem);
else if ((*a)->clave == elem) {
aux = *a;
if ((*a)->izq == NULL) *a = (*a)->der;
else if ((*a)->der == NULL) *a = (*a)->izq;
else sustituir(&(*a)->izq, &aux); /* se sustituye por
la mayor de las menores */

free(aux);
}
}

1. CONCEPTOS BASICOS

Hablando intuitivamente, un grafo es un conjunto de nodos unidos por un conjunto de lneas


o flechas. Por lo general, los nodos son entes de procesamiento o estructuras que contienen algn
tipo de informacin y las lneas o flechas son conexiones o relaciones entre estos entes. Si se
utilizan flechas para conectar los nodos decimos que el grafo es dirigido (tambin llamado
digrafo) porque las relaciones entre los nodos tienen una direccin. En caso contrario el
grafo es no dirigido. En cualquiera de los dos casos, bien sea que se utilicen lneas o
flechas, a estas relaciones se les puede llamar simplemente aristas. Frecuentemente las aristas
tambin tienen algn tipo de informacin asociada (distancia, costo, confiabilidad, etc.), en
cuyo caso estamos en presencia de un grafo pesado.

29
Las secuencias de aristas forman caminos o ciclos. Un ciclo es un camino que termina
en el mismo nodo donde comenz. Si el camino recorre todos los nodos del grafo es
llamado tour. El nmero de aristas en un camino es la longitud del camino.

Se dice que un grafo es conexo si se puede llegar desde cualquier nodo hasta cualquier
otro mediante un camino. De lo contrario no es conexo, pero puede dividirse en componentes
conexas, que son subconjuntos de nodos y aristas del grafo original que si son conexos. Un grafo
conexo sin ciclos es llamado un rbol.
Estos son apenas unos cuantos conceptos de lo que se conoce como la Teora de Grafos. El
objetivo de estas notas no es cubrir por completo dicha teora sino enfocarnos en la
implementacin de este tipo de estructuras y las operaciones y algoritmos ms comunes e
importantes que se aplican sobre las mismas.

2. REPRESENTACION EN EL COMPUTADOR

Hay por lo menos dos maneras evidentes de representar un grafo en un computador, utilizando
la notacin pseudoformal propuesta en [2]. La primera utiliza lo que se conoce como una
matriz de adyacencia, a saber:

CLASE Grafo

Privado:

Arreglo de <Tipo> Nodos de [1..N];

Arreglo de logico MatrizDeAdyacencia de [1..N][1..N];


Publico:
# Todas las operaciones aqu
FCLASE

Un valor verdadero en la posicin (i,j) de la matriz indica que hay una arista que
conecta al nodo i con el nodo j. Para representar un grafo pesado se puede cambiar la matriz
de adyacencia de lgicos a una matriz de registros, siendo el peso un campo del registro.

Esta representacin es muy til cuando se cumplen dos condiciones principales.


Primero, si se conoce el nmero exacto de nodos en el grafo no hace falta utilizar
estructuras dinmicas porque las estticas se pueden acceder con mayor facilidad. Segundo,
la matriz de adyacencia no contiene un gran nmero de elementos en FALSO.

30
Si no se cumple la primera de estas condiciones y el nmero de nodos en el grafo puede
variar drsticamente entonces se justifica el uso de estructuras dinmicas. En este caso, lo
ideal es utilizar una lista lineal de nodos conteniendo la informacin en <Tipo>. Por
supuesto, si el nmero de nodos va a cambiar entonces tampoco se justificas tener un
matriz estticas, por lo que debera utilizarse una matriz esparcida.

CLASE Nodo #Nodo de la lista de <Tipo>


Publico:

entero Id;

<Tipo> Info;
Nodo proximo;
#Operaciones aqu
FCLASE

#La declaracin de los nodos para las columnas (NodoC), filas (NodoF) y

#nodos internos de la matriz van aqu. Son las declaraciones de una

#matriz esparcida implementada con listas con posicin lgica fija o

#relativa.

CLASE Grafo

Privado:

Nodo primerNodo; # 1er. nodo de la lista

NodoF primeraFila; # 1era. fila de la matriz esparcida

NodoC primeraColumna; # 1era. columna de la matriz esparcida

Publico:

# Todas las operaciones aqu


FCLASE

Sin embargo, puede que esta solucin no sea la ms conveniente por el hecho de que la
matriz esparcida ocupar ms memoria que su contraparte esttica a medida que el nmero
de conexiones entre los nodos sea mayor, ya que habr pocos elementos no nulos dentro de
la matriz. En ese caso, se debe utilizar otra implementacin.

31
CLASE Nodo #Nodo de la lista de <Tipo>
Publico:

entero Id;

<Tipo> Info;
Nodo proximo;

Ady ListaDeAdyacentes;

#Operaciones aqu
FCLASE

CLASE Ady #Nodo de la lista de nodos adyacentes

Publico:

Nodo AdyAeste;
Ady proximo;

#Operaciones aqu
FCLASE

CLASE Grafo

Privado:

Nodo primerNodo; # 1er. nodo de la lista

Publico:

32
# Todas las operaciones aqu

FCLASE

33
Esta representacin ocupa menos memoria que la anterior sin importar si la matriz
esparcida est muy llena o no, pero puede incrementar la complejidad de algunas
peraciones, como por ejemplo saber cules nodos son adyacentes a un nodo en particular
(en caso de un grafo dirigido).
De nuevo, si las aristas tambin tienen algn tipo de informacin asociada bastara una
leve modificacin en la clase Ady estructura para agregarla.
Por supuesto, se deben implementar las operaciones ms comunes como agregar un nodo
al grafo, eliminar un nodo del grafo y conectar un nodo con otro. En adicin, se puede
implementar todo tipo de operaciones basadas en la teora de grafos, para resolver los
problemas que se describen a continuacin.

3. PROBLEMAS DE PROCESAMIENTO DE GRAFOS

Los algoritmos que se tratan en este texto son fundamentales y son muy tiles en muchas
aplicaciones, pero solamente son una introduccin al tema de algoritmos de grafos. Existe
un gran variedad de problemas relacionados con grafos y una gran variedad de
algoritmos para procesamiento de grafos, pero claramente no todo problema de grafos es
sencillo de resolver y en muchas ocasiones tampoco es sencillo determinar que tan difcil
puede ser resolverlo.
Fciles: Un problema fcil de procesamiento de grafos es aquel que se puede resolver
utilizando un programa eficiente y elegante. Frecuentemente su tiempo de ejecucin es
lineal en el peor caso, o limitado por un polinomio de bajo grado en el nmero de nodos o el
nmero de aristas.
Generalmente, tambin podemos decir que el problema es fcil si podemos desarrollar un
algoritmos de fuerza bruta que aunque sea lento para grandes grafos, es til para grafos
pequeos e inclusive de tamao medio. Entonces, una vez que sabemos que el problema es
fcil, buscamos soluciones eficientes y escogemos la mejor de ellas.
Tratable: Un problema tratable de procesamiento de grafos es aquel para el que se conoce
un algoritmo que garantiza que sus requerimientos en tiempo y espacio estn limitados
por una funcin polinomial en el tamao del grafo (nmero de nodos + nmero de aristas).

Todo problema fcil es tratable, pero se hace la distincin debido a que el desarrollo de
una solucin eficiente para resolverlo es extremadamente difcil o imposible. Las soluciones a
algunos problemas intratables nunca han sido escritas en programas, o tiempo tiempos de
ejecucin tan altos que no puede contemplarse su utilizacin en la prctica.

34
Intratable: Un problema intratable de procesamiento de grafos es aquel para el que no se
conoce algoritmo que garantice obtener una s o l u c i n d e l p r o b l e m a e n u n a
c a n t i d a d r a z o n a b l e d e tiempo. Muchos de estos problemas tienen la
caracterstica de que podemos utilizar un mtodo de fuerza bruta para probar todas las
posibilidades de calcular la solucin, y se consideran intratables porque existen demasiadas
posibilidades a considerar.
Esta clase de problemas es extensa y muchos expertos piensan que no existen algoritmos
eficientes para solucionar estos problemas. El trmino NP-hard describe los
problemas de esta clase, el cual representa un altsimo nivel de dificultad.
Desconocida: Existen problemas de procesamiento de grafos cuya dificultad es desconocida.
No hay un algoritmo eficiente conocido para resolverlos, ni son conocidos como NP-hard. El
problema de isomorfismo de grafos pertenece a esta clase.

Algunos de los problemas ms conocidos de procesamiento de grafos son:

Conectividad Simple: Consiste en estudiar si el grafo es conexo, es decir, si existe al


menos un camino entre cada par de vrtices.

Deteccin de Ciclos: Consiste en estudiar la existencia de al menos un ciclo en el grafo

Camino Simple: Consiste en estudiar la existencia de un camino entre dos vrtices


cualquiera.

Camino de Euler: Consiste en estudiar la existencia de un camino que conecte dos


vrtices dados usando cada arista del grafo exactamente una sola vez. Si el camino tiene como
inicio y final el mismo vrtice, entonces se desea encontrar un tour de Euler.

Camino de Hamilton: Consiste en estudiar la existencia de un camino que conecte dos


vrtices dados que visite cada nodo del grafo exactamente una vez. Si el camino tiene
como inicio y final el mismo vrtice, entonces se desea encontrar un tour de Hamilton.

Conectividad Fuerte en Dgrafos: Consiste en estudiar si hay un camino dirigido conectando


cada par de vrtices del dgrafo. Inclusive se puede estudiar si existe un camino dirigido
entre cada par de vrtices, en ambas direcciones.

35
Clausura Transitiva: Consiste en tratar de encontrar un conjunto de vrtices que pueda ser
alcanzado siguiendo aristas dirigidas desde cada vrtice del dgrafo.

rbol de Expansin Mnima: Consiste en encontrar, en un grafo pesado, el conjunto de


aristas de peso mnimo que conecta a todos los vrtices.

Caminos cortos a partir de un mismo origen: Consiste en encontrar cuales son los caminos
ms cortos conectando a un vrtice v cualquier con cada uno de los otros vrtices de un dgrafo
pesado. Este es un problema que por lo general se presenta en redes de computadores,
representadas como grafos.

Planaridad: Consiste en estudiar si un grafo puede ser dibujado sin que ninguna de las lneas
que representan las aristas se intercepten.

Pareamiento (Matching): Dado un grafo, consiste en encontrar cual es el subconjunto ms


largo de sus aristas con las propiedad de que no haya dos conectados al mismo vrtice. Se sabe
que este problema clsico es resoluble en tiempo proporcional a una funcin polinomial en el
nmero de vrtices y de aristas, pero an no existe un algoritmo rpido que se ajuste a grandes
grafos.

Ciclos Pares en Dgrafos: Consiste en encontrar en un dgrafo un camino de longitud par.


Este problema puede lucir simple ya que la solucin para grafos no dirigidos es sencilla. Sin
embargo, an no se conoce si existe un algoritmo eficiente para resolverlo.

Asignacin: Este problema se conoce tambin como pareamiento bipartito pesado


(bipartite weigthed matching). Consiste en encontrar un pareamiento perfecto de peso mnimo
en un grafo bipartito. Un grafo bipartito es aquel cuyos vrtices se pueden separar en dos
conjuntos, de tal manera que todas las aristas conecten a un vrtice en un conjunto con otro vrtice
en el otro conjunto.

Conectividad General: Consiste en encontrar el nmero mnimo de aristas que al ser


removidas separarn el grafo en dos partes disjuntas (conectividad de aristas). Tambin se
puede encontrar el nmero mnimo de nodos que al ser removidos separarn el grafo en dos
partes disjuntas (conectividad de nodos).

36
El camino ms largo: Consiste en encontrar cual es el camino ms largo que conecte a
dos nodos dados en el grafo. Aunque parece sencillo, este problema es una versin del
problema del tour de Hamilton y es NP-hard.

Colorabilidad: Consiste en estudiar si existe alguna manera de asignar k colores a cada uno
de los vrtices de un grafo, de tal forma de que ninguna arista conecte dos vrtices del
mismo color. Este problema clsico es fcil para k=2 pero es NP-hard para k=3.
Conjunto Independiente: Consiste en encontrar el tamao del mayor subconjunto
de nodos de un grafo con la propiedad de que no haya ningn par conectado por una arista. Este
problema es NP-hard.
Clique: Consiste en encontrar el tamao del clique (subgrafo completo) ms grande en un
grafo dado.
Isomorfismo de grafos: Consiste en estudiar la posibilidad de hacer dos grafos idnticos
con solo renombrar sus nodos. Se conocen algoritmos eficientes para solucionar este
problema, para varios clases particulares de grafos, pero no se tiene solucin para el
problema general. Este problema es NP-hard.

A continuacin estudiaremos algunos algoritmos clsicos de procesamiento de grafos


que resuelven algunos de los problemas anteriores.

4. RECORRIDO DE GRAFOS

Cualquier algoritmo de recorrido de grafos consiste bsicamente en visitar un nodo del


grafo y luego ir visitando los nodos conectados a este. Este principio se aplica
recursivamente comenzando desde un nodo inicial cualquiera del grafo.

Lo que diferencia un algoritmo de recorrido de otro es, una vez ubicado en un nodo en
particular, la forma en que se visitan los nodos conectados a este. Por supuesto, estos algoritmos
pueden ser aplicados en grafos dirigidos o no dirigidos.

Los dos algoritmos clsicos de recorrido de grafos son el recorrido en


profundidad y en anchura. Precisamente por ser clsicos han sido estudiados con
anterioridad y se les conoce su orden de complejidad en tiempo y todos los beneficios de
aplicarlos.

37
Recorrido en profundidad
Para efectuar un recorrido en profundidad de un grafo, se selecciona cualquier nodo como
punto de partida (por lo general el primer nodo del grafo) y se marcan todos los nodos
del grafo como no visitados. El nodo inicial se marca como visitado y si hay un nodo
adyacente a este que no haya sido visitado, se toma este nodo como nuevo punto de partida
del recorrido. El recorrido culmina cuando todos los nodos hayan sido visitados.

Se dice que el recorrido es en profundidad, porque para visitar otro nodo adyacente del
nodo inicial, primero se deben visitar TODOS los nodos adyacentes al que se eligi antes.
Es as, como el nmero de ambientes recursivos vara dependiendo de la profundidad que
alcance el algoritmo.

Agregando el campo logico visitado; en la ltima implementacin de grafos tratada,


podramos implementar el recorrido en profundidad de la siguiente manera:
Privado:

ACCION DFS_R( Nodo Actual)

#se marca el nodo actual como visitado

Actual .visitado verdad;

Ady aux;

aux Actual. ListaDeAdyacentes;

#se recorre la lista de adyacentes al nodo Actual para

#visitarlos

Mientras ( aux NULL ) hacer

si ( (aux .AdyAeste) .visitado verdad) entonces

#se hace la llamada recursiva a los nodos

#adyacentes para visitarlos


DFS_R(aux . AdyAeste);

fsi

38
aux aux .proximo;

fmientras

FACCION

Publico:

ACCION DFS() #Depth-First Search

Nodo aux;

aux primerNodo;

#aqu se recorre la lista de nodos iterativamente

#haciendo las llamadas al DFS_R (DFS recursivo) cada vez que

#se consiga a alguien no visitado. Esto se hace para evitar

#que el algoritmo no funcione si el grafo tiene varias com-

#ponentes conexas

mientras (aux NULL) hacer

si (aux .visitado verdad) entonces

DFS_R(aux);
fsi

aux aux .proximo;

fmientras

FACCION

Este algoritmo recorre todos los nodos del grafo pero fcilmente puede modificarse para
que sea una funcin que encuentre un nodo en particular dentro de grafo. Este algoritmo
se conoce como el algoritmo DFS (Depth-First Search).

39
Una bondad de este algoritmo es que los nodos solo se vistan una vez. Esto implica que si
se salvan en alguna estructura las aristas que se van recorriendo se obtiene un conjunto
de aristas de cubrimiento mnimo del grafo, lo cual se utiliza frecuentemente se utiliza para
reducir la complejidad del grafo cuando la perdida de informacin de algunas aristas no es
importante. Este resultado se conoce como rbol DFS (DFS Tree).

0 2 0 2

6 6
1 7 1 7

3 3

5 4 5 4

El algoritmo de recorrido en profundidad tiene orden O(mx(A,N)) donde N es el nmero de


nodos y A es el nmero de aristas. Esto es porque un grafo de N nodos puede tener ms de
N aristas, en cuyo caso se ejecutan ms de N ciclos en DFS_R, pero si por el contrario hay
menos aristas que nodos, de cualquier manera se visitaran todos los nodos en DFS.

El DFS puede modificarse fcilmente y utilizarse para resolver problemas sencillos como
los de conectividad simple, deteccin de ciclos y camino simple. Por ejemplo, el nmero
de veces que se invoca a la accin DFS_R desde la accin DFS en el algoritmo anterior es
exactamente el nmero de componentes conexas del grafo, lo cual representa la solucin al
problema de conectividad simple.

Recorrido en anchura

En este algoritmo tambin se utiliza la estrategia de marcas los nodos como visitados
para detectar la culminacin del recorrido, pero los nodos se recorren de una manera
ligeramente distinta.

De nuevo, se selecciona cualquier nodo como punto de partida (por lo general el primer
nodo del grafo) y se marcan todos los nodos del grafo como no visitados. El nodo inicial se
marca como visitado y luego se visitan TODOS los nodos adyacentes a este, al finalizar este

40
proceso se busca visitar nodos ms lejanos visitando los nodos adyacentes a los nodos
adyacentes del nodo inicial.
Este algoritmo puede crear menos ambientes recursivos que el anterior porque visita ms
nodos en un mismo ambiente, pero esto depende de cmo este construido el grafo. El algoritmo
se conoce como el algoritmo de BFS (Breadth-First Search).
Este algoritmo tiene exactamente el mismo orden en tiempo de ejecucin del algoritmo de
recorrido en profundidad y tambin se puede obtener el conjunto de aristas de cubrimiento mnimo
del grafo.
Una diferencia notable entre el DFS y el BFS es que este ultimo necesita de una estructura
auxiliar, que por lo general es una cola, para el almacenamiento de las aristas que se van a
visitar durante el recorrido.

El siguiente ejemplo ilustra el funcionamiento del algoritmo BFS sobre un grafo de


ejemplo. La secuencia de ilustraciones va de izquierda a derecha y de arriba hacia abajo.

0 2 0 2 0 2

1 7 1 7 1 7
6 6 6
3 3 3
5 4 5 4 5 4
C: 0 -5 0-7 2-6 C: 0-7 2-6 5-3 5-4
C: 0 -2 0-5 0-7

0 2 0 2 0 2

6 6 6

1 7 1 7 1 7
3 3 3
5 4 5 4 5 4

C: 2 -6 5-3 5-4 7-1 7-4 C: 5-3 5-4 7-1 7-4 6-4 C: 5-4 7-1 7-4 6 -4 3 -4

41
0 2 0 2

6 6
1 7 1 7

3 3

5 4 5 4

C: 7-1 7-4 6-4 3-4

Comenzamos introduciendo a la cola C todas las aristas adyacentes al nodo inicial


(El nodo 0). Luego, extraemos la arista 0-2 de la cola y procesamos las aristas adyacentes a
2, la 0-2 y la 2-6. No colocamos la arista 0-2 en la cola porque el vrtice 0 ya fue visitado.
Luego, extraemos la arista 0-5 de la cola y procesamos las aristas adyacentes a 5. De
manera similar a la anterior, no se toma en cuenta la arista 0-5, pero si se encolan las aristas
5-3 y 5-4. Seguidamente, extraemos la arista 0-7 y encolamos la arista 7-1. La arista 7-4
esta impresa en color gris porque si bien es un enlace adyacente a 7, podramos evitar
encolarla debido a que ya existe una arista en la cola que nos lleva hasta el nodo 4.
Para completar el recorrido, tomamos las aristas que quedan en la cola, ignorando aquellas que
estn impresas en color gris cuando queden de primeras en la cola. Las aristas entran y salen de
la cola en el orden de su distancia del vrtice 0.

Al igual que en el DFS, usando el BFS se puede obtener un conjunto de aristas de


cubrimiento mnimo del grafo, conocido como el rbol (BFS Tree).

0 2 0 2

6 6
1 7 1 7

3 3

5 4 5 4
42
Tambin puede modificarse fcilmente y utilizarse para resolver problemas sencillos
como los de conectividad simple, deteccin de ciclos y camino simple.

El BFS es el algoritmo clsico para encontrar el camino ms corto entre dos nodos especficos en
un grafo, mientras que DFS nos ofrece muy poca ayuda para esta tarea debido a que el
orden en el que se visitan los nodos no tiene absolutamente ninguna relacin con la longitud
de los caminos.

5. CALCULO DEL CAMINO MAS CORTO

Todo camino en un dgrafo pesado tiene un peso asociado, el cual es la suma de los pesos de
las aristas del camino. Esta medida esencial nos permite formular problemas como el de
encontrar el camino con el menor peso entre dos vrtices. El tpico de esta seccin es el
clculo de este tipo de camino, donde la longitud del camino no se mide en base al
nmero de aristas del mismo, sino en base al peso del camino.

Con esto ltimo en mente, definiremos al camino ms corto entre dos nodos de un dgrafo
pesado, como el camino dirigido que tenga la propiedad de tener el peso mnimo entre
todos los caminos que existan entre dicho par de nodos.

Se pueden plantear tres tipos de problemas:

Camino ms corto origen-destino: Dados dos nodos v y w de un grafo,


encontrar el camino ms corto que comience en v y culmine w.

Camino ms corto a partir de un origen: Dado un nodo v de un grafo,


encontrar el camino ms corto desde v hasta cada uno de los dems nodos.

Camino ms corto entre cada par de nodo

43
El primero de estos problemas no es ms que un caso particular del segundo. En lo
que respecta al segundo, por ol general lo que se busca es tratar de obtener un rbol de
caminos ms cortos o el SPT (shortest-path tree), que consiste en un rbol dirigido que
tiene como raz al nodo origen y todo camino en el rbol en un camino corto en el grafo. El tercero
de los problemas se puede resolver obteniendo los SPT correspondientes a cada uno de los
nodos del grafo.

Algoritmo de Dijkstra
El algoritmo de Dijkstra resuelve el problema de encontrar los caminos ms cortos a partir de un
origen, en grafos pesados que no tengan pesos negativos.

El algoritmo de Dijkstra es un algoritmo voraz que opera a partir de un conjunto S de nodos


cuya distancia ms corta desde el origen ya es conocida. En principio, S contiene slo el
nodo origen. En cada paso, se agrega algn nodo v a S, cuya distancia desde el origen
es la ms corta posible. Bajo la hiptesis de que los pesos son no negativos, siempre es
posible encontrar un camino ms corto entre el origen y v que pasa slo a travs de los
nodos de S, al que llamaremos especial. En cada paso del algoritmo, se utiliza un arreglo
D para registrar la longitud del camino especial ms corto a cada nodo. Una vez que S
incluye todos los nodos, todos los caminos son especiales, as que D contendr la
distancia ms corta del origen a cada vrtice. Se puede utilizar un arreglo P, para ir
almacenando los caminos ms cortos.

A continuacin se muestra un esbozo del algoritmo de Dijkstra en lenguaje


pseudoformal :

#Supngase la existencia del siguiente grafo

Conjunto V; # Conj. de nodos del grafo-N nodos

Arreglo C de real [1..N][1..N]; # Matriz de costos de las aristas

#y las siguientes variables auxiliares

entero i,w,v;
Arreglo D de real [1..N]; # arreglo auxiliar de costos
Arreglo P de entero [1..N]; # arreglo que guarda los caminos ms

# cortos

Conjunto S; # Conjunto de nodos evaluados

# Inicializado con el conjunto vaco

44
#el esbozo del algoritmo de Dijkstra

S.Agregar(1); # tomando el nodo 1 como nodo origen

Para i 2 hasta N hacer

D[i] C[1][i]; # asignando valores iniciales a D


Fpara

Para i 1 hasta N-1 hacer

w nodo en V-S tal que D[w] sea un mnimo

S.Agregar(w);

Para cada nodo v V-S hacer

45
D[v] min (D[v], D[w]+C[w,v]);

Fpara
P[v] w;

Fpara

Al final de la ejecucin, cada posicin del arreglo P contiene el nodo inmediato


anterior a v en el camino ms corto a partir del nodo inicial. Dado el grafo:

10 100

30

2
5

50 10

60
3

20
4

46
Al final de la ejecucin el arreglo P debe tener los valores P[2]=1, P[3]=4 , P[4]=1 y P[5]=3.
Para encontrar el camino ms corto del nodo 1 al nodo 5, por ejemplo, se siguen los
predecesores en orden inverso comenzando en 5. As, es sencillo encontrar que el camino
ms corto del nodo 1 al 5, es el 1, 4, 3, 5.

Usando el arreglo P, o bien mediante alguna otra heurstica, se puede construir fcilmente
un SPT, tomando el nodo inicial del recorrido como raz del rbol y luego aadiendo una
arista y un nodo a la vez, siempre tomando la prxima arista que pertenezca al camino ms
corto a un nodo que no est en el SPT.

El orden en tiempo de ejecucin del algoritmo de Dijkstra depende muchsimo de las


caractersticas del grafo y de cmo este almacenado. Si se emplea una matriz de
adyacencia como en el cdigo anterior, entonces el ciclo ms interno es de O(N) y como se
ejecuta N-1 veces, tendramos un algoritmo de O(N 2 ). Si por el contrario se utiliza una
representacin dinmica, justificada en el hecho de que el nmero de aristas es mucho
menor a N2 , se podra emplear un rbol parcialmente ordenado para organizar los nodos
V-S, y por lo tanto se reducira la complejidad del ciclo ms interno un orden logartmico.

Aunque se puede ejecutar Dijkstra N veces para resolver el problemas de caminos cortos
entre cada par de nodos, el Algoritmo de Floyd [5] tambin resuelve este problema, con una
complejidad en tiempo similar.

6. ARBOL DE EXPANSION MINIMA

Anteriormente, tratamos el problema de encontrar la ruta ms corta entre dos nodos en un


digrafo pesado, pero si el grafo no es dirigido y lo que se desea es encontrar la manera
menos costosa de conectar todos los puntos, entonces nos enfrentamos al problema de
encontrar un rbol de expansin mnima (MST Minimum Spanning Tree). Un rbol de
expansin de un grafo conexo es un subgrafo que contiene todos los nodos del grafo y
no tiene ciclos. El rbol de expansin mnima de un grafo pesado no dirigido es el rbol
de expansin cuyo peso (la suma de los pesos de todas sus aristas) no es mayor al de ningn
otro rbol de expansin.

El problema de encontrar el MST de un grafo pesado no dirigido arbitrario tiene una gran
cantidad de aplicaciones importantes y se conocen algoritmos para encontrarlo al menos

47
desde 1920, pero la eficiencia de las implementaciones vara ampliamente y los investigadores
an buscan mejores mtodos. En esta seccin se examinan dos algoritmos clsicos para
resolver este problema.

Algoritmo de Prim

El algoritmo de Prim es tal vez el algoritmo de MST ms sencillo de implementar y el


mejor mtodo para grafos densos. Este algoritmo puede encontrar el MST de cualquier
grafo conexo pesado.

Sea V el conjunto de nodos de un grafo pesado no dirigido. El algoritmo de Prim


comienza cuando se asigna a un conjunto U de nodos un nodo inicial perteneciente a V, en
el cual crece un rbol de expansin, arista por arista. En cada paso se localiza la arista
ms corta (u,v) que conecta a U con V-U, y despus se agrega v, el vrtice en V-U, a U. Este
paso se repite hasta que V=U. El algoritmo de Prim es de O(N2 ), donde | V | = N.

El siguiente ejemplo ilustra el funcionamiento del algoritmo. La secuencia de


ilustraciones va de izquierda a derecha y de arriba hacia abajo. La primera imagen muestra
el grafo pesado y las siguientes muestran el funcionamiento del algoritmo de Prim y como
va cambiando el conjunto U durante la ejecucin.

U U

0 5 0 0

1 3 3 1 3
5

1 2 1 1

4
2 2 2

0 U 0

1 3 1 3

1 1 2

48
4 4
2 2

Agregar un nodo al MST es un cambio incremental, para implementar el algoritmo de


Prim debemos enfocarnos en la naturaleza de ese cambio incremental. La clave est en
notar que nuestro inters esta en la distancia ms corta de cada vrtice de U a V-U. Al
agregar un nodo v al rbol, el nico cambio posible para cada vrtice w fuera del rbol es
que agregar v coloca a w ms cerca del rbol. Esto es, no es necesario verificar la distancia
de w a todos los dems nodos del rbol, solo se necesita verificar si la adicin de v al rbol
necesita actualizar dicho mnimo. Esto se puede lograr agregando una estructura de datos
simple para evitar repetir clculos excesivos, y hacer que el algoritmo sea ms rpido y ms
simple.

El siguiente ejemplo ilustra la metodologa anterior, utilizando una pila de aristas P,


en donde las aristas se van apilando en menor a mayor segn el peso de la misma. La
secuencia de ilustraciones va de izquierda a derecha.

0 5 0 5 0 5 0 5

1 3 1 3 1 3 1 3
5 5 5 5

1 2 1 2 1 2 1 2

4 4 4 4
2 2 2 2

P: 0-3 0-1 P: 0-3 1-2 P: 2-3 P:

49
Se comienza en el nodo 0 y se apilan las aristas adyacentes a este nodo, en
orden decreciente. La arista mnima es la que esta en el tope de la pila, as que se
desapila y se agrega al MST. Seguidamente se procede con el nodo 1 y se apilan sus
aristas adyacentes, con la diferencia de que hay que verificar si dichas aristas
representan un nuevo camino mnimo con respecto a las aristas que ya estn
introducidas en la pila. En este caso no se apila la arista 1-3 porque ya hay una arista
que lleve a 3 con el mismo costo en la pila. Se toma 1-2 porque esta en el tope y se
procede con el nodo 2. Cuando se va a apilar la arista
2-3, se encuentra que ya hay un camino que lleve a 3 pero de mayor costo, as que
se desapila 0-3 y luego se apila 2-3. Se agrega 2-3 al MST y termina el proceso, porque el
conjunto de nodos en el MST es igual al conjunto de vrtices del grafo original.

Algoritmo de Kruskal

El algoritmo de Prim construye un MST una arista a la vez, encontrando una nueva arista
que agregar a un MST que va creciendo en cada paso. El algoritmo de Kruskal
tambin construye el MST una arista a la vez, con la diferencia que este encuentra una
arista que conecte dos MST que van creciendo dentro de un bosque de MST
crecientes, formado de los nodos del grafo original.

El algoritmo comienza a partir de un conjunto de rboles degenerados formados por un


solo nodo, que son los nodos del grafo, y se comienzan a combinar los rboles de dos en
dos usando la arista menos costosa posible, hasta que solo quede un solo rbol: El MST.

Dada una lista de las aristas del grafo, el primer paso del algoritmo de Kruskal es ordenarlas
por peso (usando un quicksort por ejemplo). Luego se van procesando las aristas en el
orden de su peso, agregando aristas que no produzcan ciclos en el MST. El algoritmo de
Kruskal es de O(A*log2 A), donde A es el nmero de aristas del grafo. El siguiente ejemplo
ilustra el funcionamiento del algoritmo. La secuencia de ilustraciones va de izquierda a
derecha y de arriba hacia abajo.

50
0 0 0 0

3 1 3 1 3 1 3

1 1 1 2 1 2

4
2 2 2 2

ALGORITMOS DE ORDENACIN
Dado un conjunto de n elementos a1, a2,..., an y una relacin de orden total () sobre ellos, el
problema de la ordenacin consiste en encontrar una permutacin de esos elementos ordenada
de forma creciente.

Aunque tanto el tipo y tamao de los elementos como el dispositivo en donde se encuentran
almacenados pueden influir en el mtodo que utilicemos para ordenarlos, en este tema vamos a
solucionar el caso en que los elementos son nmeros enteros y se encuentran almacenados en un
vector.

Si bien existen distintos criterios para clasificar a los algoritmos de ordenacin, una posibilidad es
atendiendo a su eficiencia. De esta forma, en funcin de la complejidad que presentan en el caso
medio, podemos establecer la siguiente clasificacin:

O (n2): Burbuja, Insercin, Seleccin.


O (nlogn): Mezcla, Montculos, Quicksort.
Otros: Incrementos O (n1.25), Cubetas O (n), Residuos O (n).

A continuacin explicaremos los diferentes algoritmos de ordenacin:

ORDENACIN POR INSERCIN


El mtodo de Insercin realiza n1 iteraciones sobre el vector, dejando en la i-sima etapa (2 i
n) ordenado el subvector a [1..i]. La forma de hacerlo es colocando en cada iteracin el elemento

51
a[i] en su sitio correcto, aprovechando el hecho de que el subvector a [1..i1] ya ha sido
previamente ordenado. Este mtodo puede ser implementado de forma iterativa como sigue:

(Tecnicas de diseo de algoritmos)

Este mtodo se muestra muy adecuado para aquellas situaciones en donde necesitamos ordenar
un vector del que ya conocemos que est casi ordenado, como suele suceder en aquellas
aplicaciones de insercin de elementos en bancos de datos previamente ordenados cuya
ordenacin total se realiza peridicamente.

El mtodo de ordenacin por insercin es similar al proceso tpico de ordenar tarjetas de nombres
(cartas de una baraja) por orden alfabtico, que consiste en insertar un nombre en su posicin
correcta dentro de una lista o archivo que ya est ordenado. As el proceso en el caso de la lista de
enteros A = 50, 20, 40, 80, 30.

(novella.mhhe, n.d.)

ORDENACIN POR SELECCIN

En cada paso (i=1...n1) este mtodo busca el mnimo elemento del subvector a[i..n] y lo
intercambia con el elemento en la posicin i:

52
(Tecnicas de diseo de algoritmos)

Este mtodo, por el nmero de operaciones de comparacin e intercambio que realiza, es el ms


adecuado para ordenar pocos registros de gran tamao. Si el tipo base del vector a ordenar no es
entero, sino un tipo ms complejo (guas telefnicas, ndices de libros, historiales hospitalarios,
etc.) deberemos darle mayor importancia al intercambio de valores que a la comparacin entre
ellos en la valoracin del algoritmo por el coste que suponen. En este sentido, analizando el
nmero de intercambios que realiza el mtodo de Seleccin vemos que es de orden O (n), frente
al orden O (n^2) de intercambios que presentan los mtodos de Insercin o Burbuja.

Un ejemplo prctico ayudar a la comprensin del algoritmo. Consideremos un array A con 5


valores enteros 51, 21, 39, 80, 36:

(novella.mhhe, n.d.)

ORDENACIN BURBUJA

53
Este mtodo de ordenacin consiste en recorrer los elementos siempre en la misma direccin,
intercambiando elementos adyacentes si fuera necesario:

(Tecnicas de diseo de algoritmos)

Este algoritmo funciona de forma parecida al de Seleccin, pero haciendo ms trabajo para llevar
cada elemento a su posicin. De hecho es el peor de los tres vistos hasta ahora, no slo en cuanto
al tiempo de ejecucin, sino tambin respecto al nmero de comparaciones y de intercambios que
realiza.
Una posible mejora que puede admitir este algoritmo es el control de la existencia de una pasada
sin intercambios; en ese momento el vector estar ordenado.

El ejemplo siguiente ilustra el funcionamiento del algoritmo de la burbuja con un array de 5


elementos (A = 50, 20, 40, 80, 30), donde se introduce una variable interruptor para detectar si se
ha producido intercambio en la pasada.

54
(novella.mhhe, n.d.)

55
ORDENACIN POR MECLA (MERGESORT)

Este mtodo utiliza la tcnica de Divide y Vencers para realizar la ordenacin del vector a. Su
estrategia consiste en dividir el vector en dos subvectores, ordenarlos mediante llamadas
recursivas, y finalmente combinar los dos subvectores ya ordenados. Esta idea da lugar a la
siguiente implementacin:

(Tecnicas de diseo de algoritmos)

El mtodo de ordenacin por Mezcla se adapta muy bien a distintas circunstancias, por lo que es
comnmente utilizado no slo para la ordenacin de vectores. Por ejemplo, el mtodo puede ser
tambin implementado de forma que el acceso a los datos se realice de forma secuencial, por lo
que hay diversas estructuras (como las listas enlazadas) para las que es especialmente apropiado.
Tambin se utiliza para realizar ordenacin externa, en donde el vector a ordenar reside en
dispositivos externos de acceso secuencial (i.e. ficheros).

(Hernndez, n.d.)

56
ORDENACIN RPIDA DE HOARE (QUICKSORT)

Este mtodo es probablemente el algoritmo de ordenacin ms utilizado, pues es muy fcil de


implementar, trabaja bien en casi todas las situaciones y consume en general menos recursos
(memoria y tiempo) que otros mtodos.
Su diseo est basado en la tcnica de Divide y Vencers, que estudiaremos en el siguiente
captulo, y consta de dos partes:

a) En primer lugar el vector a ordenar a[prim..ult] es dividido en dos subvectores no vacos


a[prim..l1] y a[l+1..ult], tal que todos los elementos del primero son menores que los del
segundo. El elemento de ndice l se denomina pivote y se calcula como parte del
procedimiento de particin.
b) A continuacin, los dos subvectores son ordenados mediante llamadas recursivas a
Quicksort. Como los subvectores se ordenan sobre ellos mismos, no es necesario realizar
ninguna operacin de combinacin.
Esto da lugar al siguiente procedimiento, que constituye la versin clsica del algoritmo de
ordenacin rpida de Hoare:

(Tecnicas de diseo de algoritmos)


Se ordena una lista de nmeros enteros aplicando el algoritmo quicksort, como pivote se elige el
primer elemento de la lista.

57
(novella.mhhe, n.d.)

El algoritmo quicksort requiere una estrategia de particin y la seleccin idnea del pivote. Las
etapas fundamentales del algoritmo dependen del pivote elegido aunque la estrategia de particin
suele ser similar.

ALGORITMOS DE BSQUEDA
Bsqueda:
Es un proceso para encontrar un elemento objetivo especfico dentro de un grupo de
elementos.
Comprobar que el elemento objetivo no existe dentro del grupo.
El equipo de elementos en el que se est buscando conjunto de bsqueda.

Internos: Almacena en la memoria principal:

58
Esttica, Dinmica.

Segn donde se estn ubicando los datos Externos: Almacena en la memoria secundaria:

Discos, Hash.

Bsqueda Interna:
Lineal o secuencial, Binaria, Indirecta.
Por transformaciones de clave o funciones Hash.

Bsqueda lineal o secuencial


Comienza desde el principio de la lista y compara por turno cada valor por elemento
especificado.
Eventualmente se encuentra el elemento especificado o se llegue hasta el final de la lista.
Condicin que el elemento especificado este en la lista.

Explorar todo el conjunto de bsqueda de forma lineal.

Inicio Fin

1 . . . . . . . .

Bsqueda Binaria
Se da si el conjunto de elementos de la bsqueda esta ordenado, entonces la tcnica tiene ms
eficiencia que la anterior.

Este tipo de algoritmos elimina partes del conjunto de bsqueda en cada componente,
aprovechando que el conjunto de bsqueda est ordenado.

Comienza en el centro de la lista ordenada.


Si el elemento buscado no se encuentra en esa posicin, se deber continuar con la
bsqueda, en uno de los lados de la matriz.
Depende si el elemento objetivo es mayor que el elemento central.
Cuando la lista esta ordenada, se elimina la mitad del conjunto de bsqueda. La mitad
restante del conjunto de bsqueda, conjunto de candidatos viables, en los que an se
pueden encontrar el elemento objetivo.

59
La bsqueda continua de esta misma forma, determinando el elemento central del
conjunto de candidatos objetivos y eliminando la mitad del resto.

(Rosita Wachenchauzer, n.d.)

BUSQUEDA MEDIANTE HASHING


FUNCIONES HASH
Almacenamiento Hash
Tener en cuenta el orden (Ubicacin de un elemento dentro de una coleccin) que est
determinada por una funcin del valor del elemento a almacenar o por alguna funcin de un valor
clave del elemento que hay que almacenar.

Con las funciones Hash los elementos se almacenan en una tabla de Hash, estando su ubicacin
dentro de la tabla determinada por la funcin Hash, donde cada ubicacin de la tabla se
denominara celda o franja.

Suponga que se quiere crear o almacenar una matriz que albergue 26 elementos:
Nombre --> CREAR FUNCION HASH que asigne a cada nombre una posicin dentro de la matriz que
estar asociada con la primera letra del nombre.

60
Ejemplo: La letra A se asignara a la posicin 0, la letra D se asignara a la posicin 3 de esa matriz, y
as sucesivamente.

0 Ana
1 Brian
2 Carlos
3 David
4 Erika
5 Fabricio
6 Gabriela
7 Helena
.
.
.
. Maritza
.
.
.
. Tomas
.
. Walter
31 Yolanda

1. Este tipo de almacenamiento hace K al tiempo de acceso a un elemento en concreto sea


este independiente al nmero de elementos contenidos en la tabla.
2. Todas las operaciones realizadas sobre un elemento de una tabla Hash tienen O(1), ya que
no hace falta que se hagan comparaciones para encontrar un elemento concreto o para
averiguar la posicin apropiada para un cierto elemento.
3. Con el almacenamiento Hash simplemente se calcula dnde debe encontrarse cada
elemento.
4. No obstante esta suficiencia solo puede conseguirse completamente si a cada elemento se
le asigna una posicin distinta dentro de la tabla.

COLISIONES
Funcin Hash Perfecta
Es una funcin Hash que asigne a cada elemento a una posicin nica de la tabla.
Una funcin Hash que se limita a distribuir adecuadamente los elementos entre las
distintas posiciones de la tabla, tambin proporcionara los resultados.

Como hacer Re direccionamiento?

61
Una posibilidad es usar los mtodos que se utilizan con las matrices y a continuacin
expandir la tabla cuando se llene. No obstante debe considerarse que una caracterstica
inherente a las tablas Hash es que si rendimiento se degrada significativamente a medida
que se llena. Por lo tanto, la mejor estrategia es hacer uso de un factor de carga.

Factor De Carga (Fc)


El factor de carga de una tabla Hash es el porcentaje de ocupacin de la tabla para la cual
deber procederse a redimensionar.

EJEMPLO:
Si el factor de carga fuera 0.50 la tabla se redimensionara cada vez que alcance el 50%
de ocupacin.

FUNCIONES HASH
El objetivo es encontrar una funcin que permita distribuir de forma razonable (buena) los
elementos dentro de la tabla de forma que se eviten las colisiones.

Una funcin Hash razonablemente segura procurando en tiempo de acceso constante (0, 1) al
conjunto de datos.

Para ello existen tcnicas para desarrollar una funcin Hash para un conjunto de datos concretos.

Utilizar nicamente una parte de la clave o del valor de elemento con el fin de calcular la
ubicacin en donde se debe almacenar el elemento.
Extraccin: Implica en utilizar nuevamente una parte del valor o de la clave del elemento
con el fin de calcular la ubicacin en la que se almacenar.

MTODO DE DIVISIN
Este mtodo consiste en tomar el resto de la divisin por m, el nmero de entradas de la tabla, asi
h (k) = ( k mod m).

Usar m = una potencia de 2, no es buena idea, ya que el valor de hash queda dependiendo de slo
los bits menos significativos de k.

Una forma de hacer hash (k) dependiente de todos los bits menos significativos es usar nmero
primos no muy cercanos a una potencia de dos.

Este mtodo opera en dos pasos. Primero, multiplicamos la clave por una constante A en el rango
0 < A < 1 y extraemos la parte fraccionaria de k*A. Segundo, Multiplicamos este valor por el
nmero de entradas de la tabla y tomamos el piso del (o truncamos el) resultado.

COLISIONES
Prueba lineal

62
Prueba cuadrtica
Doble direccionamiento

PRUEBA LINEAL

Consiste en que una vez que se detecta la colisin se recorre el arreglo secuencialmente a partir
de una colisin, buscando al elemento. El proceso de bsqueda concluye cuando el elemento es
hallado, o cuando se encuentra una posicin vaca. El arreglo se trata como una estructura
circular.

PRUEBA CUADRATICA

Similar a la anterior se diferencia porque las direcciones en esta se obtienen con la frmula:

D+1, D+4, D+9,,D+i^2

Permite una mejor distribucin de las claves que colisionan aunque tiene como desventaja que
pueden quedar casillas o celdas sin visitar.

Suponga que tiene V con 10 elementos compuestos por:

25, 43, 56, 35, 54, 13, 80, 104, 55 y que son asignados segn la siguiente funcin hash.

h (k) = (k<10) (k mod 10)+1.

D i Dx 1 80 K h(k)
2 55 25 6
1 7
3 43 4
6 2 10
4 43 56 7
5 54 35 9
6 25 54 5
7 56 13 4
8 13 104 5
9 104 55 6
10 35

Al aplicar la funcin Hash a la 35, se obtiene la direccin D=6 pero de esta posicin no est el valor
buscado, entonces se calcula Dx en la posicin como la suma D + (1*J), obtenindose la direccin
7, en donde la bsqueda termine cuando se encuentre el valor deseado, en este caso en la
posicin 10

DOBLE DIRECCIONAMIENTO

Es un mtodo que consiste en que una vez que se detecta la colisin, se genera otra direccin
aplicando la misma funcin Hash a la direccin previamente obtenida.

El proceso termina cuando se encuentra el elemento o cuando se encuentra una posicin.

63
D J Dx
D(H(O)) 6 1 7
D'(H(O)) 2 10
D''(H(O)) 3 15
0 1
2

La funcin Hash que se aplica no necesariamente tiene que ser la misma que se utiliz
originalmente, si no que una vez detectada la colisin se debe generar otra colisin.

Por lo tanto, se puede deducir que no existe una regla que permita decidir cul es la mejor funcin
utilizada en el clculo de una sucesin de direcciones.

25, 43, 56, 35, 54, 13, 80, 104 h (k) = (k mod 10)+1.

La funcin H para calcular las direcciones alternativas en caso de haber colisin.

1
2
3
4 41
5 54
6 25
7 56
8 35
9 104
10 13

Arreglos anidados
Este mtodo consiste en que cada elemento del arreglo tenga otro arreglo, en el cual se
almacenan los elementos que colisionan. Este mtodo resulta ser ineficiente ya que al trabajar con
arreglos se depende del espacio que se haya asignado a los mismos, lo cual resulta un nuevo
problema, este problema es saber el tamao de la segunda estructura que controla la segunda
dimensin.

Encadenamiento
Consiste en que cada posicin de la estructura contenga una lista ligada, la cual crecer con cada
elemento que entre en la estructura, sobre todo con los elementos que generen una colisin. Este
es el mtodo ms eficiente debido a que las listas ligadas son dinmicas y evitan tener tantos
lugares libres como el mtodo arreglos anidados. Como desventaja se puede encontrar que
cuando la lista ligada crece demasiado se pierde la facilidad de acceso directo del mtodo hash.

64
Algoritmos para encontrar coincidencia de patrones

El reconocimiento de patrones puede dividirse en dos reas principales: decisin terica y


estructural. La primera categora trata con la descripcin de patrones usando descriptores
cuantitativos, tales como la longitud, el rea, la textura y muchos otros descriptores. La segunda
categora trata con patrones mejor presentados por smbolos de informacin, tales como strings, y
descritos por las propiedades y relaciones entre estos smbolos. El tema central del
reconocimiento es el concepto de aprendizaje (Learning) a partir de patrones muestra.
Uno de los principales problemas que se aborda en este contexto es la bsqueda de patrones en
un texto. La aplicacin principal es la bsqueda de palabra en un fichero de texto o las bsquedas
relacionados con la biologa computacional, en donde se requiere buscar patrones dentro de una
secuencia de ADN, la cual puede ser modelada como una secuencia de caracteres.
Los algoritmos de coincidencia de cadenas son componentes bsicos utilizados en las
implementaciones prcticas de software existentes en la mayora de sistemas operativos. Por otra
parte, destacan los mtodos de programacin que sirven como paradigmas en otros campos de la
ciencia de la computacin (sistema o diseo de software). Tambin juegan un papel importante en
la informtica terica.
Aunque los datos se memorizan en diversas formas, el texto sigue siendo la forma principal para
intercambiar informacin. Esto es particularmente evidente en la literatura o la lingstica donde
los datos se componen de enorme corpus y diccionarios. Es aplicable donde se necesite almacena
una gran cantidad de datos en archivos lineales.
As, si se quisiera encontrar la ocurrencia de un patrn dentro de un determinado texto,
tendramos que conocer el tamao o longitud del texto donde se quiere buscar y el tamao o
longitud del patrn a buscar.
Suponiendo que n representa la longitud de la cadena de texto y m la longitud del patrn,
tendramos:
n representara el texto donde se quiere buscar, es decir texto = a1, a2, a3,an
m, la longitud del patrn a buscar, es decir patrn = b1, b2, b3,bn

Ejemplo:
En el texto = "anlisis de algoritmos", n=22
y el patrn a buscar: patrn = "algo", m= 4

Algoritmo de Fuerza Bruta


Los algoritmos de fuerza bruta son un enfoque de solucin, usualmente basado en el enunciado
del problema y las definiciones de conceptos involucrados. Los algoritmos de fuerza bruta
resuelven problemas tales como:
a. Calcular an(a > 0, n Z+)
b. Calcular n!
c. Multiplicar dos matrices
d. Buscar un valor dentro de una lista
e. Etc.

Fortalezas y debilidades
Fortalezas
Amplia aplicabilidad
Simplicidad

65
Lleva a disear algoritmos que permiten resolver razonablemente algunos problemas
importantes (e.g., multiplicacin de matrices, ordenamiento, bsqueda de subcadenas,
etc.)
Pueden ser punto de referencia para desarrollar algoritmos ms efectivos

Debilidades
Raramente llevan a desarrollar algoritmos altamente eficientes
Algunos algoritmos de fuerza bruta son extremadamente lentos.

El algoritmo Knuth-Morris-Pratt (KMP)

Suponga que se est comparando el patrn y el texto en una posicin dada, cuando se encuentra
una discrepancia.

Sea X la parte del patrn que calza con el texto, e Y la correspondiente parte del texto, y suponga
que el largo de X es j. El algoritmo de fuerza bruta mueve el patrn una posicin hacia la derecha,
sin embargo, esto puede ser o no lo correcto en el sentido que los primeros j-1 caracteres de X
pueden o no pueden calzar los ltimos j-1 caracteres de Y.
La observacin clave que realiza el algoritmo Knuth-Morris-Pratt(en adelante KMP) es que X es
igual a Y, por lo que la pregunta planteada en el prrafo anterior puede ser respondida mirando
solamente el patrn de bsqueda, lo cual permite pre calcular la respuesta y almacenarla en una
tabla.
Por lo tanto, si deslizar el patrn en una posicin no funciona, se puede intentar deslizarlo en 2, 3,
..., hasta j posiciones.
Se define la funcin de fracaso (failurefunction) del patrn como:

()=max(<|1==+1

66
Intuitivamente, f(j) es el largo del mayor prefijo de X que adems es sufijo de X. note que j = 1 es
un caso especial, puesto que si hay una discrepancia en b1 el patrn se desliza en una posicin.
Si se detecta una discrepancia entre el patrn y el texto cuando se trata de calzar bj+1, se desliza
el patrn de manera que bf(j) se encuentre donde bj se encontraba, y se intenta calzar
nuevamente.

Suponiendo que se tiene f(j) precalculado, la implementacin del algoritmo KMP es la siguiente:

// n = largo del texto


// m = largo del patron
// Los indices comienzan desde 1
int k=0;
int j=0;
while (k<n && j<m)
{
while (j>0 &&texto[k+1]!=patron[j+1])
{
j=f[j];
}
if (texto[k+1])==patron[j+1]))
{
j++;
}
k++;
}
// j==m => calce, j el patron estaba en el texto

Algoritmo Boyer-Moore
Hasta el momento, los algoritmos de bsqueda en texto siempre comparan el patrn con el texto
de izquierda a derecha. Sin embargo, suponga que la comparacin ahora se realiza de derecha a
izquierda: si hay una discrepancia en el ltimo carcter del patrn y el carcter del texto no
aparece en todo el patrn, entonces ste se puede deslizar m posiciones sin realizar ninguna
comparacin extra. En particular, no fue necesario comparar los primeros m-1 caracteres del
texto, lo cual indica que podra realizarse una bsqueda en el texto con menos de n
comparaciones; sin embargo, si el carcter discrepante del texto se encuentra dentro del patrn,
ste podra desplazarse en un nmero menor de espacios.

67
El mtodo descrito es la base del algoritmo Boyer-Moore, del cual se estudiarn dos variantes:
Horspool y Sunday.

Boyer-Moore-Horspool (BMH)

El algoritmo BMH compara el patrn con el texto de derecha a izquierda, y se detiene cuando se
encuentra una discrepancia con el texto. Cuando esto sucede, se desliza el patrn de manera que
la letra del texto que estaba alineada con bm, denominada c, ahora se alinee con algn bj, con j<m,
si dicho calce es posible, o con b0, un carcter ficticio a la izquierda de b1, en caso contrario (este
es el mejor caso del algoritmo).
Para determinar el desplazamiento del patrn se define la funcin siguiente como:
0 si c no pertenece a los primeros m-1 caracteres del patrn (Por qu no se considera el
carcter bm?).
jsi c pertenece al patrn, donde j<m corresponde al mayor ndice tal que bj==c.

Esta funcin slo depende del patrn y se puede precalcular antes de realizar la bsqueda

Cdigo fuente del algoritmo de bsqueda:


// m es el largo del patron
// losindices comienzan desde 1
int k=m;
int j=m;
while(k<=n && j>=1)
{
if (texto[k-(m-j)]==patron[j])
{
j--;
}
else
{
k=k+(m-siguiente(a[k]));
j=m;
}
}
// j==0 => calce!, j>=0 => no hubo calce.
Ejemplo de uso del algoritmo BMH:

Se puede demostrar que el tiempo promedio que toma el algoritmo BMH es:

68
dondec es el tamao del alfabeto (c<<n). Para un alfabeto razonablemente grande, el algoritmo
es: ().
En el peor caso, BMH tiene el mismo tiempo de ejecucin que el algoritmo de fuerza bruta

Boyer-Moore-Sunday (BMS)
El algoritmo BMH desliza el patrn basado en el smbolo del texto que corresponde a la posicin
del ltimo carcter del patrn. Este siempre se desliza al menos una posicin si se encuentra una
discrepancia con el texto.
Es fcil ver que si se utiliza el carcter una posicin ms adelante en el texto como entrada de la
funcin siguiente el algoritmo tambin funciona, pero en este caso es necesario considerar el
patrn completo al momento de calcular los valores de la funcin siguiente. Esta variante del
algoritmo es conocida como Boyer-Moore-Sunday (BMS).
Es posible generalizar el argumento, es decir, se pueden utilizar caracteres ms adelante en el
texto como entrada de la funcin siguiente? La respuesta es no, dado que en ese caso puede
ocurrir que se salte un calce en el texto.

CONCLUSIONES:
El mtodo de bsqueda secuencial compara cada elemento del arreglo con el valor a
encontrar hasta que se consiga o hasta leer todo el arreglo.
La bsqueda secuencial examina el vector desde el primer elemento hasta llegar al ltimo.
El ordenamiento por burbuja consiste en llevar los elementos menores a la izquierda o a
los mayores a la derecha del conjunto de elementos en el arreglo.
El mtodo de la burbuja es la tcnica ms usada por su comprensin fcil, aunque en la
programacin este consume mucho tiempo de computadora.
El mtodo de bsqueda binaria se encarga de examinar primero el elemento central de la
lista, si este es el elemento buscado entonces la bsqueda termino.
La bsqueda binaria se utiliza en vectores ya ordenados.
El rendimiento del mtodo de ordenamiento quicksort depende de la buena eleccin de
un pivote, esto permite que este sea ms ptimo que el mtodo de ordenamiento
mergesort.
Las colisiones se producen cuando, despus de implementar una funcin hash en dos entradas
distintas, se produce una misma salida, por lo tanto se obtienen dos datos en una misma
salida.
La eleccin de un mtodo adecuado para resolver estas colisiones es tan importante como
elegir correctamente la funcin hash.
Hay tres mtodos importantes que son, Resignacin, Arreglos anidados, Encadenamiento
El mtodo de arreglos anidados, es un mtodo que presenta dificultades y no es muy
aconsejable utilizar por su gran costo en cuanto a memoria, ya que se desperdician
demasiados espacios.

69
Bibliografa
[1] Aho, Alfred V.; Hopcroft, Jhon E. ; Ullman, Jeffrey D. Data Estructures and
Algorithms. Addison-Wesley. Massachusetts, EUA. 1983.
[2] Coto, Ernesto. Lenguaje Pseudoformal para la Construccin de Algoritmos. ND 2002-
08. Laboratorio de Computacin Grfica. Universidad Central de Venezuela. Caracas,
Venezuela. Octubre, 2002.
[3] Chvtal, V. Linear Programming. W.H. Freeman and Co., New York, NY, 1983.
[4] Ford Jr., L. R. ; Fulkerson, D. R. Flows in Networks. Princeton University Press,
Princeton, NJ, 1962.
[5] Sedgewick, Robert. Algorithms in C++, Third Edition, Part 5: Graph Algorithms.
Addison-Wesley. 2002.
Hernndez, E. G. (s.f.). punto com no es un lenguaje. Obtenido de Tutorial Java. Aprende a
programar con Java desde cero.:
http://puntocomnoesunlenguaje.blogspot.com/2014/10/java-mergesort.html

novella.mhhe. (s.f.). Obtenido de Algoritmos y estructuras de datos CAP 6 Algortimos de


ordenacion y busqueda:
http://novella.mhhe.com/sites/dl/free/844814077x/619434/A06.pdf

Rosita Wachenchauzer, M. M. (s.f.). librosweb. Obtenido de


https://librosweb.es/libro/algoritmos_python/capitulo_8/busqueda_binaria.html

Tecnicas de diseo de algoritmos. (s.f.).

70

También podría gustarte