Está en la página 1de 103

Algoritmos

Para la carera de Ingeniera Matemtica

PDF generado usando el kit de herramientas de fuente abierta mwlib. Ver http://code.pediapress.com/ para mayor informacin. PDF generated at: Mon, 06 Jan 2014 22:21:32 UTC

Contenidos
Artculos
Introduccin
Algoritmo Heurstica Teora de la complejidad computacional 1 1 8 11 18 18 20 21 22 22 25 27 31 31 32 42 50 50 52 59 74 74 87

Crecimiento de finciones
Cota superior asinttica Cota inferior asinttica Cota ajustada asinttica

Ordenamiento
Algoritmo de ordenamiento Heapsort Quicksort

Estructuras de datos
Estructura de datos Pila (informtica) Cola (informtica)

rboles de bsqueda
rbol (informtica) rbol binario rbol binario de bsqueda

Tablas y funciones de dispersin


Tabla hash Funcin hash

Referencias
Fuentes y contribuyentes del artculo Fuentes de imagen, Licencias y contribuyentes 98 99

Licencias de artculos

Licencia

100

Introduccin
Algoritmo
En matemticas, lgica, ciencias de la computacin y disciplinas relacionadas, un algoritmo (del griego y latn, dixit algorithmus y este a su vez del matemtico persa Al-Juarismi) es un conjunto prescrito de instrucciones o reglas bien definidas, ordenadas y finitas que permite realizar una actividad mediante pasos sucesivos que no generen dudas a quien deba realizar dicha actividad.[1] Dados un estado inicial y una entrada, siguiendo los pasos sucesivos se llega a un estado final y se obtiene una solucin. Los algoritmos son el objeto de estudio de la algoritmia. 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 multiplicacin, para calcular el producto, el algoritmo de la divisin para calcular el cociente de dos nmeros, el algoritmo de Euclides para obtener el mximo comn divisor de dos enteros positivos, o el mtodo de Gauss para resolver un sistema lineal de ecuaciones.

Los diagramas de flujo sirven para representar algoritmos de manera grfica.

Definicin formal
En general, no existe ningn consenso definitivo en cuanto a la definicin formal de algoritmo. Muchos autores los sealan como listas de instrucciones para resolver un clculo o un problema abstracto, es decir, que un nmero finito de pasos convierten los datos de un problema (entrada) en una solucin (salida). Sin embargo cabe notar que algunos algoritmos no necesariamente tienen que terminar o resolver un problema en particular. Por ejemplo, una versin modificada de la criba de Eratstenes que nunca termine de calcular nmeros primos no deja de ser un algoritmo. A lo largo de la historia varios autores han tratado de definir formalmente a los algoritmos utilizando modelos matemticos. Esto fue realizado por Alonzo Church en 1936 con el concepto de "calculabilidad efectiva" basada en su clculo lambda y por Alan Turing basndose en la mquina de Turing. Los dos enfoques son equivalentes, en el sentido en que se pueden resolver exactamente los mismos problemas con ambos enfoques. . Sin embargo, estos modelos estn sujetos a un tipo particular de datos como son nmeros, smbolos o grficas mientras que, en general, los algoritmos funcionan sobre una vasta cantidad de estructuras de datos. En general, la parte comn en todas las definiciones se puede resumir en las siguientes tres propiedades siempre y cuando no consideremos algoritmos paralelos: 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)

Algoritmo 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. En resumen, un algoritmo es cualquier cosa que funcione paso a paso, donde cada paso se pueda describir sin ambigedad y sin hacer referencia a una computadora en particular, y adems tiene un lmite fijo en cuanto a la cantidad de datos que se pueden leer/escribir en un solo paso. Esta amplia definicin abarca tanto a algoritmos prcticos como aquellos que solo funcionan en teora, por ejemplo el mtodo de Newton y la eliminacin de Gauss-Jordan funcionan, al menos en principio, con nmeros de precisin infinita; sin embargo no es posible programar la precisin infinita en una computadora, y no por ello dejan de ser algoritmos. En particular es posible considerar una cuarta propiedad que puede ser usada para validar la tesis de Church-Turing de que toda funcin calculable se puede programar en una mquina de Turing (o equivalentemente, en un lenguaje de programacin suficientemente general): Aritmetizabilidad. Solamente operaciones innegablemente calculables estn disponibles en el paso inicial.

Medios de expresin de un algoritmo


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. La descripcin de un algoritmo usualmente se hace en tres niveles: 1. Descripcin de alto nivel. Se establece el problema, se selecciona un modelo matemtico y se explica el algoritmo de manera verbal, posiblemente con ilustraciones y omitiendo detalles. 2. Descripcin formal. Se usa pseudocdigo para describir la secuencia de pasos que encuentran la solucin. 3. Implementacin. Se muestra el algoritmo expresado en un lenguaje de programacin especfico o algn objeto capaz de llevar a cabo instrucciones. Tambin es posible incluir un teorema que demuestre que el algoritmo es correcto, un anlisis de complejidad o ambos.

Algoritmo

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

Diagrama de flujo que expresa un algoritmo para calcular la raz cuadrada de un nmero

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

Sistemas formales
La teora de autmatas y la teora de funciones recursivas proveen modelos matemticos que formalizan el concepto de algoritmo. Los modelos ms comunes son la mquina de Turing, mquina de registro y funciones -recursivas. Estos modelos son tan precisos como un lenguaje mquina, careciendo de expresiones coloquiales o ambigedad, sin embargo se mantienen independientes de cualquier computadora y de cualquier implementacin.

Implementacin
Muchos algoritmos son ideados para implementarse en un programa. Sin embargo, los algoritmos pueden ser implementados en otros medios, como una red neuronal, un circuito elctrico o un aparato mecnico y elctrico. Algunos algoritmos inclusive se disean especialmente para implementarse usando lpiz y papel. El algoritmo de multiplicacin tradicional, el algoritmo de Euclides, la criba de Eratstenes y muchas formas de resolver la raz

Algoritmo cuadrada son slo algunos ejemplos.

Variables
Son elementos que toman valores especficos de un tipo de datos concreto. La declaracin de una variable puede realizarse comenzando con var. Principalmente, existen dos maneras de otorgar valores iniciales a variables: 1. Mediante una sentencia de asignacin. 2. Mediante un procedimiento de entrada de datos (por ejemplo: 'read'). Ejemplo: ... i:=1; read(n); while i < n do begin (* cuerpo del bucle *) i := i + 1 end; ...

Estructuras secuenciales
La estructura secuencial es aquella en la que una accin sigue a otra en secuencia. Las operaciones se suceden de tal modo que la salida de una es la entrada de la siguiente y as sucesivamente hasta el fin del proceso. La asignacin de esto consiste, en el paso de valores o resultados a una zona de la memoria. Dicha zona ser reconocida con el nombre de la variable que recibe el valor. La asignacin se puede clasificar de la siguiente forma: 1. 2. 3. 4. Simples: Consiste en pasar un valor constante a una variable (a 15) Contador: Consiste en usarla como un verificador del nmero de veces que se realiza un proceso (a a + 1) Acumulador: Consiste en usarla como un sumador en un proceso (a a + b) De trabajo: Donde puede recibir el resultado de una operacin matemtica que involucre muchas variables (a c + b*2/4).

Un ejemplo de estructura secuencial, como obtener la rea de un tringulo: Inicio ... float b, h, a; printf("Diga la base"); scanf("%f", &b); printf("Diga la altura"); scanf("%f", &h); a = (b*h)/2; printf("El rea del tringulo es %f", a) ... Fin

Algoritmo

Algoritmos como funciones


Un algoritmo se puede concebir como una funcin que transforma los datos de un problema (entrada) en los datos de una solucin (salida). Ms aun, los Esquemtica de un algoritmo solucionando un problema de ciclo hamiltoniano. datos se pueden representar a su vez como secuencias de bits, y en general, de smbolos cualesquiera. Como cada secuencia de bits representa a un nmero natural (vase Sistema binario), entonces los algoritmos son en esencia funciones de los nmeros naturales en los nmeros naturales que s se pueden calcular. Es decir que todo algoritmo calcula una funcin donde cada nmero natural es la codificacin de un problema o de una solucin. En ocasiones los algoritmos son susceptibles de nunca terminar, por ejemplo, cuando entran a un bucle infinito. Cuando esto ocurre, el algoritmo nunca devuelve ningn valor de salida, y podemos decir que la funcin queda indefinida para ese valor de entrada. Por esta razn se considera que los algoritmos son funciones parciales, es decir, no necesariamente definidas en todo su dominio de definicin. Cuando una funcin puede ser calculada por medios algortmicos, sin importar la cantidad de memoria que ocupe o el tiempo que se tarde, se dice que dicha funcin es computable. No todas las funciones entre secuencias datos son computables. El problema de la parada es un ejemplo.

Anlisis de algoritmos
Como medida de la eficiencia de un algoritmo, se suelen estudiar los recursos (memoria y tiempo) que consume el algoritmo. El anlisis de algoritmos se ha desarrollado para obtener valores que de alguna forma indiquen (o especifiquen) la evolucin del gasto de tiempo y memoria en funcin del tamao de los valores de entrada. El anlisis y estudio de los algoritmos es una disciplina de las ciencias de la computacin y, en la mayora de los casos, su estudio es completamente abstracto sin usar ningn tipo de lenguaje de programacin ni cualquier otra implementacin; por eso, en ese sentido, comparte las caractersticas de las disciplinas matemticas. As, el anlisis de los algoritmos se centra en los principios bsicos del algoritmo, no en los de la implementacin particular. Una forma de plasmar (o algunas veces "codificar") un algoritmo es escribirlo en pseudocdigo o utilizar un lenguaje muy simple tal como Lexico, cuyos cdigos pueden estar en el idioma del programador. Algunos escritores restringen la definicin de algoritmo a procedimientos que deben acabar en algn momento, mientras que otros consideran procedimientos que podran ejecutarse eternamente sin pararse, suponiendo el caso en el que existiera algn dispositivo fsico que fuera capaz de funcionar eternamente. En este ltimo caso, la finalizacin con xito del algoritmo no se podra definir como la terminacin de este con una salida satisfactoria, sino que el xito estara definido en funcin de las secuencias de salidas dadas durante un periodo de vida de la ejecucin del algoritmo. Por ejemplo, un algoritmo que verifica que hay ms ceros que unos en una secuencia binaria infinita debe ejecutarse siempre para que pueda devolver un valor til. Si se implementa correctamente, el valor devuelto por el algoritmo ser vlido, hasta que evale el siguiente dgito binario. De esta forma, mientras evala la siguiente secuencia podrn leerse dos tipos de seales: una seal positiva (en el caso de que el nmero de ceros sea mayor que el de unos) y una negativa en caso contrario. Finalmente, la salida de este algoritmo se define como la devolucin de valores exclusivamente positivos si hay ms ceros que unos en la secuencia y, en cualquier otro caso, devolver una mezcla de seales positivas y negativas.

Algoritmo

Ejemplo de algoritmo
El problema consiste en encontrar el mximo de un conjunto de nmeros. Para un ejemplo ms complejo vase Algoritmo de Euclides.

Descripcin de alto nivel


Dado un conjunto finito de nmeros, se tiene el problema de encontrar el nmero ms grande. Sin prdida de generalidad se puede asumir que dicho conjunto no es vaco y que sus elementos estn numerados como . Es decir, dado un conjunto se pide encontrar tal que para todo elemento

que pertenece al conjunto . Para encontrar el elemento mximo, se asume que el primer elemento ( ) es el mximo; luego, se recorre el conjunto y se compara cada valor con el valor del mximo nmero encontrado hasta ese momento. En el caso que un elemento sea mayor que el mximo, se asigna su valor al mximo. Cuando se termina de recorrer la lista, el mximo nmero que se ha encontrado es el mximo de todo el conjunto.

Descripcin formal
El algoritmo puede ser escrito de una manera ms formal en el siguiente pseudocdigo:
Algoritmo Encontrar el mximo de un conjunto funcin max( // )

es un conjunto no vaco de nmeros// // es el nmero de elementos de //

para

si

hasta

hacer entonces

devolver

Sobre la notacin: "" representa una asignacin: significa que la variable toma el valor de ; "devolver" termina el algoritmo y devuelve el valor a su derecha (en este caso, el mximo de ).

Implementacin
En lenguaje C++: int max(int c[], int n) { int i, m = c[0]; for (i = 1; i < n; i++) if (c[i] > m) m = c[i]; return m; }

Algoritmo

Referencias
[1] Real Academia Espaola. Diccionario de la lengua espaola (http:/ / buscon. rae. es/ draeI/ SrvltGUIBusUsual?TIPO_HTML=2& TIPO_BUS=3& LEMA=algoritmo) "Conjunto ordenado y finito de operaciones que permite hallar la solucin de un problema."

Bibliografa
Fundamentos de Algoritmia, G. Brassard y P. Bratley. (ISBN 848966000X) The Art of Computer Programming, Knuth, D. E. [quien fue tambin, el creador del TeX] Introduction to Algorithms (2nd ed), Cormen, T. H., Leiserson, C. E., Rivest, R. L. y Stein, C. Introduction to Algorithms. A Creative Approach, Mamber, U. Algorithms in C (3r ed), Sedgewick, R. (tambin existen versiones en C++ y Java) The Design and Analysis of Computer Algorithms, Aho, A.

Enlaces externos
Wikilibros Wikilibros alberga un libro o manual sobre Algoritmia.

Wikcionario tiene definiciones para algoritmo.Wikcionario Portal de algoritmia (http://www.algoritmia.net) Tcnicas de Diseo de Algoritmos (http://www.lcc.uma.es/~av/Libro/) manual que explica y ejemplifica los distintos paradigmas de diseo de algoritmos. Rosa Guerequeta y Antonio Vallecillo (profesores de la Universidad de Mlaga). Transparencias de la asignatura "Esquemas Algortmicos", Campos, J. (http://webdiis.unizar.es/asignaturas/ EDA/) Apuntes y problemas de Algortmica por Domingo Gimnez Cnovas (http://dis.um.es/~domingo/alg.html) Curso de Diseo de Algoritmos de Carlos Pes (http://www.carlospes.com/curso_de_algoritmos/) Algoritmos y Diagramas de Flujo (http://snippets-tricks.org/algoritmos-y-diagramas-de-flujo/)

Heurstica

Heurstica
Se puede definir Heurstica como un arte, tcnica o procedimiento prctico o informal, para resolver problemas.[1] Alternativamente, se puede definir como un conjunto de reglas metodolgicas no necesariamente forzosas, positivas y negativas, que sugieren o establecen cmo proceder y qu problemas evitar a la hora de generar soluciones y elaborar hiptesis.[2] Es generalmente considerado que la capacidad heurstica es un rasgo caracterstico de los humanos[3] desde cuyo punto de vista puede describirse como el arte y la ciencia del descubrimiento y de la invencin o de resolver problemas mediante la creatividad y el pensamiento lateral o pensamiento divergente. Segn el matemtico George Plya[4] la base de la heurstica est en la experiencia de resolver problemas y en ver cmo otros lo hacen. Consecuentemente se dice que hay bsquedas ciegas, bsquedas heursticas (basadas en la experiencia) y bsquedas racionales. La palabra heurstica procede del trmino griego ,[5] que significa hallar, inventar (etimologa que comparte con eureka[6]). La palabra heurstica aparece en ms de una categora gramatical. Cuando se usa como sustantivo, identifica el arte o la ciencia del descubrimiento, una disciplina susceptible de ser investigada formalmente. Cuando aparece como adjetivo, se refiere a cosas ms concretas, como estrategias heursticas, reglas heursticas o silogismos y conclusiones heursticas. Claro est que estos dos usos estn ntimamente relacionados ya que la heurstica usualmente propone estrategias heursticas que guan el descubrimiento. La popularizacin del concepto se debe a George Plya, con su libro Cmo resolverlo (How to solve it). Habiendo estudiado tantas pruebas matemticas desde su juventud, quera saber cmo los matemticos llegan a ellas. El libro contiene la clase de recetas heursticas que trataba de ensear a sus alumnos de matemticas. Cuatro ejemplos extrados de l ilustran el concepto mejor que ninguna definicin: Si no consigues entender un problema, dibuja un esquema. Si no encuentras la solucin, haz como si ya la tuvieras y mira qu puedes deducir de ella (razonando a la inversa). Si el problema es abstracto, prueba a examinar un ejemplo concreto. Intenta abordar primero un problema ms general (es la paradoja del inventor: el propsito ms ambicioso es el que tiene ms posibilidades de xito).

Matemtica
En la matemtica, la heurstica existe desde la Grecia antigua. Sin embargo, la formalizacin y el alto grado de rigor en matemtica le ha restado importancia al estudio del descubrimiento, considerndolo ms bien de inters para la psicologa. Aunque existe el campo de la teora de la demostracin, ste nada tiene que ver con encontrar patrones de demostracin o reglas para encontrar las demostraciones de los teoremas. La palabra heurus proviene del griego erus. Hay trabajos de Poincar, Hadamard y Polya sobre la creacin en matemtica. Al respecto el libro "Razonamiento plausible " de George Polya, describe las posibilidades de creacin en la diversas ramas de la matemtica y trabajos concretos de algunos matemticos.

Psicologa
En psicologa la heurstica se relaciona con la creatividad y se ha propuesto que sea aquella regla sencilla y eficiente para orientar la toma de decisiones y para explicar en un plano prctico cmo las personas llegan a un juicio o solucionan un problema. Usualmente una heurstica opera cuando un problema es complejo o el problema trae informacin incompleta. En general, una heurstica puede considerarse como un atajo a los procesos mentales activos y, por lo tanto, es una medida que ahorra o conserva recursos mentales. Las heursticas funcionan efectivamente en la mayora de las circunstancias, sin embargo, tambin pueden conducir a errores sistemticos en la

Heurstica toma de decisiones o el desarrollo de juicios. La ideacin de soluciones heursticas frecuentemente arranca de un razonamiento por analoga. Un ejemplo de un atajo mental es el uso de un estereotipo. Cuando se juzga a un individuo basndose en la descripcin estereotpica de un grupo al cual pertenece, el uso del estereotipo puede resultar en un error, ya que el individuo puede ser poco representativo del estereotipo. Sin embargo la heurstica, aunque imperfecta, puede seguir siendo vlida si el estereotipo es estadsticamente lo bastante correcto. As, los posibles errores puntuales quedan sobradamente compensados por los ms frecuentes aciertos. stos son obtenidos, adems, mediante una regla relativamente sencilla que ahorra recursos mentales y acelera de forma significativa la toma de decisiones, lo que en ciertas situaciones puede resultar crtico (por ejemplo cuando la integridad fsica, mental o econmica del individuo est en juego).

Ingeniera
Artculo principal: Heurstica (ingeniera) En ingeniera, una heurstica es un mtodo basado en la experiencia que puede utilizarse como ayuda para resolver problemas de diseo, desde calcular los recursos necesarios hasta en planear las condiciones de operacin de los sistemas. Mediante el uso de heursticas, es posible resolver ms rpidamente problemas conocidos o similares a otros conocidos. Existen varios mtodos heursticos disponibles para los ingenieros como, por ejemplo, el Anlisis modal de fallos y efectos y los rboles de fallo. En el primero se depende de un grupo de ingenieros experimentados que evalan los problemas y fallos, los ordenan segn su importancia y recomiendan soluciones. Otros, como los mtodos de ingeniera forense, son una amplia fuente de informacin para la investigacin de problemas y responsables, y se basan en la heurstica del eslabn ms dbil y en la eliminacin de causas improbables. El conocimiento de qu causas son probables y cules no, forma una heurstica aprendida por la profesin durante muchos aos, ms que un conocimiento cientfico aplicado. Dado que las heursticas pueden equivocarse, es fundamental conocer los casos en los que son aplicables y los lmites a su uso. En general, en la ingeniera deben considerarse como ayudas o apoyos para hacer estimaciones rpidas y diseos preliminares, pero no como justificaciones finales de un diseo o proyecto u otros.

La heurstica como metodologa cientfica


Como metodologa cientfica, la heurstica es aplicable a cualquier ciencia e incluye la elaboracin de medios auxiliares, principios, reglas, estrategias y programas que faciliten la bsqueda de vas de solucin a problemas; o sea, para resolver tareas de cualquier tipo para las que no se cuente con un procedimiento algortmico de solucin. Segn Horst Mler: Los procedimientos heursticos son formas de trabajo y de pensamiento que apoyan la realizacin consciente de actividades mentales exigentes. Los procedimientos heursticos como mtodo cientfico pueden dividirse en principios, reglas y estrategias. Principios heursticos: constituyen sugerencias para encontrar directamente la idea de solucin; posibilita determinar, por tanto, a la vez, los medios y la va de solucin. Dentro de estos principios se destacan la analoga y la reduccin (modelizacin). Reglas heursticas: actan como impulsos generales dentro del proceso de bsqueda y ayudan a encontrar, especialmente, los medios para resolver los problemas. Las reglas heursticas que ms se emplean son: Separar lo dado de lo buscado. Confeccionar figuras de anlisis: esquemas, tablas, mapas, etc. Representar magnitudes dadas y buscadas con variables. Determinar si se tienen frmulas adecuadas.

Utilizar nmeros estructuras ms simples en lugar de datos. Reformular el problema.

Heurstica Estrategias heursticas: se comportan como recursos organizativos del proceso de resolucin, que contribuyen especialmente a determinar la va de solucin del problema abordado. Existen dos estrategias: El trabajo hacia adelante: se parte de lo dado para realizar las reflexiones que han de conducir a la solucin del problema: hiptesis. El trabajo hacia atrs: se examina primeramente lo que se busca y, apoyndose en los conocimientos que se tienen, se analizan posibles resultados intermedios de lo que se puede deducir lo buscado, hasta llegar a los dados.

10

Otras acepciones
Una teora cientfica tiene un alto valor heurstico si es capaz de generar nuevas ideas o inducir nuevas invenciones. Para ello, sin ser irrelevante, no es imprescindible que la teora sea cierta o incierta. Parafraseando a Sartre; merced a su capacidad heurstica, pese a las predeterminaciones genticas y otros condicionamientos, es probable que el ser humano (valga la aparente paradoja de la frase) est condenado a ser libre de las limitaciones que el medio le impone. Mirndola desde los conceptos subyacentes, la propuesta heurstica es la capacidad del ser humano para cambiar su conducta, con el fin de resolver situaciones problemticas.

Referencias
* Moustakas, Clark. "Heuristic Research: Design, Methodology and Applications." California: Sage Publications, 1990.

http:/ / www.

openisbn.com/isbn/0803938829/
[1] Glosario: Arte o tcnica de la bsqueda o investigacin. Mtodo heurstico, por oposicin al didctico o de enseanza. en Heurstica (http:/ / lengua-y-literatura. glosario. net/ terminos-filosoficos/ heurstica-5819. html) [2] Roberto Gmez L (http:/ / www. eumed. net/ cursecon/ libreria/ rgl-evol/ 2. 4. 6. htm), citando a Imre Lakatos en EVOLUCIN CIENTFICA Y METODOLGICA DE LA ECONOMA] 2.4.6. LOS PROGRAMAS DE INVESTIGACIN CIENTFICA DE LKATOS. [3] Epistemowikia: Por heurstica entendemos una estrategia, mtodo, criterio o truco usado para hacer ms sencilla la solucin de problemas difciles. El conocimiento heurstico es un tipo especial de conocimiento usado por los humanos para resolver problemas complejos. en Heurstica (http:/ / campusvirtual. unex. es/ cala/ epistemowikia/ index. php?title=Heurstica) [4] G Plya: (1945) "How to solve it", traducido al castellano como Cmo resolverlo (1965) [5] Segn la Real Academia, (http:/ / lema. rae. es/ drae/ ?val=heurstica) (consultado el 29 de abril de 2009). [6] Real Academia (http:/ / buscon. rae. es/ draeI/ SrvltConsulta?TIPO_BUS=3& LEMA=eureka) (consultado el 29 de abril de 2009).

Teora de la complejidad computacional

11

Teora de la complejidad computacional


La Teora de la Complejidad Computacional es una rama de la teora de la computacin que se centra en la clasificacin de los problemas computacionales de acuerdo a su dificultad inherente, y en la relacin entre dichas clases de complejidad. Un problema se cataloga como "inherentemente difcil" si su solucin requiere de una cantidad significativa de recursos computacionales, sin importar el algoritmo utilizado. La teora de la complejidad computacional formaliza dicha aseveracin, introduciendo modelos de cmputo matemticos para el estudio de estos problemas y la cuantificacin de la cantidad de recursos necesarios para resolverlos, como tiempo y memoria. Uno de los roles de la teora de la complejidad computacional es determinar los lmites prcticos de qu es lo que se puede hacer en una computadora y qu no. Otros campos relacionados con la teora de la complejidad computacional son el anlisis de algoritmos y la teora de la computabilidad. Una diferencia significativa entre el anlisis de algoritmos y la teora de la complejidad computacional, es que el primero se dedica a determinar la cantidad de recursos requeridos por un algoritmo en particular para resolver un problema, mientras que la segunda, analiza todos los posibles algoritmos que pudieran ser usados para resolver el mismo problema. La teora de la complejidad computacional trata de clasificar los problemas que pueden, o no pueden ser resueltos con una cantidad determinada de recursos. A su vez, la imposicin de restricciones sobre estos recursos, es lo que la distingue de la teora de la computabilidad, la cual se preocupa por qu tipo de problemas pueden ser resueltos de manera algortmica.

Historia
Antes de que se realizaran investigaciones en torno a la complejidad de los algoritmos, se crearon los cimientos de esta teora por varios investigadores. Uno de los aportes ms influyentes fue la definicin de las Mquinas de Turing en 1936, las cuales resultaron ser una nocin de computadora muy flexible y robusta. A medida que las computadoras se desarrollaban en los 40's y los 50's, la Mquina de Turing demostr ser el modelo terico correcto de cmputo. Sin embargo, rpidamente se descubri que el modelo bsico de la Mquina de Turing fallaba al cuantificar el tiempo y la memoria requerida por una computadora, un problema crtico hoy en da, y an ms en aquellos tiempos. La idea de medir el tiempo y espacio como una funcin de la longitud de la entrada, se origin a principios de los 60's por Hartmanis and Stearns, y as, naci la teora de la complejidad computacional. En los inicios, los investigadores trataban de entender las nuevas medidas de complejidad, y cmo se relacionaban unas con otras. En 1965, Edmonds defini un "buen" algoritmo como uno con un tiempo de ejecucin acotado por un polinomio, es decir, con un tiempo de ejecucin polinmico.[1] Esto condujo al surgimiento de uno de los conceptos ms importantes de la teora de la complejidad computacional: la NP-completitud y su pregunta fundamental, si P=NP. El campo comenz a florecer cuando el investigador norteamericano Stephen Cook, trabajando de manera independiente al investigador sovitico Leonid Levin, probaron que existen problemas relevantes que son NP-completos. En 1972, Richard Karp llev esta idea un paso ms adelante, demostrando que 21 problemas combinatorios y de teora de grafos, caracterizados por ser computacionalmente intratables, eran NP-completos. Tambin en los 70's, se produjo un crecimiento de las clases de complejidad a medida que los investigadores trataban de comprender los distintos modelos de cmputo existentes. En los 80's, se produjo un auge de los modelos finitos, que analizaban el proceso de cmputo de una manera inherentemente distinta. Surgi un nuevo acercamiento a problemas como P=NP, y an cuando estos modelos tenan sus limitaciones separando las clases de complejidad, esta aproximacin introdujo tcnicas combinatorias que permitieron un mejor entendimiento de los lmites de estos modelos.

Teora de la complejidad computacional Ya en los 90's, se estudiaron nuevos modelos de cmputo como las computadoras cunticas, donde una misma tarea puede tener diferente complejidad en la computacin clsica y en la computacin cuntica. Sin embargo, existen varias limitantes, entre ellas, la de desarrollar un hardware para este modelo, y que se requieren grandes cantidades de espacio para realizar los clculos.

12

Problemas, algoritmos y complejidad


Para poder referirnos a problemas como "inherentemente intratables" y problemas de dificultad "equivalente", es necesario comprender algunos trminos ms bsicos.

Problema computacional
Un problema computacional constituye una pregunta a ser respondida, teniendo generalmente varios parmetros, o variables libres, cuyos valores no se han especificado. Un problema se describe mediante: 1. Una descripcin general de todos sus parmetros (pueden ser de entrada o de salida). 2. Una sentencia que describa las propiedades que la respuesta, o la solucin, debe cumplir. Una instancia de un problema se obtiene cuando se especifican valores particulares para todos los parmetros del problema. Por ejemplo, consideremos el problema del test de primalidad. La instancia es un nmero (e.g. 15) y la solucin es "s" si el nmero es primo, y "no" en caso contrario. Visto de otra manera, la instancia es una entrada particular del problema, y la solucin es la salida correspondiente para la entrada dada.

Problemas de decisin
Un problema de decisin es un tipo especial de problema computacional cuya respuesta es solamente "s" o "no" (o, de manera ms formal, "1" o "0"). Un problema de decisin pudiera verse como un lenguaje formal, donde los elementos que pertenecen al lenguaje son las instancias del problema cuya respuesta es "s", los que no pertenecen al lenguaje son aquellas instancias cuya respuesta es "no". El objetivo es decidir, con la ayuda de un algoritmo, si una determinada entrada es un elemento del lenguaje formal considerado. Si el algoritmo devuelve como respuesta "s", se dice que el algoritmo acepta la entrada, de lo contrario se dice que la rechaza. Los problemas de decisin constituyen uno de los principales objetos de estudio de la teora de la complejidad computacional, pues la NP-completitud se aplica directamente a estos tipos de problemas en vez de a problemas de optimizacin. Estos problemas tienen gran importancia porque casi todo problema puede transformarse en un problema de decisin.

Algoritmos
Podemos decir informalmente, que los algoritmos son procedimientos paso-a-paso para resolver problemas. Se puede pensar en ellos como simples programas de computadora, escritos en un lenguaje artificial especfico.[2] Se dice que un algoritmo resuelve un problema A, si dicho algoritmo se puede aplicar a cualquier instancia I de A, y se garantiza que siempre produce una solucin para dicha instancia. De manera general, nos interesa encontrar el algoritmo ms "eficiente" para resolver cierto problema. En su sentido ms amplio, la nocin de eficiencia involucra a todos los recursos computacionales necesarios para la ejecucin de un algoritmo. Por algoritmo "ms eficiente" usualmente nos referimos al ms rpido. Debido a que los requerimientos de tiempo son usualmente un factor dominante cuando se trata de determinar si un algoritmo es lo suficientemente eficiente para ser til en la prctica, nos concentraremos en este recurso.

Teora de la complejidad computacional

13

Algoritmos de tiempo polinmico y problemas intratables


Los cientficos de la computacin realizan la distincin entre algoritmos de Tiempo polinmico y algoritmos de tiempo exponencial cuando se trata de caracterizar a los algoritmos como "suficientemente eficiente" y "muy ineficiente" respectivamente. Un algoritmo de tiempo polinomial se define como aquel con funcin de complejidad temporal en O(p(n)) para alguna funcin polinmica p, donde n denota el tamao de la entrada. Cualquier algoritmo cuya funcin de complejidad temporal no pueda ser acotada de esta manera, se denomina algoritmo de tiempo exponencial. La mayora de los algoritmos de tiempo exponencial son simples variaciones de una bsqueda exhaustiva, mientras que los algoritmos de tiempo polinomial, usualmente se obtienen mediante un anlisis ms profundo de la estructura del problema. En la teora de la complejidad computacional, existe el consenso de que un problema no est "bien resuelto" hasta que se conozca un algoritmo de tiempo polinomial que lo resuelva. Por tanto, nos referiremos a un problema como intratable, si es tan difcil que no existe algoritmo de tiempo polinomial capaz de resolverlo.[3]

Clases de complejidad
Una clase de complejidad es un conjunto de problemas que poseen la misma complejidad computacional.

Definiendo clases de complejidad


Las clases de complejidad ms sencillas se definen teniendo en cuenta factores como: El tipo de problema computacional: Los problemas ms comnmente utilizados son los problemas de decisin, pero las clases de complejidad se pueden definir para otros tipos de problemas. El modelo de cmputo: El modelo de cmputo ms comn es la Mquina de Turing determinista, pero muchas clases de complejidad se basan en Mquinas de Turing no deterministas, Mquinas de Turing cunticas, etc. El recurso (o recursos) que est(n) siendo acotado(s) y la(s) cota(s): Estas dos propiedades usualmente se utilizan juntas, por ejemplo, "tiempo polinomial", "espacio logartmico", "profundidad constante", etc.

Mquinas de Turing deterministas y la clase P


La clase P contiene a aquellos problemas que son solubles en tiempo polinmico por una mquina de Turing determinista.[4] Para la definicin anterior se ha fijado el modelo de cmputo: la Mquina de Turing determinista. Existen distintas variantes de la Mquina de Turing y es conocido que la ms dbil de ellas puede simular a la ms fuerte, adicionando a lo sumo un tiempo polinmico. En las dcadas posteriores a la Tesis de Church-Turing surgieron otros modelos de cmputo, y se pudo mostrar que la Mquina de Turing tambin poda simularlos a lo sumo adicionando tambin un tiempo polinmico. Por tanto, la clase anloga a P para dichos modelos no es mayor que la clase P para el modelo de cmputo de la mquina de Turing. La clase P juega un papel importante en la teora de la complejidad computacional debido a que: 1. P es invariante para todos los modelos de cmputo que son polinmicamente equivalentes a la Mquina de Turing determinista. 2. A grandes rasgos, P corresponde a la clase de problemas que, de manera realista, son solubles en una computadora.

Teora de la complejidad computacional

14

Computacin no determinista y la clase NP


Muchas veces podemos evitar utilizar la fuerza bruta en los problemas para obtener soluciones en tiempo polinmico. Sin embargo, para algunos problemas esto no ha podido lograrse, es decir, no se conocen algoritmos que los resuelvan en tiempo polinmico. Quizs estos problemas tengan algoritmos en tiempo polinomial que se basan en principios por ahora desconocidos, o quizs estos problemas no pueden ser resueltos en tiempo polinmico, debido a que son "inherentemente difciles". La clase de complejidad NP consta de los problemas "verificables" en tiempo polinmico. Por verificable se entiende a un problema tal que dado un certificado de solucin (candidato a solucin), se puede verificar que dicho certificado es correcto en un tiempo polinmico en el tamao de la entrada. A los problemas en la clase NP usualmente se les llama problemas NP.[5] El trmino NP proviene de no determinista en tiempo polinmico y se deriva de un caracterizacin alternativa de esta clase, donde se utilizan Mquinas de Turing no deterministas. Informalmente, se puede definir la clase NP en trminos de un algoritmo no determinista (recordar la equivalencia entre algoritmo y Mquina de Turing). El algoritmo mencionado est compuesto por 2 etapas separadas. Dada una instancia del problema I, la primera etapa simplemente "adivina" un candidato a solucin S. Entonces, la etapa de verificacin recibe como entrada a I y a S, y procede a realizar el cmputo de una manera determinista, finalmente detenindose con la respuesta "s", o con la respuesta "no", o sigue computando sin detenerse. Al igual que la clase P, la clase NP es insensible a la eleccin del modelo de cmputo no determinista, debido a que dichos modelos son equivalentes polinmicamente.

Clases de complejidad importantes


Muchas clases de complejidad importantes pueden ser definidas acotando el tiempo o el espacio utilizado por el algoritmo. Algunas de estas clases de problemas de decisin son:
Complexity class DTIME(f(n)) P EXPTIME NTIME(f(n)) NP NEXPTIME DSPACE(f(n)) L PSPACE EXPSPACE NSPACE(f(n)) NL NPSPACE NEXPSPACE Model of computation Mquina de Turing determinista Mquina de Turing determinista Mquina de Turing determinista Resource constraint Tiempof(n) Tiempo poly(n) Tiempo 2poly(n)

Mquina de Turing no determinista Tiempof(n) Mquina de Turing no determinista Tiempo poly(n) Mquina de Turing no determinista Tiempo 2poly(n) Mquina de Turing determinista Mquina de Turing determinista Mquina de Turing determinista Mquina de Turing determinista Espaciof(n) Espacio O(log n) Espacio poly(n) Espacio 2poly(n)

Mquina de Turing no determinista Espaciof(n) Mquina de Turing no determinista Espacio O(log n) Mquina de Turing no determinista Espacio poly(n) Mquina de Turing no determinista Espacio 2poly(n)

Teora de la complejidad computacional

15

La pregunta P=NP
La relacin entre las clases P y NP es fundamental para la teora de la NP-completitud. Intuitivamente, creemos que P es un subconjunto de NP. Y efectivamente, cada problema de decisin resuelto por un algoritmo de tiempo polinomial determinista, tambin puede ser resuelto por un algoritmo de tiempo polinomial no determinista. Simplemente se necesita observar que cualquier algoritmo determinista puede ser utilizado en la etapa de verificacin de un algoritmo no determinista. Si B es un problema de P, y A es un algoritmo de tiempo polinomial para B, entonces se puede construir un algoritmo de tiempo polinomial no determinista para B, simplemente utilizando A en la etapa de verificacin e ignorando la etapa de adivinacin. Por tanto, si B pertenece a P, entonces B tambin pertenece a NP. La pregunta P=NP es una de las ms importantes en el campo de las ciencias de la computacin, debido a las grandes repercusiones que habran, en caso de encontrarse una solucin. Si P=NP, cualquier problema polinmicamente verificable fuera polinmicamente decidible. La mayora de los investigadores creen que estas clases no son iguales, porque se han realizado bastantes esfuerzos para encontrar algoritmos de tiempo polinomial para varios problemas en NP, sin xito. Los investigadores tambin han tratado de probar que las clases son distintas, pero eso conllevara a mostrar que no existe un algoritmo "eficiente" para reemplazar a la bsqueda por fuerza bruta.

NP-Completitud
Reduccin polinomial
Una reduccin es una transformacin de un problema en otro problema. Intuitivamente, un problema Q puede ser reducido a otro problema Q', si cualquier instancia del problema Q puede ser "fcilmente" expresada como una instancia del problema Q', y cuya solucin proporcione una solucin para la instancia de Q.[6] Existen muchos tipos de reducciones: basadas en el mtodo de reduccin, como las reducciones de Cook, las reducciones de Karp y las reducciones de Levin, y las basadas en la cota de la complejidad, como la reduccin en tiempo polinomial o la reduccin de espacio logartmica. Una de las reducciones ms utilizadas es la reduccin en tiempo polinomial, lo cual significa que el proceso de reduccin toma un tiempo polinomial.

Problemas NP-completos
Las reducciones en tiempo polinomial nos dotan de elementos para probar, de una manera formal, que un problema es al menos tan difcil que otro, con una diferencia de un factor polinomial. Estas son esenciales para definir a los problemas NP-completos, adems de ayudar a comprender los mismos. La clase de los problemas NP-completos contiene a los problemas ms difciles en NP, en el sentido de que son los que estn ms lejos de estar en P. Debido a que el problema P=NP no ha sido resuelto, el hecho de reducir un problema B, a otro problema A, indicara que no se conoce solucin en tiempo polinomial para A. Esto es debido a que una solucin en tiempo polinomial para A, tendra como consecuencia la existencia de una solucin polinomial para B. De manera similar, debido a que todos los problemas NP pueden ser reducidos a este conjunto, encontrar un problema NP-completo que pueda ser resuelto en un tiempo polinomial significara que P=NP.

Importancia de la NP-Completitud
Quizs la razn de mayor peso por la cual los cientficos de la computacin creen que P es distinto de NP, es la existencia de la clase de problemas "NP-completos". Esta clase tiene la curiosa propiedad de que si algn problema NP-completo puede ser resuelto en tiempo polinomial, entonces todo problema en NP tiene una solucin en tiempo polinomial, es decir, P=NP. A pesar de aos de estudio, ningn algoritmo de tiempo polinomial se ha descubierto para ningn problema NP-completo.

Teora de la complejidad computacional Desde el punto de vista terico, un investigador intentando mostrar que la clase P es distinta de la clase NP, pudiera enfocarse en un problema NP-completo. Si algn problema en NP requiere ms que un tiempo polinomial, entonces uno NP-completo tambin. Adems, un investigador intentando demostrar que P=NP, solo necesita encontrar un algoritmo de tiempo polinomial para un problema NP-completo para lograrlo. Desde el punto de vista prctico, el fenmeno de la NP-completitud puede prevenir la prdida de tiempo cuando se busca un algoritmo de tiempo polinomial no existente para resolver un problema determinado. An cuando no se posean los elementos matemticos para demostrar que cierto problema no se puede resolver en tiempo polinomial, creemos que P no es igual a NP, as que demostrar que el problema es NP-completo, es una fuerte evidencia de su no "polinomialidad".

16

Haciendo frente a problemas NP


Teniendo en cuenta la definicin de problema intratable, si no se cumple que P=NP, entonces los problemas NP-completos son intratables. Muchos problemas de la prctica son NP-completos, y son muy importantes como para desistir simplemente porque no sabemos cmo encontrar una solucin ptima en tiempo polinomial. An si un problema es NP-completo, pueden haber esperanzas. Existen tres estrategias fundamentales para lidiar con un problema NP-completo: Si la entrada es pequea, un algoritmo con tiempo de ejecucin exponencial pudiera ser perfectamente aceptable. Se pudieran aislar algunos casos especiales que se pudieran resolver en tiempo polinomial. Podramos utilizar aproximaciones para encontrar soluciones lo suficientemente cercanas al ptimo en tiempo polinomial. En la prctica, obtener soluciones cercanas al ptimo es bastante aceptable. A estos algoritmos se les denomina algoritmos de aproximacin, y en muchos casos se apoyan en heursticas y metaheursticas.

Referencias
[1] Richard M. Karp, "Combinatorics, Complexity, and Randomness", 1985 Turing Award Lecture. [2] Garey, Michael R., Johnson David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, (page 4). [3] Garey, Michael R., Johnson David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, (page 8). [4] Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L. & Stein, Clifford, (2010), Introduction to Algorithms, 3ra edicin, MIT Press and McGraw-Hill, (page 1049). [5] Garey, Michael R., Johnson David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, (page 28). [6] Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L. & Stein, Clifford, (2010), Introduction to Algorithms, 3ra edicin, MIT Press and McGraw-Hill, (page 1067).

Artculos
Cook, Stephen (1983), An overview of computational complexity, Commun. ACM (ACM) 26 (6): 400408, ISSN 0001-0782 (http:/ / worldcat. org/ issn/ 0001-0782) Fortnow, Lance; Homer, Steven (2002), A Short History of Computational Complexity (http://people.cs. uchicago.edu/~fortnow/papers/history.pdf), Bulletin of the EATCS 80: 95133

Libros de texto
Arora, Sanjeev; Barak, Boaz (2009), Computational Complexity: A Modern Approach (http://www.cs. princeton.edu/theory/complexity/), Cambridge, ISBN 978-0-521-42426-4 Sipser, Michael (2006), Introduction to the Theory of Computation (2da edicin), USA: Thomson Course Technology, ISBN 0-534-95097-3

Teora de la complejidad computacional Garey, Michael R.; Johnson, David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, ISBN 0-7167-1045-5. Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L. & Stein, Clifford (2010), Introduction to Algorithms (3ra edicin), Cambridge, MA: MIT Press and McGraw-Hill, ISBN 0-262-03384-4.

17

18

Crecimiento de finciones
Cota superior asinttica
En anlisis de algoritmos una cota superior asinttica es una funcin que sirve de cota superior de otra funcin cuando el argumento tiende a infinito. Usualmente se utiliza la notacin de Landau O(g(x)) (o coloquialmente llamada Notacin O Grande) para referirse a las funciones acotadas superiormente por la funcin g(x). Ms formalmente se define:

Una funcin f(x) pertenece a O(g(x)) cuando existe una constante positiva c tal que a partir de un valor , f(x) no sobrepasa a . Quiere decir que la funcin f es inferior a g a partir de un valor dado salvo por un factor constante. La cota superior asinttica tiene gran importancia en Teora de la complejidad computacional a la hora de definir las clases de complejidad. A pesar de que O(g(x)) est definido como un conjunto, se acostumbra escribir f(x)=O(g(x)) en lugar de f(x)O(g(x)). Muchas veces tambin se habla de una funcin nombrando nicamente su expresin, como en x en lugar de h(x)=x, siempre que est claro cul es el parmetro de la funcin dentro de la expresin. En la grfica se da un ejemplo esquemtico de como se comporta con respecto a f(x) cuando x tiende a infinito. Note adems que dicho conjunto es no vaco pues f(x)=O(g(x)). La cota ajustada asinttica (notacin ) tiene relacin con las cotas asintticas superior e inferior (notacin ):
f(x)=O(g(x)).

Propiedades
Sea i) Si ii) Si iii) iv) Si v) Si vi) Si y entonces , entonces , sean y y , , entonces ,entonces (aqu es igualdad entre conjuntos) ,entonces (aqu es igualdad entre conjuntos) . , , funciones y un real. Entonces los siguientes enunciados son ciertos

Cota superior asinttica

19

Ejemplos
La funcin x+10 puede ser acotada superiormente por la funcin 11x. Para demostrarlo basta notar que para todo valor de x1 se cumple x+1011x. Por tanto x+10 = O(x). Sin embargo, x no sirve como cota inferior para x+10, es decir, . Observacin: Este ejemplo muestra que el uso del smbolo "=" esta mal empleado (matemticamente) pues la notacin de Landau (O grande) no es reflexiva. La funcin 200x est acotada superiormente por x. Quiere decir que cuando x tiende a infinito el valor de 200x se puede despreciar con respecto al de x.

rdenes usuales para funciones


Los rdenes ms utilizados en anlisis de algoritmos, en orden creciente, son los siguientes (donde c representa una constante y n el tamao de la entrada):
notacin O(1) orden constante nombre

O(log log n) orden sublogartmico O(log n) O( O(n) O(n log n) O(nc) ) orden logartmico orden sublineal orden lineal orden lineal logartmico orden potencial

O(cn), n > 1 orden exponencial O(n!) O(nn) orden factorial orden potencial exponencial[citarequerida]

Bibliografa
Introduction to Algorithms, Second Edition by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein

Cota inferior asinttica

20

Cota inferior asinttica


En anlisis de algoritmos una cota inferior asinttica es una funcin que sirve de cota inferior de otra funcin cuando el argumento tiende a infinito. Usualmente se utiliza la notacin (g(x)) para referirse a las funciones acotadas inferiormente por la funcin g(x). Ms formalmente se define:

Una funcin f(x) pertenece a (g(x)) cuando existe una constante positiva c tal que a partir de un valor

no supera f(x). Quiere decir que la funcin f es superior a g a partir de un valor dado salvo por un factor constante. La cota inferior asinttica tiene utilidad en Teora de la complejidad computacional a la hora de calcular la complejidad del mejor caso para los algoritmos. A pesar de que (g(x)) est definido como un conjunto, se acostumbra escribir f(x)=(g(x)) en lugar de f(x) (g(x)). Muchas veces tambin se habla de una funcin nombrando nicamente su expresin, como en x en lugar de h(x)=x, siempre que est claro cual es el parmetro de la funcin dentro de la expresin. En la grfica se da un ejemplo esquemtico de como se comporta con respecto a f(x) cuando x tiende a infinito. La cota ajustada asinttica (notacin ) tiene relacin con las cotas superior (notacin O) e inferior asintticas :

f(x)=(g(x)).

Ejemplos
La funcin x puede ser acotada inferiormente por la funcin x. Para demostrarlo basta notar que para todo valor de x1 se cumple xx. Por tanto x = (x) (sin embargo, x no sirve como cota superior para x). La funcin x+200x est acotada inferiormente por x. Quiere decir que cuando x tiende a infinito el valor de 200x se puede despreciar con respecto al de x.

Bibliografa
Introduction to Algorithms, Second Edition by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein

Cota ajustada asinttica

21

Cota ajustada asinttica


En anlisis de algoritmos una cota ajustada asinttica es una funcin que sirve de cota tanto superior como inferior de otra funcin cuando el argumento tiende a infinito. Usualmente se utiliza la notacin (g(x)) para referirse a las funciones acotadas por la funcin g(x). Ms formalmente se define:

Una funcin f(x) pertenece a (g(x)) cuando existen constantes positivas y tales que a partir de un valor f(x) se encuentra atrapada entre y . Quiere decir que las funciones f y g son iguales a partir de un valor dado salvo por una factor constante. Por tanto tiene sentido tomar a g como un representante de f. A pesar de que (g(x)) est definido como un conjunto, se acostumbra escribir f(x)=(g(x)) en lugar de f(x)(g(x)). Muchas veces tambin se habla de la funcin x en lugar de h(x)=x siempre que est claro cual es el parmetro de la funcin dentro de la expresin. En la grfica se da un ejemplo esquemtico de cmo se comportan y con respecto a f(x) cuando x tiende a infinito.

f(x)=(g(x)).

La cota ajustada asinttica tiene relacin con las cotas superior e inferior asintticas (respectivamente las notaciones O y ):

Ejemplos
La funcin f(x) = x+10 puede ser acotada por la funcin g(x) = x. Para demostrarlo basta notar que para todo valor de x1 se cumple que g(x)f(x)11g(x), es decir x x+10 11x . Por lo tanto x+10 = (x).

Bibliografa
Introduction to Algorithms, Second Edition by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein

22

Ordenamiento
Algoritmo de ordenamiento
En computacin y matemticas un algoritmo de ordenamiento es un algoritmo que pone elementos de una lista o un vector en una secuencia dada por una relacin de orden, es decir, el resultado de salida ha de ser una permutacin o reordenamiento de la entrada que satisfaga la relacin de orden dada. Las relaciones de orden ms usadas son el orden numrico y el orden lexicogrfico. Ordenamientos eficientes son importantes para optimizar el uso de otros algoritmos (como los de bsqueda y fusin) que requieren listas ordenadas para una ejecucin rpida. Tambin es til para poner datos en forma cannica y para generar resultados legibles por humanos.

Quicksort en accin sobre una lista de nmeros aleatorios. Las lneas horizontales son valores pivote.

Desde los comienzos de la computacin, el problema del ordenamiento ha atrado gran cantidad de investigacin, tal vez debido a la complejidad de resolverlo eficientemente a pesar de su planteamiento simple y familiar. Por ejemplo, BubbleSort fue analizado desde 1956.[1] Aunque muchos puedan considerarlo un problema resuelto, nuevos y tiles algoritmos de ordenamiento se siguen inventado hasta el da de hoy (por ejemplo, el ordenamiento de biblioteca se public por primera vez en el 2004). Los algoritmos de ordenamiento son comunes en las clases introductorias a la computacin, donde la abundancia de algoritmos para el problema proporciona una gentil introduccin a la variedad de conceptos ncleo de los algoritmos, como notacin de O mayscula, algoritmos divide y vencers, estructuras de datos, anlisis de los casos peor, mejor, y promedio, y lmites inferiores.

Clasificacin
Los algoritmos de ordenamiento se pueden clasificar de las siguientes maneras: La ms comn es clasificar segn el lugar donde se realice la ordenacin Algoritmos de ordenamiento interno: en la memoria del ordenador. Algoritmos de ordenamiento externo: en un lugar externo como un disco duro. Por el tiempo que tardan en realizar la ordenacin, dadas entradas ya ordenadas o inversamente ordenadas: Algoritmos de ordenacin natural: Tarda lo mnimo posible cuando la entrada est ordenada. Algoritmos de ordenacin no natural: Tarda lo mnimo posible cuando la entrada est inversamente ordenada. Por estabilidad: un ordenamiento estable mantiene el orden relativo que tenan originalmente los elementos con claves iguales. Por ejemplo, si una lista ordenada por fecha se reordena en orden alfabtico con un algoritmo estable, todos los elementos cuya clave alfabtica sea la misma quedarn en orden de fecha. Otro caso sera cuando no interesan las maysculas y minsculas, pero se quiere que si una clave aBC estaba antes que AbC, en el resultado ambas claves aparezcan juntas y en el orden original: aBC, AbC. Cuando los elementos son

Algoritmo de ordenamiento indistinguibles (porque cada elemento se ordena por la clave completa) la estabilidad no interesa. Los algoritmos de ordenamiento que no son estables se pueden implementar para que s lo sean. Una manera de hacer esto es modificar artificialmente la clave de ordenamiento de modo que la posicin original en la lista participe del ordenamiento en caso de coincidencia. Los algoritmos se distinguen por las siguientes caractersticas: Complejidad computacional (peor caso, caso promedio y mejor caso) en trminos de n, el tamao de la lista o arreglo. Para esto se usa el concepto de orden de una funcin y se usa la notacin O(n). El mejor comportamiento para ordenar (si no se aprovecha la estructura de las claves) es O(n log n). Los algoritmos ms simples son cuadrticos, es decir O(n). Los algoritmos que aprovechan la estructura de las claves de ordenamiento (p. ej. bucket sort) pueden ordenar en O(kn) donde k es el tamao del espacio de claves. Como dicho tamao es conocido a priori, se puede decir que estos algoritmos tienen un desempeo lineal, es decir O(n). Uso de memoria y otros recursos computacionales. Tambin se usa la notacin O(n).

23

Estabilidad
Los algoritmos de ordenamiento estable mantienen un relativo preorden total. Esto significa que un algoritmo es estable solo cuando hay dos registros R y S con la misma clave y con R apareciendo antes que S en la lista original. Cuando elementos iguales (indistinguibles entre s), como nmeros enteros, o ms generalmente, cualquier tipo de dato en donde el elemento entero es la clave, la estabilidad no es un problema. De todas formas, se asume que los siguientes pares de nmeros estn por ser ordenados por su primer componente: (4, 1) (3, 7) (3, 1) (5, 6)

En este caso, dos resultados diferentes son posibles, uno de los cuales mantiene un orden relativo de registros con claves iguales, y una en la que no: (3, 7) (3, 1) (3, 1) (3, 7) (4, 1) (4, 1) (5, 6) (5, 6) (orden mantenido) (orden cambiado)

Los algoritmos de ordenamiento inestable pueden cambiar el orden relativo de registros con claves iguales, pero los algoritmos estables nunca lo hacen. Los algoritmos inestables pueden ser implementados especialmente para ser estables. Una forma de hacerlo es extender artificialmente el cotejamiento de claves, para que las comparaciones entre dos objetos con claves iguales sean decididas usando el orden de las entradas original. Recordar este orden entre dos objetos con claves iguales es una solucin poco prctica, ya que generalmente acarrea tener almacenamiento adicional. Ordenar segn una clave primaria, secundaria, terciara, etc., puede ser realizado utilizando cualquier mtodo de ordenamiento, tomando todas las claves en consideracin (en otras palabras, usando una sola clave compuesta). Si un mtodo de ordenamiento es estable, es posible ordenar mltiples tems, cada vez con una clave distinta. En este caso, las claves necesitan estar aplicadas en orden de aumentar la prioridad. Ejemplo: ordenar pares de nmeros, usando ambos valores (4, 1) (4, 1) (3, 1) (3, 7) (3, 1) (3, 7) (3, 1) (4, 6) (4, 1) (4, 6) (original) (3, 7) (despus de ser ordenado por el segundo valor) (4, 6) (despus de ser ordenado por el primer valor)

Por otro lado: (3, 7) (3, 1) (3, 1) (4, 1) (4, 1) (4, 6) (4, 6) (despus de ser ordenado por el primer valor) (3, 7) (despus de ser ordenando por el segundo valor, el orden por el primer valor es perturbado)

Algoritmo de ordenamiento

24

Lista de algoritmos de ordenamiento


Algunos algoritmos de ordenamiento agrupados segn estabilidad tomando en cuenta la complejidad computacional.
Estables Nombre traducido Ordenamiento de burbuja Nombre original Bubblesort Complejidad O(n) O(n) O(n) O(n) O(n) O(n+k) O(n log n) O(n log n) O(n+k) O(nk) O(n) versin recursiva O(n) Inestables Nombre traducido Ordenamiento Shell Nombre original Shell sort Comb sort Ordenamiento por seleccin Ordenamiento por montculos Selection sort Heapsort Smoothsort Ordenamiento rpido Quicksort Complejidad O(n1.25) O(n log n) O(n) O(n log n) O(n log n) Promedio: O(n log n), peor caso: O(n) Memoria Mtodo O(1) O(1) O(1) O(1) O(1) O(log n) Insercin Intercambio Seleccin Seleccin Seleccin Particin Memoria Mtodo O(1) O(1) O(1) O(1) O(n) O(n+k) O(n) O(n) O(k) O(n) O(n) No comparativo Intercambio Intercambio Intercambio Insercin No comparativo No comparativo Mezcla Insercin

Ordenamiento de burbuja bidireccional Cocktail sort Ordenamiento por seleccin Ordenamiento por insercin Ordenamiento por casilleros Ordenamiento por cuentas Ordenamiento por mezcla Ordenamiento con rbol binario Selection Sort Insertion sort Bucket sort Counting sort Merge sort Binary tree sort Pigeonhole sort Ordenamiento Radix Radix sort Distribution sort Gnome sort

Several Unique Sort Promedio: O(n u), peor caso: O(n); u=n; u = nmero nico de registros Cuestionables, imprcticos Nombre traducido Nombre original Bogosort Pancake sorting Complejidad O(n n!), peor: no termina O(n), excepto en mquinas de Von Neumann Promedio: O(n!) Peor: No termina Memoria Mtodo

Randomsort

Algoritmo de ordenamiento

25

Referencias
[1] Bubble Sort: An archaeological algorithm analysis (http:/ / www. cs. duke. edu/ ~ola/ papers/ bubble. pdf). Owen Astrachan

Enlaces externos
Explicacin de los distintos mtodos de ordenamiento en Java. (http://blog.zerial.org/ficheros/ Informe_Ordenamiento.pdf) (pdf) Discusin sobre varios algoritmos de ordenacin y sus caractersticas (http://es.tldp.org/Tutoriales/ doc-programacion-algoritmos-ordenacion/alg_orden.pdf) (licencia GFDL) (pdf) Animacin de algoritmos de ordenamiento (http://web.archive.org/web/http://dvegaf.iespana.es/) Animacin de algoritmos de ordenamiento (en ingls) (http://web.archive.org/web/http://vision.bc.edu/ ~dmartin/teaching/sorting/anim-html/all.html) ALT: Algorithm Learning Tool. Herramienta de apoyo a la enseanza de algoritmos que muestra grficamente su funcionamiento. Permite implementar algoritmos propios y realizar una ejecucin dinmica e interactiva (http:// xistral.ei.uvigo.es/MTPAlgoritmos/index.php?action=VisualizarAlgoritmos&tipo=Ordenacion) Cdigos de Ordenamiento en Python (http://tutorial-python.com.ar)

Heapsort
El ordenamiento por montculos (heapsort en ingls) es un algoritmo de ordenamiento no recursivo, no estable, con complejidad computacional Este algoritmo consiste en almacenar todos los elementos del vector a ordenar en un montculo (heap), y luego extraer el nodo que queda como nodo raz del montculo (cima) en sucesivas iteraciones obteniendo el conjunto ordenado. Basa su funcionamiento en una propiedad de los montculos, por la cual, la cima contiene siempre el menor elemento (o el mayor, segn se haya definido el montculo) de Animacin mostrando el funcionamiento del heapsort. todos los almacenados en l. El algoritmo, despus de cada extraccin, recoloca en el nodo raz o cima, la ltima hoja por la derecha del ltimo nivel. Lo cual destruye la propiedad heap del rbol. Pero, a continuacin realiza un proceso de "descenso" del nmero insertado de forma que se elige a cada movimiento el mayor de sus dos hijos, con el que se intercambia. Este intercambio, realizado sucesivamente "hunde" el nodo en el rbol restaurando la propiedad montculo del arbol y dejndo paso a la siguiente extraccin del nodo raz. El algoritmo, en su implementacin habitual, tiene dos fases. Primero una fase de construccin de un montculo a partir del conjunto de elmentos de entrada, y despus, una fase de extraccin sucesiva de la cima del montculo. La implementacin del almacn de datos en el heap, pese a ser conceptualmente un rbol, puede realizarse en un vector de forma fcil. Cada nodo tiene dos hijos y por tanto, un nodo situado en la posicin i del vector, tendr a sus hijos en las posiciones 2 x i, y 2 x i +1 suponiendo que el primer elemento del vector tiene un ndice = 1. Es decir, la cima ocupa la posicin inicial del vector y sus dos hijos la posicin segunda y tercera, y as, sucesivamente. Por tanto, en

Heapsort la fase de ordenacin, el intercambio ocurre entre el primer elemento del vector (la raz o cima del rbol, que es el mayor elemento del mismo) y el ltimo elemento del vector que es la hoja ms a la derecha en el ltimo nivel. El rbol pierde una hoja y por tanto reduce su tamao en un elemento. El vector definitivo y ordenado, empieza a construirse por el final y termina por el principio.

26

Descripcin
He aqu una descripcin en pseudocdigo del algoritmo. Se pueden encontrar descripciones de las operaciones insertar_en_monticulo y extraer_cima_del_monticulo en el artculo sobre montculos. function heapsort(array A[0..n]): montculo M integer i := 124578 for i = 0..n: insertar_en_monticulo(M, A[i]) for i = 0..n: A[i] = extraer_cima_del_monticulo(M) return A

Enlaces externos
Distintas implementaciones del algoritmo en RosettaCode.org [1]

Referencias
[1] http:/ / rosettacode. org/ wiki/ Sorting_algorithms/ Heapsort

Quicksort

27

Quicksort
El ordenamiento rpido (quicksort en ingls) es un algoritmo creado por el cientfico britnico en computacin C. A. R. Hoare basado en la tcnica de divide y vencers, que permite, en promedio, ordenar n elementos en un tiempo proporcional a n log n.

Descripcin del algoritmo


El algoritmo trabaja de la siguiente forma: Elegir un elemento de la lista de elementos a ordenar, al que llamaremos pivote. Resituar los dems elementos de la lista a cada lado del pivote, de manera que a un lado Quicksort en accin sobre una lista de nmeros aleatorios. Las lneas horizontales son valores pivote. queden todos los menores que l, y al otro los mayores. Los elementos iguales al pivote pueden ser colocados tanto a su derecha como a su izquierda, dependiendo de la implementacin deseada. En este momento, el pivote ocupa exactamente el lugar que le corresponder en la lista ordenada. La lista queda separada en dos sublistas, una formada por los elementos a la izquierda del pivote, y otra por los elementos a su derecha. Repetir este proceso de forma recursiva para cada sublista mientras stas contengan ms de un elemento. Una vez terminado este proceso todos los elementos estarn ordenados. Como se puede suponer, la eficiencia del algoritmo depende de la posicin en la que termine el pivote elegido. En el mejor caso, el pivote termina en el centro de la lista, dividindola en dos sublistas de igual tamao. En este caso, el orden de complejidad del algoritmo es O(nlog n). En el peor caso, el pivote termina en un extremo de la lista. El orden de complejidad del algoritmo es entonces de O(n). El peor caso depender de la implementacin del algoritmo, aunque habitualmente ocurre en listas que se encuentran ordenadas, o casi ordenadas. Pero principalmente depende del pivote, si por ejemplo el algoritmo implementado toma como pivote siempre el primer elemento del array, y el array que le pasamos est ordenado, siempre va a generar a su izquierda un array vaco, lo que es ineficiente. En el caso promedio, el orden es O(nlog n). No es extrao, pues, que la mayora de optimizaciones que se aplican al algoritmo se centren en la eleccin del pivote.

Demostracin de un caso particular


Supongamos que el nmero de elementos a ordenar es una potencia de dos, es decir, Inmediatamente para algn natural . , donde k es el nmero de divisiones que realizar el algoritmo.

En la primera fase del algoritmo habr n comparaciones. En la segunda fase el algoritmo instanciar dos sublistas de tamao aproximadamente n/2. El nmero total de comparaciones de estas dos sublistas es: 2(n/2) = n. En la tercera fase el algoritmo procesar 4 sublistas ms, por tanto el nmero total de comparaciones en esta fase es 4(n/4) = n. En conclusin, el nmero total de comparaciones que hace el algoritmo es: , donde caso es . , por tanto el tiempo de ejecucin del algoritmo en el mejor

Quicksort

28

Tcnicas de eleccin del pivote


El algoritmo bsico del mtodo Quicksort consiste en tomar cualquier elemento de la lista al cual denominaremos como pivote, dependiendo de la particin en que se elija, el algoritmo ser ms o menos eficiente. Tomar un elemento cualquiera como pivote tiene la ventaja de no requerir ningn clculo adicional, lo cual lo hace bastante rpido. Sin embargo, esta eleccin a ciegas siempre provoca que el algoritmo tenga un orden de O(n) para ciertas permutaciones de los elementos en la lista. Otra opcin puede ser recorrer la lista para saber de antemano qu elemento ocupar la posicin central de la lista, para elegirlo como pivote. Esto puede hacerse en O(n) y asegura que hasta en el peor de los casos, el algoritmo sea O(nlog n). No obstante, el clculo adicional rebaja bastante la eficiencia del algoritmo en el caso promedio. La opcin a medio camino es tomar tres elementos de la lista - por ejemplo, el primero, el segundo, y el ltimo - y compararlos, eligiendo el valor del medio como pivote.

Tcnicas de reposicionamiento
Una idea preliminar para ubicar el pivote en su posicin final sera contar la cantidad de elementos menores que l, y colocarlo un lugar ms arriba, moviendo luego todos esos elementos menores que l a su izquierda, para que pueda aplicarse la recursividad. Existe, no obstante, un procedimiento mucho ms efectivo. Se utilizan dos ndices: i, al que llamaremos ndice izquierdo, y j, al que llamaremos ndice derecho. El algoritmo es el siguiente: Recorrer la lista simultneamente con i y j: por la izquierda con i (desde el primer elemento), y por la derecha con j (desde el ltimo elemento). Cuando lista[i] sea mayor que el pivote y lista[j] sea menor, se intercambian los elementos en esas posiciones. Repetir esto hasta que se crucen los ndices. El punto en que se cruzan los ndices es la posicin adecuada para colocar el pivote, porque sabemos que a un lado los elementos son todos menores y al otro son todos mayores (o habran sido intercambiados).

Transicin a otro algoritmo


Como se mencion anteriormente, el algoritmo quicksort ofrece un orden de ejecucin O(n) para ciertas permutaciones "crticas" de los elementos de la lista, que siempre surgen cuando se elige el pivote a ciegas. La permutacin concreta depende del pivote elegido, pero suele corresponder a secuencias ordenadas. Se tiene que la probabilidad de encontrarse con una de estas secuencias es inversamente proporcional a su tamao. Los ltimos pases de quicksort son numerosos y ordenan cantidades pequea de elementos. Un porcentaje medianamente alto de ellos estarn dispuestos de una manera similar al peor caso del algoritmo, volviendo a ste ineficiente. Una solucin a este problema consiste en ordenar las secuencias pequeas usando otro algoritmo. Habitualmente se aplica el algoritmo de insercin para secuencias de tamao menores de 8-15 elementos. Pese a que en secuencias largas de elementos la probabilidad de hallarse con una configuracin de elementos "crtica" es muy baja, esto no evita que sigan apareciendo (a veces, de manera intencionada). El algoritmo introsort es una extensin del algoritmo quicksort que resuelve este problema utilizando heapsort en vez de quicksort cuando el nmero de recursiones excede al esperado. Nota: Los tres parmetros de la llamada inicial a Quicksort sern array[0], 0, numero_elementos -1, es decir, si es un array de 6 elementos array, 0, 5

Quicksort

29

Ejemplo
En el siguiente ejemplo se marcan el pivote y los ndices i y j con las letras p, i y j respectivamente. Comenzamos con la lista completa. El elemento pivote ser el 4: 5 - 3 - 7 - 6 - 2 - 1 - 4 p Comparamos con el 5 por la izquierda y el 1 por la derecha. 5 - 3 - 7 - 6 - 2 - 1 - 4 i j p 5 es mayor que 4 y 1 es menor. Intercambiamos: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p Avanzamos por la izquierda y la derecha: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ah. 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 7 es mayor que 4 y 2 es menor: intercambiamos. 1 - 3 - 2 - 6 - 7 - 5 - 4 i j p Avanzamos por ambos lados: 1 - 3 - 2 - 6 - 7 - 5 - 4 iyj p En este momento termina el ciclo principal, porque los ndices se cruzaron. Ahora intercambiamos lista[i] con lista[sup] (pasos 16-18): 1 - 3 - 2 - 4 - 7 - 5 - 6 p Aplicamos recursivamente a la sublista de la izquierda (ndices 0 - 2). Tenemos lo siguiente: 1 - 3 - 2 1 es menor que 2: avanzamos por la izquierda. 3 es mayor: avanzamos por la derecha. Como se intercambiaron los ndices termina el ciclo. Se intercambia lista[i] con lista[sup]: 1 - 2 - 3 El mismo procedimiento se aplicar a la otra sublista. Al finalizar y unir todas las sublistas queda la lista inicial ordenada en forma ascendente. 1 - 2 - 3 - 4 - 5 - 6 - 7

Quicksort

30

Enlaces externos
Distintas implementaciones del algoritmo en RosettaCode.org [1]

Referencias
[1] http:/ / rosettacode. org/ wiki/ Sorting_algorithms/ Quicksort

31

Estructuras de datos
Estructura de datos
En programacin, una estructura de datos es una forma de organizar un conjunto de datos elementales con el objetivo de facilitar su manipulacin. Un dato elemental es la mnima informacin que se tiene en un sistema. Una estructura de datos define la organizacin e interrelacin de estos y un conjunto de operaciones que se pueden realizar sobre ellos. Las operaciones bsicas son: Alta, adicionar un nuevo valor a la estructura. Baja, borrar un valor de la estructura. Bsqueda, encontrar un determinado valor en la estructura para realizar una operacin con este valor, en forma secuencial o binario (siempre y cuando los datos estn ordenados). Otras operaciones que se pueden realizar son: Ordenamiento, de los elementos pertenecientes a la estructura. Apareo, dadas dos estructuras originar una nueva ordenada y que contenga a las apareadas. Cada estructura ofrece ventajas y desventajas en relacin a la simplicidad y eficiencia para la realizacin de cada operacin. De esta forma, la eleccin de la estructura de datos apropiada para cada problema depende de factores como la frecuencia y el orden en que se realiza cada operacin sobre los datos.

Estructuras de datos
Conjuntos (set) Matriz (matemticas) Matriz (programacin) Lista Lista simple Lista doblemente enlazada Lista circular Listas por saltos (Skip lists)

rboles rboles Binarios rbol binario de bsqueda rbol binario de bsqueda equilibrado rboles rojo-negro rboles AVL rboles biselados (rboles splay) rboles multicamino (Multirrama) rboles B rboles B+ rboles B* Tries Grafos

Estructura de datos Tablas Hash Mapeos Diccionarios Montculos (o heaps) Montculo binario Montculo binmico Montculo de Fibonacci Montculo suave Montculo 2-3

32

Pila (informtica)
Una pila (stack en ingls) es una lista ordenada o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO (del ingls Last In First Out, ltimo en entrar, primero en salir) que permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el rea de informtica debido a su simplicidad y ordenacin implcita de la propia estructura. Para el manejo de los datos se cuenta con dos operaciones bsicas: apilar (push), que coloca un objeto en la pila, y su operacin inversa, retirar (o desapilar, pop), que retira el ltimo elemento apilado.

Representacin simplificada de una pila

En cada momento slo se tiene acceso a la parte superior de la pila, es decir, al ltimo objeto apilado (denominado TOS, Top of Stack en ingls). La operacin retirar permite la obtencin de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con anterioridad), que pasa a ser el nuevo TOS. Por analoga con objetos cotidianos, una operacin apilar equivaldra a colocar un plato sobre una pila de platos, y una operacin retirar a retirarlo. Las pilas suelen emplearse en los siguientes contextos: Evaluacin de expresiones en notacin postfija (notacin polaca inversa). Reconocedores sintcticos de lenguajes independientes del contexto Implementacin de recursividad.

Historia
El mtodo de pila para la evaluacin de expresiones fue propuesto en 1955 y dos aos despus patentado por Friedrich L. Bauer, quin recibi en 1988 el premio "IEEE Computer Society Pioneer Award" por su trabajo en el desarrollo de dicha estructura de datos.

Pila como tipo abstracto de datos


A modo de resumen tipo de datos, la pila es un contenedor de nodos y tiene dos operaciones bsicas: push (o apilar) y pop (o desapilar). 'Push' aade un nodo a la parte superior de la pila, dejando por debajo el resto de los nodos. 'Pop' elimina y devuelve el actual nodo superior de la pila. Una metfora que se utiliza con frecuencia es la idea de una pila de platos en una cafetera con muelle de pila. En esa serie, slo la primera placa es visible y accesible para el

Pila (informtica) usuario, todas las dems placas permanecen ocultas. Como se aaden las nuevas placas, cada nueva placa se convierte en la parte superior de la pila, escondidos debajo de cada plato, empujando a la pila de placas. A medida que la placa superior se elimina de la pila, la segunda placa se convierte en la parte superior de la pila. Dos principios importantes son ilustrados por esta metfora: En primer lugar la ltima salida es un principio, la segunda es que el contenido de la pila est oculto. Slo la placa de la parte superior es visible, por lo que para ver lo que hay en la tercera placa, el primer y segundo platos tendrn que ser retirados.

33

Operaciones
Una pila cuenta con 2 operaciones imprescindibles: apilar y desapilar, a las que en las implementaciones modernas de las pilas se suelen aadir ms de uso habitual. Crear: se crea la pila vaca. (constructor) Tamao: regresa el nmero de elementos de la pila. (size) Apilar: se aade un elemento a la pila.(push) Desapilar: se elimina el elemento frontal de la pila.(pop) Cima: devuelve el elemento que esta en la cima de la pila. (top o peek) Vaca: devuelve cierto si la pila est vaca o falso en caso contrario (empty).

Implementacin
Un requisito tpico de almacenamiento de una pila de n elementos es O(n). El requisito tpico de tiempo de O(1) las operaciones tambin son fciles de satisfacer con un array o con listas enlazadas simples. La biblioteca de plantillas de C++ estndar proporciona una "pila" clase templated que se limita a slo apilar/desapilar operaciones. Java contiene una biblioteca de la clase Pila que es una especializacin de Vector. Esto podra ser considerado como un defecto, porque el diseo heredado get () de Vector mtodo LIFO ignora la limitacin de la Pila. Estos son ejemplos sencillos de una pila con las operaciones descritas anteriormente (pero no hay comprobacin de errores). Implementacin en Python class Stack(object): def __init__(self): self.stack_pointer = None def push(self, element): self.stack_pointer = Node(element, self.stack_pointer) def pop(self): e = self.stack_pointer.element self.stack_pointer = self.stack_pointer.next return e def peek(self): return self.stack_pointer.element def __len__(self): i = 0 sp = self.stack_pointer

Pila (informtica) while sp: i += 1 sp = sp.next return i class Node(object): def __init__(self, element=None, next=None): self.element = element self.next = next if __name__ == '__main__': # small use example s = Stack() for i in range(10):s.push(i) for i in range(len(s)):print(s.pop()) Implementacin en Maude La PilaNV es la pila no vaca, que diferenciamos de la pila normal a la hora de tomar en cuenta errores. El elemento X representa el tipo de valor que puede contener la pila: entero, carcter, registro, etc. fmod PILA-GENRICA {X :: TRIV} is sorts Pila{X} PilaNV{X}. subsorts PilaNV{X} < Pila{X}. ***generadores: op crear: -> Pila {X} [ctor]. op apilar : X$Elt Pila{X} -> PilaNV{X} [ctor]. ***constructores op desapilar : Pila{X} -> Pila{X}. ***selectores op cima : PilaNV{X} -> X$Elt. ***variables var P : Pila{X}. var E : X$Elt. ***ecuaciones eq desapilar (crear) = crear. eq desapilar(apilar(E, P)) = P. eq cima(apilar(E, P)) = E. endfm

34

Pila (informtica) Implementacin en Visual Basic Public Class Stack Private p_index As Integer Private list As New ArrayList Public Sub New() p_index = -1 End Sub ReadOnly Property count Get Return list.Count End Get End Property Public Sub push(ByVal value As Object) list.Add(value) p_index += 1 End Sub Public Function pop() As Object Dim obj As Object = list.Item(p_index) list.RemoveAt(p_index) p_index -= 1 Return obj End Function Public Sub clear() list.Clear() p_index = -1 End Sub Public Function peek() As Object Return list.Item(p_index) End Function End Class En C++ #ifndef PILA #define PILA // define la pila

35

template <class T> class Pila { private:

Pila (informtica) struct Nodo { T elemento; Nodo* siguiente; // coloca el nodo en la segunda posicion }* ultimo; unsigned int elementos; public: Pila() { elementos = 0; } ~Pila() { while (elementos != 0) pop(); } void push(const T& elem) { Nodo* aux = new Nodo; aux->elemento = elem; aux->siguiente = ultimo; ultimo = aux; ++elementos; } void pop() { Nodo* aux = ultimo; ultimo = ultimo->siguiente; delete aux; --elementos; } T cima() const { return ultimo->elemento; } bool vacia() const { return elementos == 0; } unsigned int altura() const { return elementos; } };

36

#endif

Pila (informtica) Implementacin en Java public class Nodo<tipo> { public tipo dato; private Nodo<tipo> siguiente; public Nodo(tipo Dato) { dato = Dato; siguiente = null; } public void conectar(Nodo<tipo> elSiguiente) { siguiente = elSiguiente; } public Nodo<tipo> getSiguiente() { return siguiente; } } public class Pila<tipo> { Nodo<tipo> cima; public Pila() { cima = null; } public int tamano() { Nodo<tipo> lectorAuxiliar = cima; int contadorDeDatos = 0; while (lectorAuxiliar != null) { contadorDeDatos++; lectorAuxiliar = lectorAuxiliar.getSiguiente(); } return contadorDeDatos; } public void apilar(tipo datoNuevo) { Nodo<tipo> nuevo = new Nodo<tipo>(datoNuevo); nuevo.conectar(cima); cima = nuevo; } public tipo desapilar() { tipo dato = cima.dato; cima = cima.getSiguiente(); return dato; }

37

Pila (informtica) public tipo getCima() { return cima.dato; } public boolean estaVacia() { return cima == null; } public String toString() { Nodo<tipo> lectorAuxiliar = cima; String respuesta = "IN/OUT <->"; while (lectorAuxiliar != null) { respuesta += " [" + lectorAuxiliar.dato.toString() + "] "; lectorAuxiliar = lectorAuxiliar.getSiguiente(); } return respuesta; } }

38

Estructuras de datos relacionadas


El tipo base de la estructura FIFO (el primero en entrar es el primero en salir)es la cola, y la combinacin de las operaciones de la pila y la cola es proporcionado por el deque. Por ejemplo, el cambio de una pila en una cola en un algoritmo de bsqueda puede cambiar el algoritmo de bsqueda en primera profundidad (en ingls, DFS) por una bsqueda en amplitud (en ingls, BFS). Una pila acotada es una pila limitada a un tamao mximo impuesto en su especificacin.

Pilas Hardware
Un uso muy comn de las pilas a nivel de arquitectura hardware es la asignacin de memoria.

Arquitectura bsica de una pila


Una pila tpica es un rea de la memoria de los computadores con un origen fijo y un tamao variable. Al principio, el tamao de la pila es cero. Un puntero de pila, por lo general en forma de un registro de hardware, apunta a la ms reciente localizacin en la pila; cuando la pila tiene un tamao de cero, el puntero de pila de puntos en el origen de la pila. Las dos operaciones aplicables a todas las pilas son: Una operacin apilar, en el que un elemento de datos se coloca en el lugar apuntado por el puntero de pila, y la direccin en el puntero de pila se ajusta por el tamao de los datos de partida. Una operacin desapilar: un elemento de datos en la ubicacin actual apuntado por el puntero de pila es eliminado, y el puntero de pila se ajusta por el tamao de los datos de partida. Hay muchas variaciones en el principio bsico de las operaciones de pila. Cada pila tiene un lugar fijo en la memoria en la que comienza. Como los datos se aadirn a la pila, el puntero de pila es desplazado para indicar el estado actual de la pila, que se expande lejos del origen (ya sea hacia arriba o hacia abajo, dependiendo de la aplicacin concreta).

Pila (informtica) Por ejemplo, una pila puede comenzar en una posicin de la memoria de mil, y ampliar por debajo de las direcciones, en cuyo caso, los nuevos datos se almacenan en lugares que van por debajo de 1000, y el puntero de pila se decrementa cada vez que un nuevo elemento se agrega. Cuando un tema es eliminado de la pila, el puntero de pila se incrementa. Los punteros de pila pueden apuntar al origen de una pila o de un nmero limitado de direcciones, ya sea por encima o por debajo del origen (dependiendo de la direccin en que crece la pila), sin embargo el puntero de pila no puede cruzar el origen de la pila. En otras palabras, si el origen de la pila est en la direccin 1000 y la pila crece hacia abajo (hacia las direcciones 999, 998, y as sucesivamente), el puntero de pila nunca debe ser incrementado ms all de 1000 (para 1001, 1002, etc.) Si un desapilar operacin en la pila hace que el puntero de pila se deje atrs el origen de la pila, una pila se produce desbordamiento. Si una operacin de apilar hace que el puntero de pila incremente o decremente ms all del mximo de la pila, en una pila se produce desbordamiento. La pila es visualizada ya sea creciente de abajo hacia arriba (como pilas del mundo real), o, con el mximo elemento de la pila en una posicin fija, o creciente, de izquierda a derecha, por lo que el mximo elemento se convierte en el mximo a "la derecha". Esta visualizacin puede ser independiente de la estructura real de la pila en la memoria. Esto significa que rotar a la derecha es mover el primer elemento a la tercera posicin, la segunda a la primera y la tercera a la segunda. Aqu hay dos equivalentes visualizaciones de este proceso: Manzana Pltano Fresa Fresa Pltano Manzana ==rotar a la izquierda==> ==rotar a la derecha==> Pltano Fresa Manzana Manzana Fresa Pltano

39

Una pila es normalmente representada en los ordenadores por un bloque de celdas de memoria, con los "de abajo" en una ubicacin fija, y el puntero de pila de la direccin actual de la "cima" de clulas de la pila. En la parte superior e inferior se utiliza la terminologa con independencia de que la pila crece realmente a la baja de direcciones de memoria o direcciones de memoria hacia mayores. Apilando un elemento en la pila,se ajusta el puntero de pila por el tamao de elementos (ya sea decrementar o incrementar, en funcin de la direccin en que crece la pila en la memoria), que apunta a la prxima celda, y copia el nuevo elemento de la cima en rea de la pila. Dependiendo de nuevo sobre la aplicacin exacta, al final de una operacin de apilar, el puntero de pila puede sealar a la siguiente ubicacin no utilizado en la pila, o tal vez apunte al mximo elemento de la pila. Si la pila apunta al mximo elemento de la pila, el puntero de pila se actualizar antes de que un nuevo elemento se apile, si el puntero que apunta a la prxima ubicacin disponible en la pila, que se actualizar despus de que el mximo elemento se apile en la pila. Desapilando es simplemente la inversa de apilar. El primer elemento de la pila es eliminado y el puntero de pila se actualiza, en el orden opuesto de la utilizada en la operacin de apilar.

Pila (informtica)

40

Soporte de Hardware
Muchas CPUs tienen registros que se pueden utilizar como punteros de pila. Algunos, como el Intel x86, tienen instrucciones especiales que implcitamente el uso de un registro dedicado a la tarea de ser un puntero de pila. Otros, como el DEC PDP-11 y de la familia 68000 de Motorola tienen que hacer frente a los modos de hacer posible la utilizacin de toda una serie de registros como un puntero de pila. La serie Intel 80x87 numrico de coprocessors tiene un conjunto de registros que se puede acceder ya sea como una pila o como una serie de registros numerados. Algunos microcontroladores, por ejemplo algunos PICs, tienen un fondo fijo de pila que no es directamente accesible. Tambin hay una serie de microprocesadores que aplicar una pila directamente en el hardware: Computer vaqueros MuP21 Harris RTX lnea Novix NC4016 Muchas pilas basadas en los microprocesadores se utilizan para aplicar el lenguaje de programacin Forth en el nivel de microcdigo. Pila tambin se utilizaron como base de una serie de mainframes y miniordenadores. Esas mquinas fueron llamados pila de mquinas, el ms famoso es el Burroughs B5000

Soporte de Software
En programas de aplicacin escrito en un lenguaje de alto nivel, una pila puede ser implementada de manera eficiente, ya sea usando vectores o listas enlazadas. En LISP no hay necesidad de aplicar la pila, puesto que las funciones apilar y desapilar estn disponibles para cualquier lista. Adobe PostScript tambin est diseada en torno a una pila que se encuentra directamente visible y manipuladas por el programador. El uso de las pilas est muy presente en el desarrollo de software por ello la importancia de las pilas como tipo abstracto de datos.

Expresin de evaluacin y anlisis sintctico


Se calcula empleando la notacin polaca inversa utilizando una estructura de pila para los posibles valores. Las expresiones pueden ser representadas en prefijo, infijo, postfijo. La conversin de una forma de la expresin a otra forma necesita de una pila. Muchos compiladores utilizan una pila para analizar la sintaxis de las expresiones, bloques de programa, etc. Antes de traducir el cdigo de bajo nivel. La mayora de los lenguajes de programacin son de contexto libre de los idiomas que les permite ser analizados con mquinas basadas en la pila. Por ejemplo, el clculo: ((1 + 2) * 4) + 3, puede ser anotado como en notacin postfija con la ventaja de no prevalecer las normas y los parntesis necesario: 12+4*3+ La expresin es evaluada de izquierda a derecha utilizando una pila: Apilar cuando se enfrentan a un operando y Desafilar dos operandos y evaluar el valor cuando se enfrentan a una operacin. Apilar el resultado. De la siguiente manera (la Pila se muestra despus de que la operacin se haya llevado a cabo): ENTRADA 1 2 + 4 * 3 OPERACIN Apilar operando Apilar operando Aadir Apilar operando Multiplicar Apilar operando PILA 1 1, 2 3 3, 4 12 12, 3

Pila (informtica) + Aadir 15

41

El resultado final, 15, se encuentra en la parte superior de la pila al final del clculo.

Tiempo de ejecucin de la gestin de memoria


Artculo principal: Pila basada en la asignacin de memoria y Pila mquina. Una serie de lenguajes de programacin estn orientadas a la pila, lo que significa que la mayora definen operaciones bsicas (aadir dos nmeros, la impresin de un carcter) cogiendo sus argumentos de la pila, y realizando de nuevo los valores de retorno en la pila. Por ejemplo, PostScript tiene una pila de retorno y un operando de pila, y tambin tiene un montn de grficos estado y un diccionario de pila. Forth utiliza dos pilas, una para pasar argumentos y una subrutina de direcciones de retorno. El uso de una pila de retorno es muy comn, pero el uso poco habitual de un argumento para una pila legible para humanos es el lenguaje de programacin Forth razn que se denomina una pila basada en el idioma. Muchas mquinas virtuales tambin estn orientadas hacia la pila, incluida la p-cdigo mquina y la mquina virtual Java. Casi todos los entornos de computacin de tiempo de ejecucin de memoria utilizan una pila especial PILA para tener informacin sobre la llamada de un procedimiento o funcin y de la anidacin con el fin de cambiar al contexto de la llamada a restaurar cuando la llamada termina. Ellos siguen un protocolo de tiempo de ejecucin entre el que llama y el llamado para guardar los argumentos y el valor de retorno en la pila. Pila es una forma importante de apoyar llamadas anidadas o a funciones recursivas. Este tipo de pila se utiliza implcitamente por el compilador para apoyar CALL y RETURN estados (o sus equivalentes), y no es manipulada directamente por el programador. Algunos lenguajes de programacin utilizar la pila para almacenar datos que son locales a un procedimiento. El espacio para los datos locales se asigna a los temas de la pila cuando el procedimiento se introduce, y son borradas cuando el procedimiento termina. El lenguaje de programacin C es generalmente aplicado de esta manera. Utilizando la misma pila de los datos y llamadas de procedimiento tiene importantes consecuencias para la seguridad (ver ms abajo), de los que un programador debe ser consciente, a fin de evitar la introduccin de graves errores de seguridad en un programa.

Solucionar problemas de bsqueda


La bsqueda de la solucin de un problema, es independientemente de si el enfoque es exhaustivo u ptimo, necesita espacio en la pila. Ejemplos de bsqueda exhaustiva mtodos son fuerza bruta y backtraking. Ejemplos de bsqueda ptima a explorar mtodos,son branch and bound y soluciones heursticas. Todos estos algoritmos utilizan pilas para recordar la bsqueda de nodos que se han observado, pero no explorados an. La nica alternativa al uso de una pila es utilizar la recursividad y dejar que el compilador sea recursivo (pero en este caso el compilador todava est utilizando una pila interna). El uso de pilas es frecuente en muchos problemas, que van desde almacenar la profundidad de los rboles hasta resolver crucigramas o jugar al ajedrez por ordenador. Algunos de estos problemas pueden ser resueltos por otras estructuras de datos como una cola.

Seguridad
La seguridad a la hora de desarrollar software usando estructuras de datos de tipo pila es un factor a tener en cuenta debido a ciertas vulnerabilidad que un uso incorrecto de stas puede originar en la seguridad de nuestro software o en la seguridad del propio sistema que lo ejecuta. Por ejemplo, algunos lenguajes de programacin usan una misma pila para almacenar los datos para un procedimientos y el link que permite retornar a su invocador. Esto significa que el programa introduce y extrae los datos de la misma pila en la que se encuentra informacin crtica con las direcciones de retorno de las llamadas a procedimiento, supongamos que al introducir datos en la pila lo hacemos en una posicin errnea de manera que introducimos una datos de mayor tamao al soportado por la pila corrompiendo as

Pila (informtica) las llamadas a procedimientos provocariamos un fallo en nuestro programa. sta tcnica [1] usada de forma maliciosa (es similar, pero en otro mbito al buffer overflow) permitira a un atacante modificar el funcionamiento normal de nuestro programa y nuestro sistema, y es al menos una tcnica til si no lo evitamos en lenguajes muy populares como el ejemplo C++.

42

Referencias
[1] http:/ / www. cs. ucla. edu/ ~palsberg/ paper/ sas03. pdf

Cola (informtica)
Usos concretos de la cola
La particularidad de una estructura de datos de cola es el hecho de que slo podemos acceder al primer y al ltimo elemento de la estructura. As mismo, los elementos slo se pueden eliminar por el principio y slo se pueden aadir por el final de la cola.

Representacin simplificada de una cola

Ejemplos de colas en la vida real seran: personas comprando en un supermercado, esperando para entrar a ver un partido de bisbol, esperando en el cine para ver una pelcula, una pequea peluquera, etc. La idea esencial es que son todos lneas de espera.

Informacin adicional
En caso de estar vaca, borrar un elemento sera imposible hasta que no se aade un nuevo elemento. A la hora de aadir un elemento podramos darle una mayor importancia a unos elementos que a otros (un cargo VIP) y para ello se crea un tipo de cola especial que es la cola de prioridad. (Ver cola de prioridad).

Cola (informtica)

43

Operaciones Bsicas
Crear: se crea la cola vaca. Encolar (aadir, entrar, insertar): se aade un elemento a la cola. Se aade al final de esta. Desencolar (sacar, salir, eliminar): se elimina el elemento frontal de la cola, es decir, el primer elemento que entr. Frente (consultar, front): se devuelve el elemento frontal de la cola, es decir, el primer elemento que entr.

Implementaciones
Colas en Maude
La ColaNV es la cola no vaca, que diferenciamos de la cola normal a la hora de tomar en cuenta errores. A su vez, el elemento X representa el tipo de valor que puede contener la cola: entero, carcter, registro....
fmod COLA {X :: TRIV} is sorts ColaNV{X} Cola{X} . subsort ColaNV{X} < Cola{X} . *** generadores op crear : -> Cola{X} [ctor] . op encolar : X$Elt Cola{X} -> ColaNV {X} [ctor] . *** constructores op desencolar : Cola{X} -> Cola{X} . *** selectores op frente : ColaNV{X} -> X$Elt . *** variables var C : ColaNV{X} . vars E E2 : X$Elt . *** ecuaciones eq desencolar(crear) = crear . eq desencolar(encolar(E, crear)) = crear . eq desencolar(encolar(E, C)) = encolar(E, desencolar(C)) . eq frente(encolar(E, crear)) = E . eq frente(encolar(E, C)) = frente(C) . endfm

Especificacin de una cola de colas de enteros en Maude: view VInt from TRIV to INT is sort Elt to Int . endv view VColaInt from TRIV to COLA{VInt} is

Cola (informtica)
sort Elt to Cola{VInt} . endv fmod COLA-COLAS-INT is protecting INT . protecting COLA{VColaInt} . *** operaciones propias de la cola de colas de enteros op encolarInt op frenteInt *** variables var CCNV : ColaNV{VColaInt} . var CC var CE var E : Cola{VColaInt} . : Cola{VInt} . : Int . : Int ColaNV{VColaInt} -> ColaNV{VColaInt} . -> Cola{VColaInt} . -> [Int] . : ColaNV{VColaInt} op desencolarInt : Cola{VColaInt}

44

*** ecuaciones eq encolarInt(E, encolar(CE, CC)) = encolar(encolar(E, CE), CC) . eq desencolarInt (encolar(CE, crear)) = encolar(desencolar(CE), crear) . eq desencolarInt (encolar(CE, CCNV)) = encolar(CE, desencolarInt(CCNV)) . eq frenteInt(CCNV) = frente(frente(CCNV)) . endfm

Colas en C++
#ifndef COLA #define COLA // Define la cola template <class T> class Cola{ private: struct Nodo{ T elemento; struct Nodo* siguiente; posicin }* primero; struct Nodo* ultimo; unsigned int elementos; public: Cola(){ elementos = 0; } cout<<" Hola Mundo! "<<endl; cout<<" Hello, World! "<<endl; ~Cola(){

// coloca el nodo en la segunda

Cola (informtica) while (elementos != 0) pop(); } void push(const T& elem){ Nodo* aux = new Nodo; aux->elemento = elem; if (elementos == 0) primero = aux; else ultimo->siguiente = aux; ultimo = aux; ++elementos; } void pop(){ Nodo* aux = primero; primero = primero->siguiente; delete aux; --elementos; } T consultar() const{ return primero->elemento; } bool vacia() const{ return elementos == 0; } unsigned int size() const{ return elementos; } }; #endif

45

Colas en JAVA
public void inserta(Elemento x) { Nodo Nuevo; Nuevo = new Nodo(x, null); if (NodoCabeza == null) { NodoCabeza = Nuevo; } else { NodoFinal.Siguiente = Nuevo; } NodoFinal = Nuevo; } public Elemento cabeza() throws IllegalArgumentException { if (NodoCabeza == null) { throw new IllegalArgumentException(); } else { return NodoCabeza.Info; } }

Cola (informtica)

46

public Cola() { // Devuelve una Cola vaca NodoCabeza = null; NodoFinal = null; }

Colas en C#
public partial class frmPrincipal { // Variables globales public static string[] Cola; public static int Frente; public static int Final; public static int N; [STAThread] public static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new frmPrincipal()); } public frmPrincipal() { // Constructor

InitializeComponent(); Cola = new string[5]; N = 4; Frente = -1; Final = -1; } void CmdInsercionClick(object sender, System.EventArgs e) { frmInsercion Insercion = new frmInsercion(); Insercion.Show(); } void CmdRecorridoClick(object sender, System.EventArgs e) { frmRecorrido Recorrido = new frmRecorrido(); Recorrido.Show(); } // Arreglo lineal de 5

Cola (informtica) void CmdBusquedaClick(object sender, EventArgs e) { frmBusqueda Busqueda = new frmBusqueda(); Busqueda.Show(); } void CmdEliminacionClick(object sender, EventArgs e) { frmEliminacion Eliminar = new frmEliminacion(); Eliminar.Show(); } } Algoritmo Insertar(Cola, N, Frente, Final, Elemento) void CmdInsertarClick(object sender, System.EventArgs e) { elemento = txtInsercion.Text; // Se verifica que haya espacio en la Cola if (frmPrincipal.Frente == 0 && frmPrincipal.Final == frmPrincipal.N) { MessageBox.Show("La Cola esta llena"); return; } if (frmPrincipal.Frente == frmPrincipal.Final + 1) { MessageBox.Show("La Cola esta llena"); return; } // Si la cola esta vacia se inicializan punteros if (frmPrincipal.Frente == -1) { frmPrincipal.Frente = 0; frmPrincipal.Final = 0; } else if (frmPrincipal.Final == frmPrincipal.N) { frmPrincipal.Final = 0; } else { frmPrincipal.Final = frmPrincipal.Final + 1; } // Se agrega elemento a la Cola frmPrincipal.Cola[frmPrincipal.Final] = elemento; txtInsercion.Text = "";

47

Cola (informtica)

48

} Algoritmo Eliminacin (Cola, Frente, Final, N) void CmdEliminarClick(object sender, EventArgs e) { if (frmPrincipal.Frente == -1) { MessageBox.Show("Cola Vacia"); return; } string elemento = frmPrincipal.Cola[frmPrincipal.Frente]; // si la cola tiene un solo elemento if (frmPrincipal.Frente == frmPrincipal.Final) { frmPrincipal.Frente = -1; frmPrincipal.Final = -1; } else if (frmPrincipal.Frente == frmPrincipal.N) { frmPrincipal.Frente = 0; } else { frmPrincipal.Frente = frmPrincipal.Frente + 1; } lsEliminado.Items.Add(elemento); } Otra forma de programar una cola en Java Por Jorge Herrera C import java.util.*; public class Cola <Tipo>{ private List<Tipo> cola; public Cola(){ cola=new ArrayList<Tipo>(); } public boolean colaVacia(){ return cola.isEmpty(); } public void agregar(Tipo elemento){ cola.add(elemento); } public Tipo sacar(){

Cola (informtica) if(colaVacia())return null; Tipo elemento=cola.get(0); cola.remove(0); return elemento; } }// Fin de la clase Cola A continuacion un ejemplo de una clase manejadora de la clase Cola public class Manejador { public static void main(String[] args) { Cola cola=new <Integer>Cola(); System.out.println(cola.sacar()); cola.agregar(23); cola.agregar(24); cola.agregar(25); while(!cola.colaVacia()){ System.out.println(cola.sacar()); } Cola nombres=new <String>Cola(); nombres.agregar("Jorge"); nombres.agregar("Raquel"); nombres.agregar("Mayra Alejandra"); while(!nombres.colaVacia()){ System.out.println(nombres.sacar()); } } }// Fin de la clase Manejadora

49

Tipos de colas
Colas circulares (anillos): en las que el ltimo elemento y el primero estn unidos. Colas de prioridad: En ellas, los elementos se atienden en el orden indicado por una prioridad asociada a cada uno. Si varios elementos tienen la misma prioridad, se atendern de modo convencional segn la posicin que ocupen. Hay 2 formas de implementacin: 1. Aadir un campo a cada nodo con su prioridad. Resulta conveniente mantener la cola ordenada por orden de prioridad. 2. Crear tantas colas como prioridades haya, y almacenar cada elemento en su cola. Bicolas: son colas en donde los nodos se pueden aadir y quitar por ambos extremos; se les llama DEQUE (Double Ended QUEue). Para representar las bicolas lo podemos hacer con un array circular con Inicio y Fin que apunten a cada uno de los extremos. Hay variantes: Bicolas de entrada restringida: Son aquellas donde la insercin slo se hace por el final, aunque podemos eliminar al inicio al final. Bicolas de salida restringida: Son aquellas donde slo se elimina por el final, aunque se puede insertar al inicio y al final.

50

rboles de bsqueda
rbol (informtica)
En ciencias de la informtica, un rbol es una estructura de datos ampliamente usada que imita la forma de un rbol (un conjunto de nodos conectados). Un nodo es la unidad sobre la que se construye el rbol y puede tener cero o ms nodos hijos conectados a l. Se dice que un nodo es padre de un nodo si existe un enlace desde hasta (en ese caso, tambin decimos que es hijo de ). Slo puede haber un nico nodo sin padres, que llamaremos raz. Un nodo que no tiene hijos se conoce como hoja. Los dems nodos (tienen padre y uno o varios hijos) se les conoce como rama.

Definicin
Formalmente, podemos definir un rbol de la siguiente forma: Caso base: un rbol con slo un nodo (es a la vez raz del rbol y hoja). Un nuevo rbol a partir de un nodo una de las races de los nodo , los nodos y rboles de races con y cada nodos tiene como raz el y el conjunto de nodos hoja est formado por la unin

elementos cada uno, puede construirse estableciendo una relacin padre-hijo entre rboles. El rbol resultante de son los hijos de

de los conjuntos hojas iniciales. A cada uno de los rboles se les denota ahora subrboles de la raz. Una sucesin de nodos del rbol, de forma que entre cada dos nodos consecutivos de la sucesin haya una relacin de parentesco, decimos que es un rbol recorrido. Existen dos recorridos tpicos para listar los nodos de un rbol: en profundidad y en anchura. En el primer caso, se listan los nodos expandiendo el hijo actual de cada nodo hasta llegar a una hoja, donde se vuelve al nodo anterior probando por el siguiente hijo y as sucesivamente. En el segundo, por su parte, antes de listar los nodos de nivel (a distancia aristas de la raz), se deben haber listado todos los de nivel . Otros recorridos tpicos del rbol son preorden, postorden e inorden: El recorrido en preorden, tambin llamado orden previo consiste en recorrer en primer lugar la raz y luego cada uno de los hijos en orden previo. El recorrido en inorden, tambin llamado orden simtrico (aunque este nombre slo cobra significado en los rboles binarios) consiste en recorrer en primer lugar , luego la raz y luego cada uno de los hijos en orden simtrico. El recorrido en postorden, tambin llamado orden posterior consiste en recorrer en primer lugar cada uno de los hijos en orden posterior y por ltimo la raz. Finalmente, puede decirse que esta estructura es una representacin del concepto de rbol en teora de grafos. Un rbol es un grafo conexo y acclico.

rbol (informtica)

51

Tipos de rboles
rboles Binarios rbol de bsqueda binario auto-balanceable rboles AVL rboles Rojo-Negro rbol AA rboles Multicamino rboles B (rboles de bsqueda multicamino autobalanceados) rbol-B+ rbol-B*
Ejemplo de rbol (binario).

Operaciones de rboles. Representacin


Las operaciones comunes en rboles son: Enumerar todos los elementos. Buscar un elemento. Dado un nodo, listar los hijos (si los hay). Borrar un elemento. Eliminar un subrbol (algunas veces llamada podar).

Aadir un subrbol (algunas veces llamada injertar). Encontrar la raz de cualquier nodo. Por su parte, la representacin puede realizarse de diferentes formas. Las ms utilizadas son:
Las rotaciones en rboles binarios son operaciones internas comunes utilizadas para mantener el balance perfecto (o casi perfecto) del rbol binario. Un rbol balanceado permite operaciones en tiempo logartmico.

Representar cada nodo como una variable en el heap, con punteros a sus hijos y a su padre. Representar el rbol con un array donde cada elemento es un nodo y las relaciones padre-hijo vienen dadas por la posicin del nodo en el array.

Uso de los rboles


Usos comunes de los rboles son: Representacin de datos jerrquicos. Como ayuda para realizar bsquedas en conjuntos de datos (ver tambin: algoritmos de bsqueda en rboles).

rbol binario

52

rbol binario
En ciencias de la computacin, un rbol binario es una estructura de datos en la cual cada nodo siempre tiene un hijo izquierdo y un hijo derecho. No pueden tener ms de dos hijos (de ah el nombre "binario"). Si algn hijo tiene como referencia a null, es decir que no almacena ningn dato, entonces este es llamado un nodo externo. En el caso contrario el hijo es llamado un nodo interno. Usos comunes de los rboles binarios son los rboles binarios de bsqueda, los montculos binarios y Codificacin de Huffman.

Definicin de teora de grafos


En teora de grafos, se usa la siguiente definicin: Un rbol binario es un grafo conexo, acclico y no dirigido tal que el grado de cada vrtice no es mayor a 3. De esta forma slo existe un camino entre un par de nodos. Un rbol binario con enraizado es como un grafo que tiene uno de sus vrtices, llamado raz, de grado no mayor a 2. Con la raz escogida, cada vrtice tendr un nico padre, y nunca ms de dos hijos. Si rehusamos el requerimiento de la conectividad, permitiendo mltiples componentes conectados en el grafo, llamaremos a esta ltima estructura un bosque.

Tipos de rboles binarios


Un rbol binario es un rbol con raz en el que cada nodo tiene como mximo dos hijos.

Un rbol binario sencillo de tamao 9, 4 niveles y altura 3 (altura = mximo nivel - 1), con un nodo raz cuyo valor es 2.

Un rbol binario lleno es un rbol en el que cada nodo tiene cero o dos hijos. Un rbol binario perfecto es un rbol binario lleno en el que todas las hojas (vrtices con cero hijos) estn a la misma profundidad (distancia desde la raz, tambin llamada altura). A veces un rbol binario perfecto es denominado rbol binario completo. Otros definen un rbol binario completo como un rbol binario lleno en el que todas las hojas estn a profundidad n o n-1, para alguna n. Un rbol binario es un rbol en el que ningn nodo puede tener ms de dos subrboles. En un rbol binario cada nodo puede tener cero, uno o dos hijos (subrboles). Se conoce el nodo de la izquierda como hijo izquierdo y el nodo de la derecha como hijo derecho.

Implementacin en C
Un rbol binario puede declararse de varias maneras. Algunas de ellas son: Estructura con manejo de memoria dinmica, siendo el puntero que apunta al rbol de tipo tArbol: typedef struct nodo { int clave; struct nodo *izdo, *dcho; }Nodo; Estructura con arreglo indexado: typedef struct tArbol {

rbol binario int clave; tArbol hIzquierdo, hDerecho; } tArbol; tArbol rbol[NUMERO_DE_NODOS]; En el caso de un rbol binario casi-completo (o un rbol completo), puede utilizarse un sencillo arreglo de enteros con tantas posiciones como nodos deba tener el rbol. La informacin de la ubicacin del nodo en el rbol es implcita a cada posicin del arreglo. As, si un nodo est en la posicin i, sus hijos se encuentran en las posiciones 2i+1 y 2i+2, mientras que su padre (si tiene), se encuentra en la posicin truncamiento((i-1)/2) (suponiendo que la raz est en la posicin cero). Este mtodo se beneficia de un almacenamiento ms compacto y una mejor localidad de referencia, particularmente durante un recorrido en preorden. La estructura para este caso sera por tanto: int rbol[NUMERO_DE_NODOS];

53

Recorridos sobre rboles binarios


Recorridos en profundidad
El mtodo de este recorrido es tratar de encontrar de la cabecera a la raz en nodo de unidad binaria. Ahora pasamos a ver la implementacin de los distintos recorridos: Recorrido en preorden En este tipo de recorrido se realiza cierta accin (quizs simplemente imprimir por pantalla el valor de la clave de ese nodo) sobre el nodo actual y posteriormente se trata el subrbol izquierdo y cuando se haya concluido, el subrbol derecho. Otra forma para entender el recorrido con este metodo seria seguir el orden: nodo raz, nodo izquierda, nodo derecha. En el rbol de la figura el recorrido en preorden sera: 2, 7, 2, 6, 5, 11, 5, 9 y 4. void preorden(tArbol *a) { if (a != NULL) { tratar(a); preorden(a->hIzquierdo); preorden(a->hDerecho); } } Implementacin en pseudocdigo de forma iterativa:
push(s,NULL); push(s,raz); MIENTRAS (s <> NULL) HACER p = pop(s); tratar(p); SI (D(p) <> NULL) ENTONCES push(s,D(p)); FIN-SI SI (I(p) <> NULL) ENTONCES push(s,I(p)); FIN-SI //preguntamos si p tiene rbol izquierdo //sacamos un elemento de la pila //realizamos operaciones sobre el nodo p //preguntamos si p tiene rbol derecho //insertamos en una pila (stack) el valor NULL, para asegurarnos de que est vaca //insertamos el nodo raz

//Realiza una operacin en nodo

rbol binario
FIN-MIENTRAS

54

Recorrido en postorden En este caso se trata primero el subrbol izquierdo, despus el derecho y por ltimo el nodo actual. Otra forma para entender el recorrido con este metodo seria seguir el orden: nodo izquierda, nodo derecha, nodo raz. En el rbol de la figura el recorrido en postorden sera: 2, 5, 11, 6, 7, 4, 9, 5 y 2. void postorden(tArbol *a) { if (a != NULL) { postorden(a->hIzquiedo); postorden(a->hDerecho); tratar(a); } } Recorrido en enorden En este caso se trata primero el subrbol izquierdo, despus el nodo actual y por ltimo el subrbol derecho. En un ABB este recorrido dara los valores de clave ordenados de menor a mayor. Otra forma para entender el recorrido con este metodo seria seguir el orden: nodo izquierda,nodo raz,nodo derecha. En el rbol de la figura el recorrido en enorden sera: 2, 7, 5, 6, 11, 2, 5, 4, 9. Esquema de implementacin: void enorden(tArbol *a) { if (a != NULL) { enorden(a->hIzquierdo); tratar(a); enorden(a->hDerecho); } }

//Realiza una operacin en nodo

//Realiza una operacin en nodo

Recorridos en amplitud (o por niveles)


En este caso el recorrido se realiza en orden por los distintos niveles del rbol. As, se comenzara tratando el nivel 1, que slo contiene el nodo raz, seguidamente el nivel 2, el 3 y as sucesivamente. En el rbol de la figura el recorrido en amplitud sera: 2, 7, 5, 2, 6, 9, 5, 11 y 4. Al contrario que en los mtodos de recorrido en profundidad, el recorrido por niveles no es de naturaleza recursiva. Por ello, se debe utilizar una cola para recordar los subrboles izquierdos y derecho de cada nodo. El esquema algoritmo para implementar un recorrido por niveles es exactamente el mismo que el utilizado en la versin iterativa del recorrido en preorden pero cambiando la estructura de datos que almacena los nodos por una cola. Implementacin en C: void arbol_recorrido_anch (tipo_Arbol* A) { tipo_Cola cola_nodos; // esta cola esta implementada previamente, almacena punteros (posiciones de nodos de rbol) tipo_Pos nodo_actual; // este es un puntero llevara el recorrido

rbol binario

55

if (vacio(A)) // si el rbol esta vacio, salimos return; cola_inicializa(&cola_nodos); // obvio, y necesario cola_enqueue(A, &cola_nodos); // se encola la raz while (!vacia(&cola_nodos)) { // mientras la cola no se vacie se realizara el recorrido nodo_actual = cola_dequeue(&cola_nodos) // de la cola saldran los nodos ordenados por nivel printf("%c,", nodo_actual->info); // se "procesa" el nodo donde va el recorrido, en este caso se imprime if (nodo_actual->izq != null) // si existe, ponemos el hijo izquierdo en la cola cola_enqueue(nodo_actual->izq, &cola_nodos); if (nodo_actual->der != null) // si existe, ponemos el hijo derecho en la cola cola_enqueue(nodo_actual->der, &cola_nodos); } // al vaciarse la cola se han visitado todos los nodos del rbol }

Creacin de rboles a partir de los recorridos


Para poder dibujar un rbol binario en base a los recorridos, se necesitan por lo menos dos de los recorridos de profundidad (en caso de que no se repitan los nodos, ya que si se repiten los nodos es recomendable tener los tres recorridos), ya sean inorden y preorden o inorden y postorden, la nica diferencia entre usar el recorrido en preorden o postorden es que en preorden se usa el primer nodo para encontrar la raz y en postorden se usa el ltimo nodo. El mtodo consiste en ir dividiendo los recorridos del rbol en pequeos subrboles, se va encontrando la raz con el preorden o postorden y se divide en dos subrboles basndonos en el recorrido en inorden. En el caso de que los nodos se repitan es conveniente tener los 3 recorridos para identificar ms fcilmente cul de los nodos es la raz actual. Para el rbol de la figura corresponden los siguientes recorridos: Preorden Inorden Postorden Para encontrar la raz es necesario tener el recorrido preorden o postorden, ya que la raz es el primer nodo o el ltimo nodo respectivamente. En este caso la raz es el . Una vez encontrada la raz, es necesario saber su posicin en el recorrido inorden, del paso anterior se tiene el nodo , pero existen 2 nodos con ese valor, el primero y el de en medio. Si el primer dos es la raz, entonces no existe ninguna rama del lado izquierdo, en ese caso la siguiente raz de acuerdo con el recorrido en postorden es y de

rbol binario acuerdo con preorden es , lo cual es una incongruencia, de esa forma sabemos que el otro es la raz.

56

Entonces marcamos la raz en el recorrido inorden: Preorden Inorden Postorden El recorrido inorden, es un recorrido de los rboles binarios en los que se empieza desde el nodo que se encuentra ms a la izquierda de todos, sigue con la raz y termina con los nodos del lado derecho, entonces, como en el recorrido inorden ya encontramos la raz, la parte izquierda representa el subrbol izquierdo y la parte derecha representa el subrbol derecho. En los recorridos tenemos 5 nodos a la izquierda del y a la derecha se encuentran 3 valores, entonces podemos crear los recorridos para el subrbol izquierdo y el subrbol derecho
Subrbol derecho Preorden Inorden Postorden Subrbol derecho Preorden Inorden Postorden

Se sigue repitiendo el proceso hasta encontrar todos los nodos del rbol, en este punto la siguiente raz izquierda es el y la raz derecha el . Cuando se llegan a nodos en los que nicamente cuentan con una rama es necesario saber que rama es la derecha y cul es la izquierda (para algunos rboles con balanceo como los AVL), por ejemplo siguiendo la rama de la derecha partiendo de que el es la raz el recorrido inorden es entonces el siguiente nodo va a la derecha, no hay nodo a la izquierda, despus, los recorridos para el subrbol son: Preorden Inorden Postorden Finalmente el siguiente nodo se coloca a la izquierda del .

Este mtodo es 100% efectivo cuando no existen nodos repetidos, cuando los nodos se repiten la complejidad aumenta para poder descubrir cul es el nodo raz en el recorrido inorden.

Mtodos para almacenar rboles binarios


Los rboles binarios pueden ser construidos a partir de lenguajes de programacin de varias formas. En un lenguaje con registros y referencias, los rboles binarios son construidos tpicamente con una estructura de nodos y punteros en la cual se almacenan datos, cada uno de estos nodos tiene una referencia o puntero a un nodo izquierdo y a un nodo derecho denominados hijos. En ocasiones, tambin contiene un puntero a un nico nodo. Si un nodo tiene menos de dos hijos, algunos de los punteros de los hijos pueden ser definidos como nulos para indicar que no dispone de dicho nodo. En la figura adjunta se puede observar la estructura de dicha implementacin.

rbol binario

57

Los rboles binarios tambin pueden ser almacenados como una estructura de datos implcita en vectores, y si el rbol es un rbol binario completo, este mtodo no desaprovecha el espacio en memoria. Tomaremos como notacin la siguiente: si un nodo tiene un ndice i, sus hijos se encuentran en ndices 2i + 1 y 2i + 2, mientras que sus padres (si los tiene) se encuentra en el ndice (partiendo de que la raz tenga ndice cero). Este mtodo tiene como

ventajas el tener almacenados los datos de forma ms compacta y por tener una forma ms rpida y eficiente de localizar los datos en particular durante un preoden transversal. Sin embargo, desperdicia mucho espacio en memoria.

Codificacin de rboles n-arios como rboles binarios


Hay un mapeo uno a uno entre los rboles generales y rboles binarios, el cual en particular es usado en Lisp para representar rboles generales como rboles binarios. Cada nodo N ordenado en el rbol corresponde a un nodo N' en el rbol binario; el hijo de la izquierda de N es el nodo correspondiente al primer hijo de N, y el hijo derecho de N' es el nodo correspondiente al siguiente hermano de N, es decir, el prximo nodo en orden entre los hijos de los padres de N. Esta representacin como rbol binario de un rbol general, se conoce a veces como un rbol binario primer hijo hermano, o un rbol doblemente encadenado. Una manera de pensar acerca de esto es que los hijos de cada nodo estn en una lista enlazada, encadenados junto con el campo derecho, y el nodo slo tiene un puntero al comienzo o la cabeza de esta lista, a travs de su campo izquierdo. Por ejemplo, en el rbol de la izquierda, la A tiene 6 hijos (B, C, D, E, F, G). Puede ser convertido en el rbol binario de la derecha. Un ejemplo de transformar el rbol n-ario a un rbol binario cmo pasar de rboles n-arios a rboles FLOFO.

rbol binario

58

El rbol binario puede ser pensado como el rbol original inclinado hacia los lados, con los bordes negros izquierdos representando el primer hijo y los azules representado los siguientes hermanos. Las hojas del rbol de la izquierda seran escritas en Lisp como: (((N O) I J) C D ((P) (Q)) F (M)) Que se ejecutar en la memoria como el rbol binario de la derecha, sin ningn tipo de letras en aquellos nodos que tienen un hijo izquierdo.

Enlaces externos
rbol binario de bsqueda en PHP [1]

Referencias
[1] http:/ / mmengineer. blogspot. com/ 2007/ 10/ aboles-binarios-de-busqueda-php. html

rbol binario de bsqueda

59

rbol binario de bsqueda


Un rbol binario de bsqueda tambin llamados BST (acrnimo del ingls Binary Search Tree) es un tipo particular de rbol binario que presenta una estructura de datos en forma de rbol usada en informtica.

Descripcin
Un rbol binario de bsqueda (ABB) es un rbol binario definido de la siguiente forma: rbol binario la mayora de los rboles binarios son de bsqueda Un rbol binario no vaco, de raz R, es un rbol binario de bsqueda si: En caso de tener subrbol izquierdo, la raz R debe ser mayor que el valor mximo almacenado en el subrbol izquierdo, y que el subrbol izquierdo sea un rbol binario de bsqueda. En caso de tener subrbol derecho, la raz R debe ser menor que el valor mnimo almacenado en el subrbol derecho, y que el subrbol derecho sea un rbol binario de bsqueda. Para una fcil comprensin queda resumido en que es un rbol binario que cumple que el subrbol izquierdo de cualquier nodo (si no est vaco) contiene valores menores que el que contiene dicho nodo, y el subrbol derecho (si no est vaco) contiene valores mayores. Para estas definiciones se considera que hay una relacin de orden establecida entre los elementos de los nodos. Que cierta relacin est definida, o no, depende de cada lenguaje de programacin. De aqu se deduce que puede haber distintos rboles binarios de bsqueda para un mismo conjunto de elementos. La altura h en el peor de los casos siempre el mismo tamao que el nmero de elementos disponibles. Y en el mejor de los casos viene dada por la expresin , donde ceil indica redondeo por exceso. El inters de los rboles binarios de bsqueda (ABB) radica en que su recorrido en inorden proporciona los elementos ordenados de forma ascendente y en que la bsqueda de algn elemento suele ser muy eficiente. Dependiendo de las necesidades del usuario que trate con una estructura de este tipo, se podr permitir la igualdad estricta en alguno, en ninguno o en ambos de los subrboles que penden de la raz. Permitir el uso de la igualdad provoca la aparicin de valores dobles y hace la bsqueda ms compleja. Un rbol binario de bsqueda no deja de ser un caso particular de rbol binario, as usando la siguiente especificacin de rbol binario en maude: fmod ARBOL-BINARIO {X :: TRIV}is sorts ArbolBinNV{X} ArbolBin{X} . subsort ArbolBinNV{X} < ArbolBin{X} . *** generadores

Un rbol binario de bsqueda de tamao 9 y profundidad 3, con raz 8 y hojas 1, 4, 7 y 13

rbol binario de bsqueda op crear : -> ArbolBin{X} [ctor] . op arbolBin : X$Elt ArbolBin{X} ArbolBin{X} -> ArbolBinNV{X} [ctor] . endfm podemos hacer la siguiente definicin para un rbol binario de bsqueda (tambin en maude): fmod ARBOL-BINARIO-BUSQUEDA {X :: ORDEN} is protecting ARBOL-BINARIO{VOrden}{X} . sorts ABB{X} ABBNV{X} . subsort ABBNV{X} < ABB{X} . subsort ABB{X} < ArbolBin{VOrden}{X} . subsort ABBNV{X} < ArbolBinNV{VOrden}{X} . *** generadores op crear : -> ArbolBin{X} [ctor] . op arbolBin : X$Elt ArbolBin{X} ArbolBin{X} -> ArbolBinNV{X} [ctor] . endfm con la siguiente teora de orden: fth ORDEN is protecting BOOL . sort Elt . *** operaciones op _<_ : Elt Elt -> Bool . endfth para que un rbol binario pertenezca al tipo rbol binario de bsqueda debe cumplir la condicin de ordenacin siguiente que ira junto al mdulo ARBOL-BINARIO-BUSQUEDA: var R : X$Elt . vars INV DNV : ABBNV{X} . vars I D : ABB{X} . mb crear : ABB{X} . mb arbolBin(R, crear, crear) : ABBNV{X} . cmb arbolBin(R, INV, crear) : ABBNV{X} if R > max(INV) . cmb arbolBin(R, crear, DNV) : ABBNV{X} if R < min(DNV) . cmb arbolBin(R, INV, DNV) : ABBNV{X} if (R > max(INV)) and (R < min(DNV)) . ops min max : ABBNV{X} -> X$Elt . eq min(arbolBin(R, crear, D)) = R . eq min(arbolBin(R, INV, D)) = min(INV) . eq max(arbolBin(R, I, crear)) = R . eq max(arbolBin(R, I, DNV)) = max(DNV) .

60

Implementacin en Python
class nodo: izq , der, dato = None, None, 0 def __init__(self, dato): # crea un nodo self.izq = None

rbol binario de bsqueda self.der = None self.dato = dato class arbolBinario: def __init__(self): # inicializa la raiz self.raiz = None def agregarNodo(self, dato): # crea un nuevo nodo y lo devuelve return nodo(dato) def insertar(self, raiz, dato): # inserta un dato nuevo en el rbol if raiz == None: # si no hay nodos en el rbol lo agrega return self.agregarNodo(dato) else: # si hay nodos en el rbol lo recorre if dato <= raiz.dato: # si el dato ingresado es menor que el dato guardado va al subrbol izquierdo raiz.izq = self.insertar(raiz.izq, dato) else: # si no, procesa el subrbol derecho raiz.der = self.insertar(raiz.der, dato) return raiz

61

Operaciones
Todas las operaciones realizadas sobre rboles binarios de bsqueda estn basadas en la comparacin de los elementos o clave de los mismos, por lo que es necesaria una subrutina, que puede estar predefinida en el lenguaje de programacin, que los compare y pueda establecer una relacin de orden entre ellos, es decir, que dados dos elementos sea capaz de reconocer cual es mayor y cual menor. Se habla de clave de un elemento porque en la mayora de los casos el contenido de los nodos ser otro tipo de estructura y es necesario que la comparacin se haga sobre algn campo al que se denomina clave.

Bsqueda
La bsqueda consiste acceder a la raz del rbol, si el elemento a localizar coincide con ste la bsqueda ha concluido con xito, si el elemento es menor se busca en el subrbol izquierdo y si es mayor en el derecho. Si se alcanza un nodo hoja y el elemento no ha sido encontrado se supone que no existe en el rbol. Cabe destacar que la bsqueda en este tipo de rboles es muy eficiente, representa una funcin logartmica. El mximo nmero de comparaciones que necesitaramos para saber si un elemento se encuentra en un rbol binario de bsqueda estara entre [log2(N+1)] y N, siendo N el nmero de nodos. La bsqueda de un elemento en un ABB (rbol Binario de Bsqueda) se puede realizar de dos formas, iterativa o recursiva. Ejemplo de versin iterativa en el lenguaje de programacin C, suponiendo que estamos buscando una clave alojada en un nodo donde est el correspondiente "dato" que precisamos encontrar:

rbol binario de bsqueda data Buscar_ABB(abb t,clave k) { abb p; dato e; e=NULL; p=t; if (!estaVacio(p)) { while (!estaVacio(p) && (p->k!=k) ) { if (k < p->k) { p=p->l; } if (p->k < k) { p=p->r; } } if (!estaVacio(p) &&(p->d!=NULL) ) { e=copiaDato(p->d); } } return e; } Vase ahora la versin recursiva en ese mismo lenguaje: int buscar(tArbol *a, int elem) { if (a == NULL) { return 0; } else if (a->clave < elem) { return buscar(a->hDerecho, elem); } else if (a->clave > elem) { return buscar(a->hIzquierdo, elem); } else { return 1; } }

62

rbol binario de bsqueda Otro ejemplo en Python: def buscar(raiz, clave): # busca el valor clave dentro del arbol if raiz == None: print 'No se encuentra' else: # if clave == raiz.dato: print 'El valor ',clave,' se encuentra en el ABB' elif clave < raiz.dato: # lado izquierdo return buscar(raiz.izq, clave) else: # lado derecho return buscar(raiz.der, clave) En Pascal: Function busqueda(T:ABR, y: integer):ABR begin if (T=nil) or (^T.raiz=y) then busqueda:=T; else if (^T.raiz<y) then busqueda:=busqueda(^T.dch,y); else busqueda:=busqueda(^T.izq,y); end; Una especificacin en maude para la operacin de bsqueda quedara de la siguiente forma: op esta? : X$Elt ABB{X} -> Bool . var R R1 R2 : X$Elt . vars I D : ABB{X} . eq esta?(R, crear) = false . eq esta?(R1, arbolBin(R2, I, D)) = if R1 == R2 then true else if R1 < R2 then esta?(R1, I) else esta?(R1, D) fi fi .

63

rbol binario de bsqueda

64

Insercin
La insercin es similar a la bsqueda y se puede dar una solucin tanto iterativa como recursiva. Si tenemos inicialmente como parmetro un rbol vaco se crea un nuevo nodo como nico contenido el elemento a insertar. Si no lo est, se comprueba si el elemento dado es menor que la raz del rbol inicial con lo que se inserta en el subrbol izquierdo y si es mayor se inserta en el subrbol derecho.

Evolucin de la insercin del elemento "5" en un ABB.

Como en el caso de la bsqueda puede haber varias variantes a la hora de implementar la insercin en el TAD (Tipo Abstracto de Datos), y es la decisin a tomar cuando el elemento (o clave del elemento) a insertar ya se encuentra en el rbol, puede que ste sea modificado o que sea ignorada la insercin. Es obvio que esta operacin modifica el ABB perdiendo la versin anterior del mismo. A continuacin se muestran las dos versiones del algoritmo en pseudolenguaje, iterativa y recursiva, respectivamente. PROC InsertarABB(rbol:TABB; dato:TElemento) VARIABLES nuevonodo,pav,pret:TABB clavenueva:Tclave ele:TElemento INICIO nuevonodo <- NUEVO(TNodoABB) nuevonodo^.izq <- NULO nuevonodo^.der <- NULO nuevonodo^.elem <- dato SI ABBVaco (rbol) ENTONCES rbol <- nuevonodo ENOTROCASO clavenueva <- dato.clave pav <- rbol // Puntero Avanzado pret <- NULO // Puntero Retrasado MIENTRAS (pav <- NULO) HACER pret <- pav ele = pav^.elem SI (clavenueva < ele.clave ) ENTONCES pav <- pav^.izq EN OTRO CASO pav <- pav^.dch FINSI

rbol binario de bsqueda FINMIENTRAS ele = pret^.elem SI (clavenueva < ele.clave ) ENTONCES pret^.izq <- nuevonodo EN OTRO CASO pret^.dch <- nuevonodo FINSI FINSI FIN PROC InsertarABB(rbol:TABB; dato:TElemento) VARIABLES ele:TElemento INICIO SI (ABBVaco(rbol)) ENTONCES rbol <- NUEVO(TNodoABB) rbol^.izq <- NULO rbol^.der <- NULO rbol^.elem <- dato EN OTRO CASO ele = InfoABB(rbol) SI (dato.clave < ele.clave) ENTONCES InsertarABB(rbol^.izq, dato) EN OTRO CASO InsertarABB(rbol^.dch, dato) FINSI FINSI FIN Se ha podido apreciar la simplicidad que ofrece la versin recursiva, este algoritmo es la traduccin en C. El rbol es pasado por referencia para que los nuevos enlaces a los subrboles mantengan la coherencia. void insertar(tArbol **a, int elem) { if (*a == NULL) { *a = (tArbol *) malloc(sizeof(tArbol)); (*a)->clave = elem; (*a)->hIzquierdo = NULL; (*a)->hDerecho = NULL; } else if ((*a)->clave < elem) insertar(&(*a)->hDerecho, elem); else if ((*a)->clave > elem) insertar(&(*a)->hIzquierdo, elem); } En Python el mecanismo de insercin se define, por ejemplo, dentro de la clase que defina el ABB (ver ms arriba). Otro ejemplo en Pascal:

65

rbol binario de bsqueda Procedure Insercion(var T:ABR, y:integer) var ultimo:ABR; actual:ABR; nuevo:ABR; begin ultimo:=nil; actual:=T; while (actual<>nil) do begin ultimo:=actual; if (actual^.raiz<y) then actual:=actual^.dch else actual:=actual^.izq; end; new(nuevo); ^nuevo.raiz:=y; ^nuevo.izq:=nil; ^nuevo.dch:=nil; if ultimo=nil then T:=nuevo else if ultimo^.raiz<y then ultimo^.dch:=nuevo else ultimo^.izq:=nuevo; end; Vase tambin un ejemplo de algoritmo recursivo de insercin en un ABB en el lenguaje de programacin Maude:
op insertar : X$Elt ABB{X} -> ABBNV{X} . var R R1 R2 : X$Elt . vars I D : ABB{X} . eq insertar(R, crear) = arbolBin(R, crear, crear) . eq insertar(R1, arbolBin(R2, I, D)) = if R1 < R2 then arbolBin(R2, insertar(R1, I), D) else arbolBin(R2, I, insertar(R1, D)) fi .

66

La operacin de insercin requiere, en el peor de los casos, un tiempo proporcional a la altura del rbol.

rbol binario de bsqueda

67

Borrado
La operacin de borrado no es tan sencilla como las de bsqueda e insercin. Existen varios casos a tener en consideracin: Borrar un nodo sin hijos o nodo hoja: simplemente se borra y se establece a nulo el apuntador de su padre.

Nodo a eliminar 74

Borrar un nodo con un subrbol hijo: se borra el nodo y se asigna su subrbol hijo como subrbol de su padre.

Nodo a eliminar 70

Borrar un nodo con dos subrboles hijo: la solucin est en reemplazar el valor del nodo por el de su predecesor o por el de su sucesor en inorden y posteriormente borrar este nodo. Su predecesor en inorden ser el nodo ms a la derecha de su subrbol izquierdo (mayor nodo del subarbol izquierdo), y su sucesor el nodo ms a la izquierda de su subrbol derecho (menor nodo del subarbol derecho). En la siguiente figura se muestra cmo existe la posibilidad de realizar cualquiera de ambos reemplazos:

Nodo a eliminar 59

El siguiente algoritmo en C realiza el borrado en un ABB. El procedimiento reemplazar busca la mayor clave del subrbol izquierdo y la asigna al nodo a eliminar. void reemplazar(tArbol **a, tArbol **aux); /*Prototipo de la funcion ''reemplazar''*/ void borrar(tArbol **a, int elem) { tArbol *aux; if (*a == NULL) return; if ((*a)->clave < elem) borrar(&(*a)->hDerecho, elem); else if ((*a)->clave > elem) borrar(&(*a)->hIzquierdo, elem);

rbol binario de bsqueda else if ((*a)->clave == elem) { aux = *a; if ((*a)->hIzquierdo == NULL) *a = (*a)->hDerecho; else if ((*a)->hDerecho == NULL) *a = (*a)->hIzquierdo; else reemplazar(&(*a)->hIzquierdo, &aux); free(aux); } } void reemplazar(tArbol **a, tArbol **aux) { if ((*a)->hDerecho == NULL) { (*aux)->clave = (*a)->clave; *aux = *a; *a = (*a)->hIzquierdo; } else reemplazar(&(*a)->hDerecho, aux); } Otro ejemplo en Pascal. Procedure Borrar(var T:ABR, x:ABR) var aBorrar:ABR; anterior:ABR; actual:ABR; hijo:ABR; begin if (^x.izq=nil) or (^x.dch=nil) then aBorrar:=x; else aBorrar:=sucesor(T,x); actual:=T; anterior:=nil; while (actual<>aBorrar) do begin anterior:=actual; if (^actual.raiz<^aBorrar.raiz) then actual:=^actual.dch; else actual:=^actual.izq;

68

rbol binario de bsqueda end; if (^actual.izq=nil) then hijo:=^actual.dch; else hijo:=^actual.izq; if (anterior=nil) then T:=hijo; else if (^anterior.raiz<^actual.raiz) then ^anterior.dch:=hijo; else ^anterior.izq:=hijo; if (aBorrar<>x) then ^x.raiz:=^aBorrar.raiz; free(aBorrar); end; Vase tambin un ejemplo de algoritmo recursivo de borrado en un ABB en el lenguaje de programacin Maude, considerando los generadores crear y arbolBin. Esta especificacin hace uso de la componente clave a partir de la cual se ordena el rbol.
op eliminar : X$Elt ABB{X} -> ABB{X} . varS R M : X$Elt . vars I D : ABB{X} . vars INV DNV : ABBNV{X} . ops max min : ArbolBin{X} -> X$Elt . eq min(arbolBin(R, crear, D)) = R . eq max(arbolBin(R, I, crear)) = R . eq min(arbolBin(R, INV, D)) = min(INV) . eq max(arbolBin(R, I, DNV )) = max(DNV) . eq eliminar(M, crear) = crear . ceq eliminar(M, arbolBin(R, crear, D)) = D if M == clave(R) . ceq eliminar(M, arbolBin(R, I, crear)) = I if M == clave(R) . ceq eliminar(M, arbolBin(R, INV, DNV)) = arbolBin(max(INV), eliminar(clave(max(INV)), INV), DNV) if M == clave(R) . ceq eliminar(M, arbolBin(R, I, D)) = arbolBin(R, eliminar(M, I), D) if M < clave(R) . ceq eliminar(M, arbolBin(R, I, D)) = arbolBin(R, I, eliminar(M, D)) if clave(R) < M .

69

Otras Operaciones
Otra operacin sera por ejemplo comprobar que un rbol binario es un rbol binario de bsqueda. Su implementacin en maude es la siguiente: op esABB? : ABB{X} -> Bool . var R : X$Elt . vars I D : ABB{X} . eq esABB?(crear) = true . eq esABB?(arbolbBin(R, I, D)) = (Max(I) < R) and (Min(D) > R) and (esABB?(I)) and (esABB?(D)) .

rbol binario de bsqueda

70

Recorridos
Se puede hacer un recorrido de un rbol en profundidad o en anchura. Los recorridos en anchura son por niveles, se realiza horizontalmente desde la raz a todos los hijos antes de pasar a la descendencia de alguno de los hijos. El coste de recorrer el ABB es O(n), ya que se necesitan visitar todos los vrtices. El recorrido en profundidad lleva al camino desde la raz hacia el descendiente ms lejano del primer hijo y luego contina con el siguiente hijo. Como recorridos en profundidad tenemos inorden, preorden y postorden. Una propiedad de los ABB es que al hacer un recorrido en profundidad inorden obtenemos los elementos ordenados de forma ascendente. Resultado de hacer el recorrido en: Inorden = [6, 9, 13, 14, 15, 17, 20, 26, 64, 72]. Preorden = [15, 9, 6, 14, 13, 20, 17, 64, 26, 72]. Postorden =[6, 13, 14, 9, 17, 26, 72, 64, 20, 15]. Recorridos en Visual Basic .Net
Ejemplo rbol binario de bsqueda

'funcin de recorrido en PREORDEN Public Function preorden() As String cadenasalida = "" rePreorden(raz) Return cadenasalida End Function Private Sub rePreorden(ByVal padre As Nodo) If IsNothing(padre) Then Return End If cadenasalida = cadenasalida & "-" & padre.dato rePreorden(padre.ant) rePreorden(padre.sig) End Sub 'funcin de recorrido en POSTORDEN Public Function postorden() As String cadenasalida = "" reposorden(raz) Return cadenasalida End Function Private Sub repostorden(ByVal padre As Nodo) If IsNothing(padre) Then Return End If repostorden(padre.ant) repostorden(padre.sig) cadenasalida = cadenasalida & "-" & padre.dato

rbol binario de bsqueda End Sub 'funcin de recorrido en ENORDEN Public Function inorden() As String cadenasalida = "" reinorden(raz) Return cadenasalida End Function Private Sub reinorden(ByVal padre As Nodo) If IsNothing(padre) Then Return End If reinorden(padre.ant) cadenasalida = cadenasalida & "-" & padre.dato reinorden(padre.sig) End Sub Recorridos en C con funciones recursivas struct Nodo{ char nombre[30]; struct Nodo *izq; struct Nodo *der; }; typedef struct Nodo Nodo; typedef Nodo *Arbol; void preOrden(Arbol abb){ if(abb) { printf("%s\n", abb->nombre); preOrden(abb->izq); preOrden(abb->der); } } void postOrden(Arbol abb){ if(abb) { postOrden(abb->izq); postOrden(abb->der); printf("%s\n", abb->nombre); } } void inOrden(Arbol abb){ if(abb) {

71

rbol binario de bsqueda inOrden(abb->izq); printf("%s\n", abb->nombre); inOrden(abb->der); } }

72

Tipos de rboles binarios de bsqueda


Hay varios tipos de rboles binarios de bsqueda. Los rboles AVL, rbol rojo-negro, son rboles autobalanceables . Los rbol biselado son rboles tambin autobalanceables con la propiedad de que los elementos accedidos recientemente se acceder ms rpido en posteriores accesos. En el montculo como en todos los rboles binarios de bsqueda cada nodo padre tiene un valor mayor que sus hijos y adems es completo, esto es cuando todos los niveles estn llenos con excepcin del ltimo que puede no estarlo, por ltimo, en lo montculos, cada nodo mantiene una prioridad y siempre, un nodo padre tendr una prioridad mayor a la de su hijo. Otras dos maneras de configurar un rbol binario de bsqueda podra ser como un rbol completo o degenerado. Un rbol completo es un rbol con "n" niveles, donde cada nivel d <= n-1; el nmero de nodos existentes en el nivel "d" es igual que 2d. Esto significa que todos los posibles nodos existen en esos niveles, no hay ningn hueco. Un requirimiento adicional para un rbol binario completo es que para el nivel "n", los nodos deben estar ocupados de izquierda a derecha, no pudiendo haber un hueco a la izquierda de un nodo ocupado. Un rbol degenerativo es un rbol que, para cada nodo padre, slo hay asociado un nodo hijo. Por lo que se comporta como una lista enlazada.

Comparacin de rendimiento
D. A. Heger(2004) realiza una comparacin entre los diferentes tipos de rboles binarios de bsqueda para encontrar que tipo nos dara el mejor rendimiento para cada caso. Los montculos se encuentran como el tipo de rbol binario de bsqueda que mejor resultado promedio da, mientras que los rboles rojo-negro los que menor rendimiento medio nos aporta.

Buscando el rbol binario de bsqueda ptimo


Si nosotros no tenemos en mente planificar un rbol binario de bsqueda, y sabemos exactamente como de frecuente sern visitados cada elemento podemos construir un rbol binario de bsqueda ptimo con lo que conseguiremos que la media de gasto generado a la hora de buscar un elemento sea minimizado. Asumiendo que conocemos los elementos y en qu nivel est cada uno, tambin conocemos la proporcin de futuras bsquedas que se harn para encontrar dicho elemento. Si es as, podemos usar una solucin basada en la programacin dinmica. En cambio, a veces slo tenemos la estimacin de los costes de bsqueda, como pasa con los sistemas que nos muestra el tiempo que ha necesitado para realizar una bsqueda. Un ejemplo, si tenemos un ABB de palabras usado en un corrector ortogrfico, deberamos balancear el rbol basado en la frecuencia que tiene una palabra en el Corpus lingstico, desplazando palabras como "de" cerca de la raz y palabras como "vesnico" cerca de las hojas. Un rbol como tal podra ser comparado con los rboles Huffman que tratan de encontrar elementos que son accedidos frecuentemente cerca de la raz para producir una densa informacin; de todas maneras, los rboles Huffman slo puede guardar elementos que contienen datos en las hojas y estos elementos no necesitan ser ordenados. En cambio, si no sabemos la secuencia en la que los elementos del rbol van a ser accedidos, podemos usar rboles biselados que son tan buenos como cualquier rbol de bsqueda que podemos construir para cualquier secuencia en particular de operaciones de bsqueda.

rbol binario de bsqueda rboles alfabticos son rboles Huffman con una restriccin de orden adicional, o lo que es lo mismo, rboles de bsqueda con modificacin tal que todos los elementos son almacenados en las hojas.

73

Referencias Enlaces externos


rboles binarios de bsqueda en Google Implementacin de rboles binarios de bsqueda en distintos lenguajes (http://en.literateprograms.org/ Binary_search_tree_(C)) Aplicacin JAVA de rboles (http://people.ksp.sk/~kuko/bak/index.html)

74

Tablas y funciones de dispersin


Tabla hash
Una tabla hash, mapa hash, tabla de dispersin o tabla fragmentada es una estructura de datos que asocia llaves o claves con valores. La operacin principal que soporta de manera eficiente es la bsqueda: permite el acceso a los elementos (telfono y direccin, por ejemplo) almacenados a partir de una clave generada (usando el nombre o nmero de cuenta, por ejemplo). Funciona transformando la clave con una funcin hash en un hash, un nmero que identifica la posicin (casilla o cubeta) donde la tabla hash localiza el valor deseado. Un ejemplo prctico para ilustrar que es una tabla hash es el siguiente: Se necesita organizar los peridicos que llegan diariamente de tal forma que se puedan ubicar de forma rpida, entonces se hace de la siguiente forma - se hace una gran caja para guardar todos los peridicos (una tabla), y se divide en 31 contenedores (ahora es una "hash table" o tabla fragmentada), y la clave para guardar los peridicos es el da de publicacin (ndice). Cuando se requiere buscar un peridico se busca por el da que fue publicado y as se sabe en que zcalo (bucket) est. Varios peridicos quedarn guardados en el mismo zcalo (es decir colisionan al ser almacenados), lo que implica buscar en la sub-lista que se guarda en cada zcalo. De esta forma se reduce el tamao de las bsquedas de O(n) a - En el mejor de los casos O(1) y en el peor de los casos O(log(n)). Las tablas hash se suelen implementar sobre vectores de una dimensin, aunque se pueden hacer implementaciones multi-dimensionales basadas en varias claves. Como en el caso de los arrays, las tablas hash proveen tiempo constante de bsqueda promedio O(1),[1] sin importar el nmero de elementos en la tabla. Sin embargo, en casos particularmente malos el tiempo de bsqueda puede llegar a O(n), es decir, en funcin del nmero de elementos.

Ejemplo de tabla hash.

Comparada con otras estructuras de arrays asociadas, las tablas hash son ms tiles cuando se almacenan grandes cantidades de informacin. Las tablas hash almacenan la informacin en posiciones pseudo-aleatorias, as que el acceso ordenado a su contenido es bastante lento. Otras estructuras como rboles binarios auto-balanceables tienen un tiempo promedio de bsqueda mayor (tiempo de bsqueda O(log n)), pero la informacin est ordenada en todo momento.

Tabla hash

75

Funcionamiento
Las operaciones bsicas implementadas en las tablas hash son: insercin(llave, valor) bsqueda(llave) que devuelve valor La mayora de las implementaciones tambin incluyen borrar(llave). Tambin se pueden ofrecer funciones como iteracin en la tabla, crecimiento y vaciado. Algunas tablas hash permiten almacenar mltiples valores bajo la misma clave. Para usar una tabla hash se necesita: Una estructura de acceso directo (normalmente un array). Una estructura de datos con una clave Una funcin resumen (hash) cuyo dominio sea el espacio de claves y su imagen (o rango) los nmeros naturales.

Insercin
1. Para almacenar un elemento en la tabla hash se ha de convertir su clave a un nmero. Esto se consigue aplicando la funcin resumen (hash) a la clave del elemento. 2. El resultado de la funcin resumen ha de mapearse al espacio de direcciones del vector que se emplea como soporte, lo cual se consigue con la funcin mdulo. Tras este paso se obtiene un ndice vlido para la tabla. 3. El elemento se almacena en la posicin de la tabla obtenido en el paso anterior. 1. Si en la posicin de la tabla ya haba otro elemento, se ha producido una colisin. Este problema se puede solucionar asociando una lista a cada posicin de la tabla, aplicando otra funcin o buscando el siguiente elemento libre. Estas posibilidades han de considerarse a la hora de recuperar los datos.

Bsqueda
1. Para recuperar los datos, es necesario nicamente conocer la clave del elemento, a la cual se le aplica la funcin resumen. 2. El valor obtenido se mapea al espacio de direcciones de la tabla. 3. Si el elemento existente en la posicin indicada en el paso anterior tiene la misma clave que la empleada en la bsqueda, entonces es el deseado. Si la clave es distinta, se ha de buscar el elemento segn la tcnica empleada para resolver el problema de las colisiones al almacenar el elemento.

Prcticas recomendadas para las funciones hash


Una buena funcin hash es esencial para el buen rendimiento de una tabla hash. Las colisiones son generalmente resueltas por algn tipo de bsqueda lineal, as que si la funcin tiende a generar valores similares, las bsquedas resultantes se vuelven lentas. En una funcin hash ideal, el cambio de un simple bit en la llave (incluyendo el hacer la llave ms larga o ms corta) debera cambiar la mitad de los bits del hash, y este cambio debera ser independiente de los cambios provocados por otros bits de la llave. Como una funcin hash puede ser difcil de disear, o computacionalmente cara de ejecucin, se han invertido muchos esfuerzos en el desarrollo de estrategias para la resolucin de colisiones que mitiguen el mal rendimiento del hasheo. Sin embargo, ninguna de estas estrategias es tan efectiva como el desarrollo de una buena funcin hash de principio. Es deseable utilizar la misma funcin hash para arrays de cualquier tamao concebible. Para esto, el ndice de su ubicacin en el array de la tabla hash se calcula generalmente en dos pasos: 1. Un valor hash genrico es calculado, llenando un entero natural de mquina.

Tabla hash 2. Este valor es reducido a un ndice vlido en el vector encontrando su mdulo con respecto al tamao del array. El tamao del vector de las tablas hash es con frecuencia un nmero primo. Esto se hace con el objetivo de evitar la tendencia de que los hash de enteros grandes tengan divisores comunes con el tamao de la tabla hash, lo que provocara colisiones tras el clculo del mdulo. Sin embargo, el uso de una tabla de tamao primo no es un sustituto a una buena funcin hash. Un problema bastante comn que ocurre con las funciones hash es el aglomeramiento. El aglomeramiento ocurre cuando la estructura de la funcin hash provoca que llaves usadas comnmente tiendan a caer muy cerca unas de otras o incluso consecutivamente en la tabla hash. Esto puede degradar el rendimiento de manera significativa, cuando la tabla se llena usando ciertas estrategias de resolucin de colisiones, como el sondeo lineal. Cuando se depura el manejo de las colisiones en una tabla hash, suele ser til usar una funcin hash que devuelva siempre un valor constante, como 1, que cause colisin en cada insercin. Funciones Hash ms usadas: 1. Hash de Divisin: Dado un diccionario D, se fija un nmero m >= |D| (m mayor o igual al tamao del diccionario) y que sea primo no cercano a potencia de 2 o de 10. Siendo k la clave a buscar y h(k) la funcin hash, se tiene h(k)=k%m (Resto de la divisin k/m). 2. Hash de Multiplicacin Si por alguna razn, se necesita una tabla hash con tantos elementos o punteros como una potencia de 2 o de 10, ser mejor usar una funcin hash de multiplicacin, independiente del tamao de la tabla. Se escoge un tamao de tabla m >= |D| (m mayor o igual al tamao del diccionario) y un cierto nmero irracional (normalmente se usa 1+5^(1/2)/2 o 1-5^(1/2)/2). De este modo se define h(k)= Suelo(m*Parte fraccionaria(k*))

76

Resolucin de colisiones
Si dos llaves generan un hash apuntando al mismo ndice, los registros correspondientes no pueden ser almacenados en la misma posicin. En estos casos, cuando una casilla ya est ocupada, debemos encontrar otra ubicacin donde almacenar el nuevo registro, y hacerlo de tal manera que podamos encontrarlo cuando se requiera. Para dar una idea de la importancia de una buena estrategia de resolucin de colisiones, considerese el siguiente resultado, derivado de la paradoja de las fechas de nacimiento. Aun cuando supongamos que el resultado de nuestra funcin hash genera ndices aleatorios distribuidos uniformemente en todo el vector, e incluso para vectores de 1 milln de entradas, hay un 95% de posibilidades de que al menos una colisin ocurra antes de alcanzar los 2.500 registros. Hay varias tcnicas de resolucin de colisiones, pero las ms populares son encadenamiento y direccionamiento abierto.

Tabla hash

77

Direccionamiento Cerrado, Encadenamiento separado o Hashing abierto


En la tcnica ms simple de encadenamiento, cada casilla en el array referencia una lista de los registros insertados que colisionan en la misma casilla. La insercin consiste en encontrar la casilla correcta y agregar al final de la lista correspondiente. El borrado consiste en buscar y quitar de la lista. La tcnica de encadenamiento tiene ventajas sobre direccionamiento abierto. Primero el borrado es simple y segundo el crecimiento de la tabla puede ser pospuesto durante mucho ms tiempo dado que el rendimiento disminuye mucho ms lentamente incluso cuando todas las casillas ya estn ocupadas. De hecho, muchas tablas hash encadenadas pueden no requerir crecimiento nunca, dado que la degradacin de rendimiento es lineal Ejemplo de encadenamiento. en la medida que se va llenando la tabla. Por ejemplo, una tabla hash encadenada con dos veces el nmero de elementos recomendados, ser dos veces ms lenta en promedio que la misma tabla a su capacidad recomendada. Las tablas hash encadenadas heredan las desventajas de las listas ligadas. Cuando se almacenan cantidades de informacin pequeas, el gasto extra de las listas ligadas puede ser significativo. Tambin los viajes a travs de las listas tienen un rendimiento de cach muy pobre. Otras estructuras de datos pueden ser utilizadas para el encadenamiento en lugar de las listas ligadas. Al usar rboles auto-balanceables, por ejemplo, el tiempo terico del peor de los casos disminuye de O(n) a O(log n). Sin embargo, dado que se supone que cada lista debe ser pequea, esta estrategia es normalmente ineficiente a menos que la tabla hash sea diseada para correr a mxima capacidad o existan ndices de colisin particularmente grandes. Tambin se pueden utilizar vectores dinmicos para disminuir el espacio extra requerido y mejorar el rendimiento del cach cuando los registros son pequeos.

Tabla hash

78

Direccionamiento abierto o Hashing cerrado


Las tablas hash de direccionamiento abierto pueden almacenar los registros directamente en el array. Las colisiones se resuelven mediante un sondeo del array, en el que se buscan diferentes localidades del array (secuencia de sondeo) hasta que el registro es encontrado o se llega a una casilla vaca, indicando que no existe esa llave en la tabla. Las secuencias de socorridas incluyen: sondeo lineal en el que el intervalo entre cada intento es constante (frecuentemente 1). sondeo cuadrtico en el que el intervalo entre los intentos aumenta linealmente (por lo que los ndices son descritos por una funcin cuadrtica), y doble hasheo en el que el intervalo entre intentos es constante para cada registro pero es calculado por otra funcin hash.
Ejemplo de direccionamiento abierto.

sondeo

ms

El sondeo lineal ofrece el mejor rendimiento del cach, pero es ms sensible al aglomeramiento, en tanto que el doble hasheo tiene pobre rendimiento en el cach pero elimina el problema de aglomeramiento. El sondeo cuadrtico se sita en medio. El doble hasheo tambin puede requerir ms clculos que las otras formas de sondeo. Una influencia crtica en el rendimiento de una tabla hash de direccionamiento abierto es el porcentaje de casillas usadas en el array. Conforme el array se acerca al 100% de su capacidad, el nmero de saltos requeridos por el sondeo puede aumentar considerablemente. Una vez que se llena la tabla, los algoritmos de sondeo pueden incluso caer en un crculo sin fin. Incluso utilizando buenas funciones hash, el lmite aceptable de capacidad es normalmente 80%. Con funciones hash pobremente diseadas el rendimiento puede degradarse incluso con poca informacin, al provocar aglomeramiento significativo. No se sabe a ciencia cierta qu provoca que las funciones hash generen aglomeramiento, y es muy fcil escribir una funcin hash que, sin querer, provoque un nivel muy elevado de aglomeramiento.

Ventajas e inconvenientes de las tablas hash


Una tabla hash tiene como principal ventaja que el acceso a los datos suele ser muy rpido si se cumplen las siguientes condiciones: Una razn de ocupacin no muy elevada (a partir del 75% de ocupacin se producen demasiadas colisiones y la tabla se vuelve ineficiente). Una funcin resumen que distribuya uniformemente las claves. Si la funcin est mal diseada, se producirn muchas colisiones. Los inconvenientes de las tablas hash son: Necesidad de ampliar el espacio de la tabla si el volumen de datos almacenados crece. Se trata de una operacin costosa. Dificultad para recorrer todos los elementos. Se suelen emplear listas para procesar la totalidad de los elementos.

Tabla hash Desaprovechamiento de la memoria. Si se reserva espacio para todos los posibles elementos, se consume ms memoria de la necesaria; se suele resolver reservando espacio nicamente para punteros a los elementos.

79

Implementacin en pseudocdigo
El pseudocdigo que sigue es una implementacin de una tabla hash de direccionamiento abierto con sondeo lineal para resolucin de colisiones y progresin sencilla, una solucin comn que funciona correctamente si la funcin hash es apropiada. registro par { llave, valor } var vector de pares casilla[0..numcasillas-1] function buscacasilla(llave) { i := hash(llave) mdulo de numcasillas loop { if casilla[i] esta libre or casilla[i].llave = llave return i i := (i + 1) mdulo de numcasillas } } function busqueda(llave) i := buscacasilla(llave) if casilla[i] est ocupada // llave est en la tabla return casilla[i].valor else // llave no est en la tabla return no encontrada function asignar(llave, valor) { i := buscacasilla(llave) if casilla[i] est ocupada casilla[i].valor := valor else { if tabla casi llena { hacer tabla ms grande (nota 1) i := buscacasilla(llave) } casilla[i].llave := llave casilla[i].valor := valor } }

Tabla hash

80

Implementacin en Java
En este mtodo no se requiere que los elementos estn ordenados. El mtodo consiste en asignar el ndice a cada elemento mediante una transformacin del elemento, esto se hace mediante una funcin de conversin llamada funcin hash. Hay diferentes funciones para transformar el elemento y el nmero obtenido es el ndice del elemento. La principal forma de transformar el elemento es asignarlo directamente, es decir al 0 le corresponde el ndice 0, al 1 el 1, y as sucesivamente pero cuando los elementos son muy grandes se desperdicia mucho espacio ya que necesitamos arreglo grandes para almacenarlos y estos quedan con muchos espacios libres, para utilizar mejor el espacio se utilizan funciones ms complejas. La funcin de hash ideal debera ser biyectiva, esto es, que a cada elemento le corresponda un ndice, y que a cada ndice le corresponda un elemento, pero no siempre es fcil encontrar esa funcin, e incluso a veces es intil, ya que puedes no saber el nmero de elementos a almacenar. La funcin de hash depende de cada problema y de cada finalidad, y se pueden utilizar con nmeros o cadenas, pero las ms utilizadas son:

Restas Sucesivas
Esta funcin se emplea con claves numricas entre las que existen huecos de tamao conocido, obtenindose direcciones consecutivas. Un ejemplo seran los alumnos de ingeniera en sistemas que entraron en el ao 2005 sus nmeros de control son consecutivos y est definido el nmero de alumnos. 05210800 -05210800 0 05210801 -05210800 1 05210802 -05210800 2 05210899 -05210800 99

Aritmtica Modular
El ndice de un nmero es resto de la divisin de ese nmero entre un nmero N prefijado, preferentemente primo. Los nmeros se guardarn en las direcciones de memoria de 0 a N-1. Este mtodo tiene el problema de que dos o ms elementos pueden producir el mismo residuo y un ndice puede ser sealado por varios elementos. A este fenmeno se le llama colisin. Si el nmero N es el 7, los nmeros siguientes quedan transformados en: 1679 6 4567 3 8471 1 0435 1 5033 0 Mientras ms grande sea nmero de elementos es mejor escoger un nmero primo mayor para seccionar el arreglo en ms partes. El nmero elegido da el nmero de partes en que se secciona el arreglo, y las cada seccin est compuesta por todos los elementos que arrojen el mismo residuo, y mientras ms pequeas sean las secciones la bsqueda se agilizara ms que es lo que nos interesa.

Tabla hash

81

Mitad del Cuadrado


Consiste en elevar al cuadrado la clave y coger las cifras centrales. Este mtodo tambin presenta problemas de colisin. 709^2=502681 26 456^2=207936 79 105^2=011025 10 879^2=772641 26 619^2=383161 31 Nota: en caso de que la cifra resultante sea impar se toma el valor nmero y el anterior.

Truncamiento
Consiste en ignorar parte del nmero y utilizar los elementos restantes como ndice. Tambin se produce colisin. Por ejemplo, si un nmero de 7 cifras se debe ordenar en un arreglo de elementos, se pueden tomar el segundo, el cuarto y el sexto para formar un nuevo nmero: 5700931 703 3498610 481 0056241 064 9134720 142 5174829 142

Plegamiento
Consiste en dividir el nmero en diferentes partes, y operar con ellas (normalmente con suma o multiplicacin). Tambin se produce colisin. Por ejemplo, si dividimos el nmero de 7 cifras en 2, 2 y 3 cifras y se suman, dar otro nmero de tres cifras (y si no, se toman las tres ltimas cifras): 5700931 > 57 + 00 + 931 = 988 3498610 34 + 98 + 610 = 742 0056241 00 + 56 + 241 = 297 9134720 91 + 34 + 720 = 845 5174929 51 + 74 + 929 = 1054 Nota: Estas solo son sugerencias y que con cada problema se pude implementar una nueva funcin hash que incluso tu puedes inventar o formular.

Tratamiento de Colisiones
Hay diferentes maneras de solucionarlas pero lo ms efectivo es en vez de crear un arreglo de nmero, crear un arreglo de punteros, donde cada puntero seala el principio de una lista enlazada. As, cada elemento que llega a un determinado ndice se pone en el ltimo lugar de la lista de ese ndice. El tiempo de bsqueda se reduce considerablemente, y no hace falta poner restricciones al tamao del arreglo, ya que se pueden aadir nodos dinmicamente a la lista.

Tabla hash

82

Prueba Lineal
Consiste en que una vez detectada la colisin se debe recorrer el arreglo secuencialmente a partir del punto de colisin, buscando al elemento. El proceso de bsqueda concluye cuando el elemento es hallado, o bien cuando se encuentra una posicin vaca. Se trata al arreglo como a una estructura circular: el siguiente elemento despus del ltimo es el primero. La funcin de rehashing es, por tanto, de la forma: R(H(X)) = (H(X) + 1) % m (siendo m el tamao del arreglo) Ejemplo: Si la posicin 397 ya estaba ocupada, el registro con clave 0596397 es colocado en la posicin 398, la cual se encuentra disponible. Una vez que el registro ha sido insertado en esta posicin, otro registro que genere la posicin 397 o la 398 es insertado en la posicin siguiente disponible. public class Principal { public static void main(String[] args) { try { int i, n, resp; int m = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el tamao de la tabla")); Hash[] h = new Hash[m]; for (i = 0; i < m; i++) { h[i] = new Hash(); h[i].estado = 0; } do { resp = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Men Principal nn" + "Insertar (1)nBuscar (2)nEliminar (3)nSalir (4)")); switch (resp) { case 1: n = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el nmero a ser insertado en la tabla:")); Hash.insertaHash(h, m, n); break; case 2: n = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el nmero a ser buscado en la tabla:")); i = Hash.buscaHash(h, m, n); if (i == -1) { javax.swing.JOptionPane.showMessageDialog(null, "Nmero no encontrado"); } else { javax.swing.JOptionPane.showMessageDialog(null, "Nmero encontrado"); } break;

Tabla hash case 3: n = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el nmero a ser eliminado de la tabla:")); i = Hash.eliminaHash(h, m, n); if (i == -1) { javax.swing.JOptionPane.showMessageDialog(null, "Nmero no encontrado"); } else { javax.swing.JOptionPane.showMessageDialog(null, "Nmero eliminado con xito"); } break; case 4: System.exit(0); default: } } while (resp != 4); } catch (NumberFormatException nfe) { javax.swing.JOptionPane.showMessageDialog(null, "Est Saliendo del Programa"); } catch (OutOfMemoryError ome) { javax.swing.JOptionPane.showMessageDialog(null, "No Hay Espacio"); } } } public class Hash { int dato; int estado; //0 = Vaco, 1 = Eliminado, 2 = Ocupado static int funcion(int n, int m) { return ((n + 1) % m); } static void insertaHash(Hash[] h, int m, int n) { boolean i = false; int j = funcion(n, m); do { if (h[j].estado == 0 || h[j].estado == 1) { h[j].dato = n; h[j].estado = 2; i = true; } else {

83

Tabla hash j++; } } while (j < m && !i); if (i) { javax.swing.JOptionPane.showMessageDialog(null, "Elemento insertado con xito!"); } else { javax.swing.JOptionPane.showMessageDialog(null, "Tabla llena!"); } } static int buscaHash(Hash[] h, int m, int n) { int j = funcion(n, m); while (j < m) { if (h[j].estado == 0) { return -1; } else if (h[j].dato == n) { if (h[j].estado == 1) { return -1; } else { return j; } } else { j++; } } return -1; } static int eliminaHash(Hash[] h, int m, int n) { int i = buscaHash(h, m, n); if (i == -1) { return -1; } else { h[i].estado = 1; return 1; } } }

84

Tabla hash

85

Hash Dinmico
Las tablas hash se presentaron como una alternativa hacia las estructuras tipo rbol ya que permitan el almacenamiento de grandes volmenes de informacin y algoritmos eficientes para la administracin sobre estas estructuras (insercin, eliminacin y bsqueda). Sin embargo, presentan 2 grandes problemas: 1. No existen funciones hash perfectas que permitan asegurar que por cada transformacin de un elemento habr una nica correspondencia en la clave que contiene este elemento. 2. Son estructuras estticas que no pueden crecer ya que necesitan un tamao fijo para el funcionamiento de la estructura. Para solucionar el segundo problema se implementa la utilizacin de mtodos totales y mtodos parciales. Convirtiendo la tabla hash en una estructura dinmica capaz de almacenar un flujo de informacin y no una cantidad fija de datos.

Mtodos Totales
Mtodo de las expansiones totales El mtodo de las expansiones totales consiste en realizar una duplicacin del tamao del arreglo establecido para realizar la tabla hash, esta expansin se ejecuta cuando se supera la densidad de ocupacin . As si se tiene una tabla hash de tamao N, al realizar la expansin total se obtendr una tabla hash de 2N, al realizar una segunda expansin se obtendr una tabla hash de 4N, al realizar una tercera expansin se obtendr una tabla hash de 8N y en general el tamao de la tabla para una i-sima expansin se define como aparece a continuacin:

Dnde: N: Tamao de la Tabla. i: Nmero de expansiones que se quieren realizar. T: Nuevo tamao de la Tabla. La densidad de ocupacin se define como el cociente entre el nmero de registros ocupados y el nmero de registros disponibles; as se tiene que:

Dnde: ro: Registros Ocupados. rd: Registros Disponibles. o: Densidad de Ocupacin. Cada vez que se pretende insertar un elemento es necesario calcular la densidad de ocupacin, si se supera esta densidad se procede a implementar la expansin. Al realizar cada de una de las expansiones es necesario volver a implementar la funcin hash para cada uno de los registros almacenados en la tabla y volver a insertarlos de nuevo en la tabla. Mtodo de las reducciones totales Este mtodo surge como una consecuencia del mtodo de expansiones totales presentado anteriormente. En este mtodo la densidad de ocupacin disminuye de tal manera que acepta una reduccin del tamao de la tabla hash a la mitad. As si se tiene una tabla hash de N, la primera reduccin dar como resultado la N/2, la segunda reduccin dar como resultado N/4, la tercera reduccin dar N/8 y la i-sima reduccin dar como resultado:

Dnde: N: Tamao de la Tabla. i: Nmero de expansiones que se quieren realizar. T: Nuevo tamao de la Tabla. Para realizar una reduccin la densidad de ocupacin se debe disminuir a un valor menor al rango establecido y los registros se deben eliminar de tal manera que los registros resultantes se puedan ingresar en una tabla hash que posea

Tabla hash la mitad del tamao de la tabla original. Cada vez que se implementa una reduccin es necesario volver a utilizar la funcin hash con cada uno de los registros almacenados.

86

Mtodos Parciales
Mtodo de las expansiones parciales El mtodo de las expansiones parciales consiste en incrementar en un 50% el tamao del arreglo establecido para realizar la tabla hash, esta expansin se ejecuta cuando se supera la densidad de ocupacin. As si se tiene una tabla hash de tamao N, al realizar la expansin parcial se obtendr una tabla hash de 1.5 N, al realizar una segunda expansin se obtendr una tabla hash de 2.25 N, al realizar una tercera expansin se obtendr una tabla hash de 3.375 N y en general el tamao de la tabla para una i-sima expansin se define como: T = ( (1.5) ^ i * N ) Dnde: N: Tamao de la Tabla. i: Nmero de expansiones que se quieren realizar. T: Nuevo tamao de la Tabla. Cada vez que se pretende insertar un elemento es necesario calcular la densidad de ocupacin, si se supera esta densidad se procede a implementar la expansin. Al realizar cada de una de las expansiones es necesario volver a implementar la funcin hash para cada uno de los registros almacenados en la tabla hash y volver a insertarlos de nuevo en la tabla. Mtodo de las reducciones parciales Este mtodo surge como una consecuencia del mtodo de expansiones parciales presentado en la seccin 2.1 de este documento. En este mtodo la densidad de ocupacin disminuye de tal manera que acepta una reduccin del tamao de la tabla hash al 50%. As si se tiene una tabla hash de N, la primera reduccin dar como resultado la 0.5 N, la segunda reduccin dar como resultado 0.25 N, la tercera reduccin dar 0.125 N y la i-sima reduccin dar como resultado: T = ((0.5)^i*N) Dnde: N: Tamao de la Tabla. i: Nmero de reducciones que se quieren realizar. T: Nuevo tamao de la Tabla. Para realizar una reduccin la densidad de ocupacin debe disminuir a un valor menor al rango establecido y los registros se deben eliminar de tal manera que los registros resultantes se puedan ingresar en una tabla hash que posea la mitad del tamao de la tabla original. Cada vez que se implementa una reduccin es necesario volver a utilizar la funcin hash con cada uno de los registros almacenados.

Nota
[1] La reconstruccin de la tabla requiere la creacin de un array ms grande y el uso posterior de la funcin asignar para insertar todos los elementos del viejo array en el nuevo array ms grande. Es comn aumentar el tamao del array exponencialmente, por ejemplo duplicando el tamao del array.

Enlaces externos
Artculos e implementaciones
Artculo donde se explica la implementacin en C y un anlisis de costo-beneficio de una tabla hash (http:// urtevolution.com.ar/blog/?p=1). [Categora:Estructura de datos]]

Funcin hash

87

Funcin hash
A las funciones hash (adopcin ms o menos directa del trmino ingls hash function) tambin se les llama funciones picadillo, funciones resumen o funciones de digest (adopcin ms o menos directa del trmino ingls equivalente digest function)[1][2][3]Una funcin hash H es una funcin computable mediante un algoritmo, H: U M x h(x),
Una funcin de hash en funcionamiento.

que tiene como entrada un conjunto de elementos, que suelen ser cadenas, y los convierte (mapea) en un rango de salida finito, normalmente cadenas de longitud fija. Es decir, la funcin acta como una proyeccin del conjunto U sobre el conjunto M. Observar que M puede ser un conjunto definido de enteros. En este caso podemos considerar que la longitud es fija si el conjunto es un rango de nmeros de enteros ya que podemos considerar que la longitud fija es la del nmero con mayor nmero de cifras. Todos los nmeros se pueden convertir al nmero especificado de cifras simplemente anteponiendo ceros. Normalmente el conjunto U tiene un nmero elevado de elementos y M es un conjunto de cadenas con un nmero ms o menos pequeo de smbolos. Por esto se dice que estas funciones resumen datos del conjunto dominio. La idea bsica de un valor hash es que sirva como una representacin compacta de la cadena de entrada. Por esta razn decimos que estas funciones resumen datos del conjunto dominio.

Orgenes del trmino


El trmino hash proviene, aparentemente, de la analoga con el significado estndar (en ingls) de dicha palabra en el mundo real: picar y mezclar. Donald Knuth cree que H. P. Luhn, empleado de IBM, fue el primero en utilizar el concepto en un memorndum fechado en enero de 1953. Su utilizacin masiva no fue hasta despus de 10 aos.

Terminologa asociada
Al conjunto U se le llama dominio de la funcin hash. A un elemento de U se le llama preimagen o dependiendo del contexto clave o mensaje. Al conjunto M se le llama imagen de la funcin hash. A un elemento de M se le llama valor hash, cdigo hash o simplemente hash. Se dice que se produce una colisin cuando dos entradas distintas de la funcin de hash producen la misma salida. De la definicin de funcin hash podemos decir que U, el dominio de la funcin, puede tener infinitos elementos. Sin embargo M, el rango de la funcin, tiene un nmero finito de elementos debido a que el tamao de sus cadenas es fijo. Por tanto la posibilidad de existencia de colisiones es intrnseca a la definicin de funcin hash. Una buena funcin de hash es una que tiene pocas colisiones en el conjunto esperado de entrada. Es decir, se desea que la probabilidad de colisin sea muy baja.

Funcin hash

88

Parmetros adicionales
La definicin formal dada, a veces se generaliza para poder aprovechar las funciones hash en otros mbitos. Para ello a la funcin hash se le aaden nuevos parmetros de forma que el valor hash no es slo funcin del contenido en s, sino adems de otros nuevos factores. Para hallar valores hash de ficheros a veces se usan, adems del contenido en s, diversos parmetros como el nombre del archivo, su longitud, hora de creacin, etc. Otras veces se aaden parmetros que permiten configurar el comportamiento de la funcin. Por ejemplo, la funcin hash puede recibir como parmetro una funcin de generacin de valores pseudoaleatorios que es usada dentro del algoritmo de la funcin hash. Otros ejemplos de parmetros son el uso de valores sal, el uso de claves secretas, el uso de parmetros que especifican el rango de la funcin (funciones hash de rango variable), el uso de parmetros que especifican el nivel de seguridad que se quiere en el valor hash de salida (funciones hash dinmicas),....

Funciones hash con clave


Una funcin hash con clave HK (en ingls keyed hash function) es una funcin hash H que tiene un parmetro secreto K que pertenece al conjunto posible de claves y en la que para una entrada x, hK(x) es el valor hash de x. Al resto de funciones hash se dice que son sin clave (en ingls unkeyed hash function).

Propiedades
La calidad de una funcin hash viene definida con base en la satisfaccin de ciertas propiedades deseables en el contexto en el que se va a usar.

Bajo costo
Calcular el valor hash necesita poco costo (computacional, de memoria,...).

Compresin
Una funcin hash comprime datos si puede mapear un dominio con datos de longitud muy grande a datos con longitud ms pequea

Uniforme
Se dice que una funcin hash es uniforme cuando para una clave elegida aleatoriamente es igualmente probable tener un valor hash determinado, independientemente de cualquier otro elemento. Para una funcin hash H uniforme del tipo H:{0,1}m{0,1}n, es decir: Las cadenas estn construidas sobre un alfabeto de 2 smbolos (Alfabeto binario) El dominio es el conjunto de las cadenas de longitud m El rango es el conjunto de las cadenas de longitud n podemos decir que a cada resumen le corresponde 2m-n mensajes y que la probabilidad de que dos mensajes den como resultado la misma salida es 2-n Para algoritmos de bsqueda, si todas las entradas son igualmente probables, se busca esta propiedad para minimizar el nmero de colisiones ya que cuantas ms colisiones haya, ser mayor el tiempo de ejecucin de las bsquedas.

Funcin hash

89

De rango variable
En algunas funciones hash el rango de valores hash puede ser diferente a lo largo del tiempo. Ejemplo: Funciones hash usadas para tablas hash que necesitan expandirse. En estos caso a la funcin hash se le debe pasar un parmetro que le permita saber en qu rango se mueve la ejecucin para hallar el valor hash.

Inyectividad. Funcin hash perfecta


Se dice que la funcin hash es inyectiva cuando cada dato de entrada se mapea a un valor hash diferente. En este caso se dice que la funcin hash es perfecta. Para que se d, es necesario que la cardinalidad del conjunto dominio sea inferior o igual a la cardinalidad del conjunto imagen. Normalmente slo se dan funciones hash perfectas cuando las entradas estn preestablecidas. Ejemplo:Mapear los das del ao en nmeros del 1 al 366 segn el orden de aparicin. Formalizacin: implica Cuando no se cumple la propiedad de inyectividad se dice que hay colisiones. Hay una colisin cuando y

Determinista
Una funcin hash se dice que es determinista cuando dada una cadena de entrada siempre devuelve el mismo valor hash. Es decir, el valor hash es el resultado de aplicar un algoritmo que opera slo sobre la cadena de entrada. Ejemplos de funciones hash no-deterministas son aquellas funciones hash que dependen de parmetros externos, tales como generadores de nmeros pseudoaleatorios o la fecha. Tampoco son deterministas aquellas funciones hash que dependen de la direccin de memoria en la que est almacenada la cadena de entrada. Esa direccin es accidental y no se considera un cambio de la cadena entrada en s. De hecho puede cambiar dinmicamente durante la propia ejecucin del algoritmo de la funcin hash.

Propiedades para analizar la resistencia frente a colisiones


El estudio de este tipo de propiedades es muy til en el campo de la criptografa para los llamados 'cdigos de deteccin de modificaciones'. Resistencia a la primera imagen
[4]

Se dice que una funcin hash tiene resistencia a la primera preimagen o simplemente que tiene resistencia a preimagen (del ingls preimage-resistant) si dado un valor hash y, es computacionalmente intratable encontrar un x, tal que h(x)=y. Resistencia a la segunda preimagen
[5]

Se dice que una funcin hash tiene resistencia a la segunda preimagen (en ingls second preimage-resistant) si dado un mensaje x, es computacionalmente intratable encontrar un x', , tal que h(x)=h(x'). Resistencia a colisiones (CRHF)
[6]

Se dice que una funcin hash tiene resistencia a colisiones o que es resistente a colisiones o CRHF (del ingls Collision Resistant Hash Function) si encontrar un par con tal que es computacionalmente intratable. Es decir, es difcil encontrar dos entradas que tengan el mismo valor hash. Como encontrar una segunda preimagen no puede ser ms fcil que encontrar una colisin, entonces la resistencia a colisiones incluye la propiedad de resitencia a la segunda preimagen.[7][8] Por otro lado se puede decir que la mayora de las funciones hash CRHFs son resistentes a preimagen.[9] La resistencia a colisisiones implica resistencia

Funcin hash a preimagen para funciones hash con salida aleatoria uniforme.[10] En algunos trabajos a estas funciones se les llama funciones hash de un slo sentido fuertes (del ingls strong one way hash function) para resaltar que es fuerte debido a que hay libre eleccin de los dos valores x e y. Funcin hash de un solo sentido (OWHF)
[11]

90

Una funcin hash se dice que es una funcin hash de un solo sentido o que es OWHF (del ingls One-Way Hash Function) si tiene las propiedades de resistencia a preimagen y de resistencia a segunda preimagen. Es decir, es difcil encontrar una entrada cuya hash sea un valor hash preespecificado. Observar que es diferente a la definicin general que se hace de funciones de un solo sentido:
[12]

Una funcin se dice que es una funcin de un solo sentido o que es OWF si para cada x del dominio de la funcin, es fcil computar f(x), pero para todo y del rango de f, es computacionalmente intratable encontrar cualquier x tal que y=f(x). La diferencia entre OWHF y OWF es que OWF no requiere que sea funcin hash ni que sea resistente a segunda preimagen. En algunos trabajos a estas funciones se les llama funciones hash de un slo sentido dbiles (del ingls strong one way hash function) para resaltar que es dbil en contraste con CRHF (que es fuerte) debido a que al cumplir la propiedad de resistencia a segunda preimagen no hay libre eleccin en la seleccin del valor x, y por tanto del valor h(x), en el que se tiene que producir la colisin. Resistencia a la casi colisin
[13]

H es resistente a la casi colisin (en ingls near-colission resistance) si es difcil encontrar dos mensajes con para las cuales sus imgenes y difieran solamente en unos pocos bits.

[14]

Por ejemplo podemos tener una funcin resistente a colisiones de 256 bits que no es resistente a la casi colisin porque se pueden encontrar casi-colisiones para los 224 bits de ms a la izquierda. Resistencia a las preimgenes parciales
[15]

Una funcin hash tiene resistencia a preimgenes parciales (en ingls Partial-preimage resistance) si es difcil encontrar una parte de la preimagen de un valor hash incluso conociendo el resto de la preimagen. Es decir, se debe recurrir a la fuerza bruta: si se desconocen t bits de la preimagen, se deben realizar en promedio 2n-t operaciones de hash encontrarlo. A una funcin hash resistente a preimgenes parciales tambin se le dice que es localmente de un slo sentido (del ingls local one-wayness).

Con normalizacin de datos


En algunas aplicaciones, las cadenas de entrada pueden contener caractersticas que son irrelevantes cuando comparamos las cadenas. Por ejemplo en algunas aplicaciones las maysculas pueden ser irrelevantes. Por tanto para hallar el valor hash es interesante ignorar las distinciones no relevantes entre las cadenas de entrada. De esta forma cadenas distintas con diferencias no relevantes, tienen asociados valores hash iguales.

Continuidad. Efecto avalancha


Se dice que una funcin es continua cuando una modificacin minscula (ej un bit) en la cadena de entrada ocasiona pequeos cambios en el valor hash. En una funcin hash se dice que no hay correlacin cuando los bits de las cadenas de entrada y los bits de las cadenas de salida no estn relacionados, es decir cuando una modificacin minscula (ej un bit) en la cadena de entrada ocasiona cambios en el valor hash comparables a un cambio de cualquier otro tipo. Por tanto cualquier

Funcin hash cambio en el mensaje original idealmente hace que cada uno de cualquier bit del valor hash resultante cambie con probabilidad 0.5. Cuando esto sucede (o casi) se dice que se produce un efecto avalancha En funciones hash usadas para bsqueda normalmente se buscan funciones tan continuas como sea posible; de forma que entradas que difieran un poco deberan tener valores hash similares o iguales. Sin embargo la continuidad no es deseable para funciones hash usadas para sumas de verificacin o funciones criptogrficas por evidentes razones.

91

Resistencia a la computacin de nuevos valores hash


[16]

Una funcin hash con clave K,

se dice que tiene resistencia a la computacin de nuevos valores hash no puede ser

(en ingls Computation-resistance) si a partir de un rango de pares conocidos

computado para un nuevo dato x con para cualquier i, sin que K sea conocida. Observar que la propiedad anterior implica que no debera ser posible calcular K a partir de un rango de pares conocidos . A esta propiedad se la llama propiedad de no recuperacin de clave (en ingls key non-recovery). El estudio de este tipo de propiedades son muy tiles en el campo de la criptografa para los llamados 'cdigos de autenticacin de mensajes'

Familias de funciones hash y propiedades asociadas


Motivacin[17]
Podramos imaginarnos un algoritmo probabilstico de tiempo polinomial con dos mensajes codificados en el algoritmo que dan lugar a una colisin para una especfica funcin hash. El algoritmo simplemente devolvera los dos mensajes que causan la colisin. Crear tal algoritmo puede ser extremadamente difcil, pero una vez construido podra ser ejecutado en tiempo polinomial. Sin embargo, definiendo una familia de funciones hash como una familia infinita de funciones hash nos impide que la bsqueda de este algoritmo tenga xito para todas las funciones hash de la familia, porque hay infinitas. Por tanto las familias hash nos proporcionan un mecanismo interesante para el estudio y categorizacin de las funciones hash respecto a su fortaleza frente a la bsqueda de colisiones por parte de un adversario. Este tipo de estudios es muy til en el campo de la criptografa para los llamados 'cdigos de deteccin de modificaciones'.

Concepto
Sea , el dominio de la funcin, sea el rango de la funcin. Sea el conjunto de todas las posibles claves (tericamente es infinito aunque en la prctica es finito), Una familia de funciones hash (notacin equivalente es un conjunto infinito de funciones hash de la forma , donde cada funcin de la familia es indexada por una clave que

cumple las siguientes propiedades: es accesible, es decir hay un algoritmo probabilstico de tiempo polinomial, que sobre una entrada devuelve una instancia es muestreable, es decir, hay un algoritmo probabilstico de tiempo polinomial, que selecciona uniformemente elementos de entrada . computa . es computable en tiempo polinomial, es decir, hay un algoritmo de tiempo polinomial (en l) que sobre una

Ejemplo: SHA-1 es una sola instancia de funcin hash, no una familia. Sin embargo SHA-1 puede ser modificado para construir una familia finita de funciones. M. Bellare y P. Rogaway[18] modificaron SHA-1 de tal forma que la claves especifica las constantes usadas en la cuarta ronda de las funciones. En este caso el tamao de la clave es de 128 bits y por tanto , y .

Funcin hash Observar que en la definicin de una funcin hash el dominio se puede formalizar como , sin embargo en una . Esto es

92

funcin hash definida como instancia de un elemento de una familia de funciones hash el dominio es

debido a que para que se cumplan las propiedades de seguridad es necesario que el dominio sea muestreado uniformemente en tiempo polinomial. Una familia de funciones puede siempre ser definida con aquel tamao apropiado para acomodar cualquier mensaje que sea necesario.

Familia de funciones hash resistente a colisiones


De forma informal una familia de funciones es familia de funciones hash resistente a colisiones, tambin llamadas CRHF por sus siglas en ingls (Collision Resistant Hash Function), dada una funcin escogida aleatoriamente de la familia, un adversario es incapaz de obtener una colisin para ella.[19] Definicin formal
[20]

Se dice que una familia de funciones hash es una (t,)-familia hash resistente a colisiones

con la forma un y obtiene como

con n,l y k enteros positivos y n>=l, que satisfacen la siguiente condicin: Sea buscador de colisiones de cadenas que para un entrada K en el espacio de claves usa tiempo salida , un par tal que . Observar que la probabilidad es tomada sobre las elecciones aleatorias de . Mirando esta definicin se ve que son interesantes aquellas familias que tienen un t/ suficientemente grande. Estrictamente hablando hablamos de familias CRHF pero por simplicidad se suele hablar simplemente de CRHF. . Para cada ,

La definicin no se mete en cmo se eligen las funciones hash de la familia. Este punto es crucial.[21] En realidad, en cualquier aplicacin de funciones hash resistentes a colisiones, alguna parte P tienen que elegir una funcin de la familia de forma aleatoria para producir la descripcin de la funcin. Es importante distinguir entre dos casos: La eleccin aleatoria se puede hacer pblica (o 'public-coin'). La eleccin aleatoria puede ser revelada como parte de la descripcin de la funcin. La eleccin aleatoria se tiene que mantener secreta (o 'secret-coin'). La revelacin la eleccin aleatoria realizada puede que permita encontrar colisiones. Por tanto P tiene que mantener secreta la eleccin despus de producir la descripcin de la funcin. Evidentemente una familia CRHF elegible de forma pblica (public-coin) tambin puede trabajar si uno elige o mantiene la eleccin de forma privada (secret-coin).

Funcin hash universal


Una funcin hash universal es un familia de funciones donde la probabilidad de colisin entre dos textos escogidos es despreciable.[22] Definicin formal[23] Una k-familia de funciones hash universal es un conjunto H de funciones elemento
[24]

tal que para cada .

y todos los (no necesariamente distintos)

Una familia de funciones hash

es -casi universal o -AU (del ingls -almost universal) si es menor que la

probabilidad de que dos entradas distintas m,n tengan el mismo valor hash asociado, estando la funcin hash elegida aleatoriamente entre los miembros de . De la definicin se percibe que son interesantes aquellas familias que tienen un valor pequeo de indicando que el adversario no puede encontrar un par de entradas que producen el mismo valor hash, para una funcin hash elegida aleatoriamente de entre los elementos la familia.

Funcin hash

93

Familia de funciones hash universal de un solo sentido


Una familia de funciones hash universal de un solo sentido, tambin llamadas UOWHF por sus siglas en ingls (Universal One-Way Hash Function), es una familia de funciones hash universales donde, elegida una clave K aleatoriamente en el espacio de claves, dada una cadena x con valor hash hK(x) es difcil encontrar un x' distinta de x tal que hK(x)=hK(x'). Al par (x,x') se le llama par de colisin Definicin formal
[25][26]

Se dice que una familia de funciones hash

es (t,)-funcin hash universal de un slo sentido (UOWHF)

si no existe ningn adversario que en tiempo menor que t pueda ganar el siguiente juego con probabilidad mayor o igual que : El adversario escoge un valor x del Rango, entonces recibe una clave K del espacio de claves escogida de forma aleatoria. El juego se gana si encuentra un x' tal que hK(x)= hK(x'). El adversario est compuesto por dos algoritmos . slo tiene como parmetro de entrada el conjunto de la familia de funciones hash. Produce como salida x y

State. x es el valor hash objetivo y State es alguna informacin extra que puede ayudar a A2 a encontrar la colisin. tiene como parmetros de entrada K,x y State y produce como salida x' por tanto . siendo un par con tal que hK(x)= hK(x') Observar que, al igual que en la definicin de (t,)-CRHF la probabilidad es tomada sobre las elecciones aleatorias de . La gran diferencia es que aqu la entrada x se fija primero. Mirando esta definicin se ve que son interesantes aquellas familias que tienen un t/ suficientemente grande.

Comparacin UOWHF y CRHF[27]


Una familia UOWHF es una nocin ms dbil que una familia CRHF. En una CRHF, a el oponente primero se le da la clave y despus ella o l tiene que producir la pareja de entradas que colisiona. Encontrar colisiones para un parmetro fijo de una UOWHF, puede que sea bastante ms fcil, pero esto no ayudar a un oponente a violar la seguridad. Simon[28] ha demostrado que existe un orculo relativo a el cual UOWHF existe, pero no CRHF.

Funciones hash iterativas. Construccin de Merkle-Damgrd


[29][30][31]

Muchas funciones hash se construyen mediante el proceso iterativo siguiente hasta conseguir el valor hash de la entrada X, h(X): El nmero de bits de la entrada X (en principio de longitud arbitraria) tiene que ser mltiplo de la longitud de bloque. Para conseguirlo se tiene una regla de padding que alarga la entrada a una longitud aceptable. Normalmente esta regla consiste en aadir al final de la entrada unos smbolos adicionales a los que se llama relleno o padding. Se divide la entrada en bloques de longitud fija. Obteniendo un conjunto de bloques x1,...,xt. Se realiza un proceso iterativo de la siguiente forma: H0=IV Hi=f(xi,Hi-1), i=1,2,...,t y h(X)=g(Ht). Al valor IV se le llama valor inicial y se representa por esas siglas por el trmino ingls Initial Value. A la funcin f se la llama funcin de ronda o funcin de compresin. A la funcin g se la llama transformacin de salida. Lo que hace la funcin g es derivar a partir de Ht tantos bits como se quieran en la salida de la funcin. Frecuentemente

Funcin hash g es la funcin identidad o un truncamiento de Ht. En este tipo de descripcin de funciones hash hay dos elecciones importantes que afectarn a las propiedades que tendr la funcin: La eleccin de la regla de padding. Si lo que se quiere es evitar colisiones es recomendable que la regla de padding no permita que existan dos mensajes que sean rellenados a el mismo mensaje. La eleccin de valor inicial (IV). Debera ser definido como parte de la descripcin de la funcin hash. A las funciones que se construyen mediante el anterior sistema se dice que son son funciones hash iterativas. A esta forma de construccin recursiva se la conoce tambin como de Merkle-Damgrd debido a que fue usado por primera vea por R. Merkle y I. Damgrd independientemente en 1989.

94

Aplicaciones
Las funciones hash son usadas en mltiples campos. Ejemplos: Herramienta bsica para la construccin de utilidades ms complejas: Construccin de estructuras de datos: Su uso en distintas estructuras de datos hacen ms eficientes las bsquedas. Ej. tablas hash. Construccin de esquemas de compromiso. Los esquemas de compromiso permiten que una entidad elija una valor entre un conjunto finito de posibilidades de tal forma que no pueda cambiarla. Esa entidad no tiene que revelar su eleccin hasta si acaso el momento final (la eleccin puede permanecer oculta). Construccin de algoritmos de cifrado/descifrado. Por ejemplo se usa en la construccin de cifradores de flujo y de cifradores de bloque. Construccin de algoritmos generadores de nmeros pseudoaleatorios. Construccin de cadenas pseudoaleatorias. Por ejemplo el llamado modelo de orculo aleatorio se basa en considerar que funciones hash con ciertas propiedades se comportan como funciones que escogen cadenas al azar, se usa para el estudio de la seguridad los esquemas criptogrficos. Construccin de algoritmos de testeo de pertenencia o no a un conjunto.- Se han usado funciones hash para la construccin de acumuladores criptogrficos y filtros de Bloom. Estas tecnologas permiten establecer mecanismos que permiten pronunciarse, a veces con cierto grado de error, sobre la pertenencia o no a cierto conjunto. Construccin de mtodos de generacin de sellos de tiempo confiables. Herramienta para proteger la integridad En la firma digital Como dato que se firma:En los algoritmos de firma convencionales normalmente en lugar de firmar todo el contenido se suele ser firmar slo el valor hash del mismo. Algunas de las motivaciones para hacer esto son:[32] Cuando se usa para firmar algoritmos de firma por bloques donde los mensajes son ms largos que el bloque, no es seguro firmar mensajes bloque a bloque ya que un enemigo podra borrar bloques del mensaje firmado o insertar bloques de su eleccin en el mensaje antes de que sea firmado. Al usar una funcin hash hacemos una transformacin que hace a la firma dependiente de todas las partes del mensaje. Normalmente los valores hash son mucho ms cortos que los datos originales de entrada. Se puede mejorar mucho la velocidad de firma firmando el valor hash en lugar de firmar el dato original. Si los mensajes a firmar pueden tener cierta estructura algebraica y el algoritmo de firma se comporta de forma que el sistema resultante puede ser vulnerable a criptoanlisis con ataques de texto escogido, podemos usar funciones hash para destruir esta estructura algebraica.

Funcin hash Como parte del algoritmo de firma: Se han desarrollado algoritmos de firma que usan funciones hash en el propio algoritmo de firma como una herramienta interna del mismo. Ejemplo de este tipo algoritmos son el esquema de firma de Merkle. Suma de verificacin (del ingls checksum): Cuando queremos almacenar o transmitir informacin, para protegernos frente a errores fortuitos en el almacenamiento o transmisin, es til acompaar a los datos de valores hash obtenidos a partir de ellos aplicando funciones hash con ciertas propiedades de forma que puedan ser usados para verificar hasta cierto punto el propio dato. A el valor hash se le llama Suma de verificacin. Prueba de la integridad de contenidos.- Por ejemplo cuando se distribuye un contenido por la red, y se quiere estar seguro de que lo que le llega al receptor es lo que se est emitiendo, se proporciona un valor hash del contenido de forma que ese valor tiene que obtenerse al aplicar la funcin hash sobre el contenido distribuido asegurando as la integridad. A esto se le suele llamar checksum criptogrfico debido a que es un checksum que requiere el uso de funciones hash criptogrficas para que sea difcil generar otros ficheros falso que tengan el mismo valor hash. Otro ejemplo de uso esta tecnologa para verificar la integridad es calcular y guardar el valor hash de archivos para poder verificar posteriormente que nadie (Ej un virus) los ha modificado. Si en lugar de verificar la integridad de un solo contenido lo que se quiere es verificar la integridad de un conjunto de elementos, se pueden usar algoritmos basados en funciones hash como los rboles de Merkle que se basan en aplicar reiteradamente las funciones hash sobre los elementos del conjunto y sobre los valores hash resultantes. Herramientas vinculadas a la autenticacin y control de acceso Autenticacin de entidades: Por ejemplo es frecuente el uso para este propsito de funciones hash deterministas con clave secreta que tienen ciertas propiedades (Cdigos de autenticacin de mensajes). En estos esquemas tanto el servicio de autenticacin, o verificador, como la entidad que se quiere autenticar mantienen en secreto la clave de la funcin hash. El esquema funciona de la siguiente forma: El que se quiere autenticar genera un mensaje y calcula su valor hash. Estos dos datos se mandan al verificador. El verificador comprueba que el valor hash se corresponde con el mensaje enviado y de esta forma verifica que la entidad tiene la clave secreta y por otra parte puede asegurar que el mensaje es ntegro (no ha sido modificado desde que se calcul el valor hash). Observar que el esquema no tiene la propiedad del no-repudio por parte del que se quiere autenticar ya que el verificador, al disponer de la clave secreta, puede generar tambin los valores hash. Proteccin de claves: Para comprobar la correccin de una clave no es necesario tener la clave almacenada, lo que puede ser aprovechado para que alguien no autorizado acceda a ella, sino almacenar el valor hash resultante de aplicar una funcin hash determinista. De esta forma para verificar si una clave es correcta basta con aplicar la funcin hash y verificar si el resultado coincide con el que tenemos almacenado. Derivacin de claves: Por ejemplo en algunas aplicaciones usan funciones hash para derivar una clave de sesin a partir de un nmero de transaccin y una clave maestra. Otro ejemplo de aplicacin sera el uso de funciones hash para conseguir sistemas de autenticacin con claves de un solo uso o OTP (del ingls One Time Password). En este tipo de sistemas la clave es vlida para un solo uso. Estos sistemas se basan en tener un semilla inicial y luego ir generando claves (mediante un algoritmo que puede usar funciones hash) que pueden tener un solo uso y as evitar ataques de REPLAY. Herramienta para la identificacin y la rpida comparacin de datos: Se pueden usar funciones hash para proporcionar una identificacin de objetos o situaciones. Una buena funcin hash para este propsito debera ser rpida y asegurarse de que dos objetos o situaciones que se considerar iguales den lugar al mismo valor hash. Observar que dos objetos o situaciones pueden ser considerados iguales sin ser idnticos. Por ejemplo podemos considerar iguales a dos ficheros que son distintos bit a bit porque realmente son la digitalizacin de la misma pelcula. Es labor del diseo de la funcin hash capturar la esencia del criterio de igualdad. Por otra parte la evaluacin de la funcin hash debera ser poco costosa para facilitar la rpida comparacin de elementos candidatos a ser iguales y de esta forma poder implementar algoritmos de bsqueda rpidos.

95

Funcin hash Huellas digitales.- El uso de funciones hash aplicados a cadenas permiten obtener valores hash que pueden usarse detectar fcilmente la aparicin de esos datos en distintos sitios. Pueden ser usados para distintos usos como bsqueda de virus, autenticacin con datos biomtricos, deteccin de copias,...La idea puede usarse ms all de textos y ser aplicado a cualquier tipo de contenido multimedia:[33][34] Las funciones hash especficamente diseadas para este propsito obtienen valores hash que permiten detectar caractersticas intrnsecas del contenido multimedia, de forma que se pueda identificar si dos archivos diferentes se corresponden con el mismo contenido multimedia. Como aplicacin prctica de este tipo de algoritmo tenemos los programas que se ejecutan en dispositivos mviles y que son capaces de adivinar el ttulo de la cancin que est sonando en la habitacin solamente capturando el sonido y comparndolo con estos valores hash. Este tipo de algoritmos tambin se puede utilizar para proteccin de contenidos multimedia ya que permite validar automticamente si cierto fichero multimedia est protegido o no por derechos de autor. Identificacin de contenidos: En algunas aplicaciones se usa el valor hash de un contenido multimedia para identificar ese contenido independientemente de su nombre o ubicacin. Esto es ampliamente usado en redes Peer-to-peer que intercambian de archivos, tales como Kazaa, Ares Galaxy, Overnet, BitTorrent. Identificar un registro en una base de datos y permitir con ello un acceso ms rpido a los registros (incluso ms rpido que teniendo ndices). Algortmos de bsqueda de subcadenas: Los algoritmos de bsqueda de subcadenas tratan el problema de buscar subcadenas, a la que llaman patrn, dentro de otra cadena a la que llaman texto. Hay algoritmos de este tipo que usan funciones hash en su implementacin. Ejemplo: algoritmo Karp-Rabin. Deteccin de virus: Para detectar los virus muchos antivirus definen funciones hash que capturan la esencia del virus y que permiten distinguirlos de otros programas o virus. Es lo que se llama firma del virus. Estas firmas son usadas por los antivirus para poder detectarlos. Muchas de las aplicaciones de las funciones hash son relativas al campo de la criptografa ( Cifradores, acumuladores criptogrficos, firma digital, protocolos criptogrficos de autenticacin,...). La Criptografa es una rama de las matemticas que proporciona herramientas para conseguir seguridad en los sistemas de informacin. Las funciones hash interesantes en el rea de la criptografa se caracterizan por cumplir una serie de propiedades que permiten a las utilidades criptogrficas que las utilizan ser resistente frente ataques que intentan vulnerar la seguridad del sistema. A las funciones hash que cumplen estas propiedades se las llama funciones hash criptogrficas.

96

Referencias
[1] [2] [3] [4] [5] [6] [7] [8] H. Tiwari, K. Asawa "Cryptographic Hash Function: An Elevated View", European Journal of Scientific Research, 2010 A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 D. Henrici,"Concepts, Protocols, And Architectures". Lectures Notes in Electrical Engineering. Springer-Verlag 2008. A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 Bart Preneel,"The State of Cryptographic Hash functions. I. B. Damgard, "Collision free hash functions and public key signatures schemes". Advances in Cryptology- Crypto'89. LNCS 304 pages 203-216. Springer 1987 [9] A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 [10] Kazumaro Aoki, Yu Sasaki, "Meet in the midle preimage attacks against reduced SHA-0 and SHA-1" [11] H. Tiwari et all, "Cryptographic Hash Function:An elevated View", European Jorunal of Scientific Research, Vol 43 pp.452-465. 2010 [12] A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 [13] W. R. Speirs,"Dynamic cryptographic hash functions", Thesis. Purdue University School.2007 [14] Peter Stavroulakis et all,"Handbook of Information and Communication Security", Spring 2010 [15] Dirk Henric,"RFID security and privacy: concepts, protocols, and architectures", Springer 2008 [16] Gnter Schfer,"Security in fixed and wireless networks: an introduction to securing data communications". Willey 2003 [17] William Speirs, " Dynamic cryptographic hash functions (https:/ / www. cerias. purdue. edu/ assets/ pdf/ bibtex_archive/ 2007-20. pdf)" [18] Mihir Bellare and Phillip Rogaway. " Introduction to modern cryptography. Chapter 5 (http:/ / www-cse. ucsd. edu/ users/ mihir/ cse207/ w-hash. pdf).September 2005. [19] Chum-Yuan Hsiao et all, "Finding Collision on a Public Road, or Do Secure Hash Functions Need Secret Coins?"

Funcin hash
[20] "Signature Scheme in Multi-User Setting", The Institute of Electronics, Information and Communication Engineers, 2006 [21] Chun-Yuan Hsiao et all, "Finding Collisions on a Public Road, or Do Secure Hash Functions Need Secret Coins [22] Mridul Nandi," A Generic Method to Extend Message Space of a Strong Pseudorandom Permutation (http:/ / www. scielo. org. mx/ pdf/ cys/ v12n3/ v12n3a4. pdf)" [23] A. R. Caldebank et all, "Improved Range Summable Random Variable Construction Algorithms", Proceedings of the 16 Annual ACM-SIAM Symposium on Discrete Algorithms [24] Ted Krovetz,"Message Authentication on 64-Bit Architectures", Selected Areas in Cryptography, LNCS 4356, Springer.2006. [25] Ilya Mironov,"Collision-Resistant No More: Hash-and-Sign Paradigm Revisited", Public Key Cryptography PKC 2006, LNCS 3958. Springer 2006 [26] D. Hong et all, "Higher Order Universal One-Way Hash Functions",Center for Information Security Technologies, Korea University, Seoul,Korea. [27] Henk C. A. Van Tilborg,"Encyclopedia of Cryptography and Security" Second Edition. pg 1349. Springer 2011 [28] D. Simon, "Finding collisions on a one-way street:Can secure hash functions be based on general assumptions?, EUROCRYPT 98 pp 334-345, 1998 [29] H. Tiwari,"Cryptographic Hash Function: An Elevated View", European journal of Scientific Research, Vol 43 pp.452-465.2010 [30] Bart Preneel,"Cryptographic Primitives for Information Authentication-State of the Art", Katholieke Universiteit Leuven, COSIC'97 LNCS 1528 1998 [31] Chris Mitchell,"Developments in Security Mechanism Standards", "Internet and Intranet Security Management: Risks and Solutions", editado por L. Janczewski,Idea Group Publishing.2000 [32] Ivan Bjerre Damgrd, " Collision free hash functions and public key signature schemes (https:/ / hkn. eecs. berkeley. edu/ ~chris/ temp/ damgard. pdf)",Advances in Cryptology - EUROCRYPT'87, Lncs 304 PP 203-216. Springer-Verlag Berlin Heidelberg 1988 [33] P. Cano et all. A Review of Audio Fingerprinting (http:/ / www. music. mcgill. ca/ ~ich/ classes/ mumt611_08/ fingerprinting/ cano05review. pdf) Journal of VLSI Signal Processing 41, 271284, 2005 [34] Loubna Bouarfa. Research Assignment on Video Fingerprinting (http:/ / ict. ewi. tudelft. nl/ pub/ ben/ Research Assignment Loubna Bouarfa - Video fingerprinting. pdf) Faculty of Electrical Engineering, Mathematics and Computer Science Delft University of Technology

97

Enlaces externos
Funciones hash para bsqueda en tablas hash (http://burtleburtle.net/bob/hash/evahash.html) (en ingls). Generador de Hashes (http://www.sinfocol.org/herramientas/hashes.php) Generador Online de Hashes (CRCs, MD2, MD4, MD5, SHA1, Tiger, Snefru, RipeMD, Whirlpool, Haval, entre otros) Aproximadamente 123 algoritmos, y 200 modos (Hex, Base64) http://www.schneier.com/threefish.html

Fuentes y contribuyentes del artculo

98

Fuentes y contribuyentes del artculo


Algoritmo Fuente: http://es.wikipedia.org/w/index.php?oldid=70531532 Contribuyentes: -jem-, .Sergio, AS990, Abel406, AchedDamiman, Acratta, Adrianantoniors, Airunp, Aitorzubiaurre, AlbertMA, Albertochoa, Aleator, Alejandrocaro35, Alexav8, AlfonsoERomero, Alhen, AlphaWiki, Alvaro qc, Amads, Angel GN, Angus, Antonorsi, Antur, Aquiel, Arlm1, Arthur 'Two Sheds' Jackson, Aipni-Lovrij, Baiji, Balderai, Banfield, BlackBeast, BuenaGente, CASF, Caiser, Calitb, Camilo, Camima, Carlo el calvo, Carmin, Carutsu, Chuchot, Cinabrium, Clarad, ClausxD, Cratn, Crescent Moon, Ctrl Z, Dangelin5, Danielba894, David0811, DerHexer, Diegusjaimes, Dodo, Dogor, Dorieo, Drake 81, Dromero, Ecemaml, Edgar, Edslov, Eduardosalg, Edub, Eduman, Efeg, Ejmeza, Elabra sanchez, Elisardojm, Elwikipedista, Emiduronte, Emijrp, Er Komandante, Eyetheunlord, Ezarate, FAR, Fadesga, Farisori, Fegc77, Fide07, Flakinho, Francisco Mochis, Fsd141, GermanX, Gins90, Gizmo II, Gothmog, Guillervf91, Gusbelluwiki, Gusgus, H3r3dia, HUB, Haitike, Halfdrag, Hantartico, Henry bedon, Heynry1, Huhsunqu, Humberto, Ictlogist, Igna, Ignacio Icke, Imperioonepiece, Ingenioso Hidalgo, Irvinopuma, Isha, JAAC, JMPerez, Jarisleif, Jarke, Javierito92, Jecanre, Jesuja, Jhoelito14, Jjflorescueto, Jkbw, JorgeGG, Jorgeu, Jsanchezes, Jstitch, JuanRodrguez, Jugones55, Julie, Junior1209, Kn, KnightRider, Komputisto, Kotas, Kved, Laura Fiorucci, Lcpousa, Lecuona, Leonpolanco, Libertad y Saber, Llull, Lourdes Cardenal, M.heda, Macrocoliset, MadriCR, Mansoncc, ManuelGR, Manw, Mar del Sur, MarcoAurelio, Matdrodes, McMalamute, Mel 23, Metilisopropilisergamida, Metrnomo, Miguel hdez, MiguelAngel fotografo, Mipataentutrasero, MorZilla, Moriel, Mortadelo2005, Muro de Aguas, Mutari, Netito777, Ninovolador, Nixn, Nocturnogatuno, Obueno, Orgullomoore, Paintman, Pan con queso, Papaplus, Pedrito suarez, Pedrovicenterosero, Peregring-lk, PeruProfe, Petruss, Pit, Plux, Qix, Queninosta, Raulshc, Raystorm, Rbonvall, Relleu, Renly, Rigenea, Riviera, Rosarino, RoyFocker, RoyFokker, Rsg, Ruy Pugliesi, Ros-Ortega, S3v3r-1, Sabbut, Sancebau, Sandovaltk10, Sauron, Savh, Schummy, Sebrev, Sergio Andres Segovia, Shining.Star, Shooke, Snakeyes, Sophie kowalsky, Speedplus, SuperBraulio13, Superzerocool, Tano4595, Technopat, Tirithel, Tomatejc, Tostadora, Triku, Ucevista, Valentin estevanez navarro, Veon, Vic Fede, Virgi, Vitamine, Waka Waka, Wikielwikingo, Wilfredor, Willtron, XalD, Xavigivax, Xpress500, Xxim, Xxxmagicmanxxx, Yeza, YoaR, Zam, ZrzlKing, Zupez zeta, conversion script, proxy1.unizar.es, 1098 ediciones annimas Heurstica Fuente: http://es.wikipedia.org/w/index.php?oldid=70925062 Contribuyentes: Acratta, Adrruiz, Alhen, Angelito7, Antonorsi, Antur, Aromera, Ascnder, Aipni-Lovrij, Beto29, Davius, Dcalder, Dhidalgo, Diegusjaimes, Dromero, Eloy, Elas, Emijrp, Ermygo, Escalda, Focojoaco, Galio, Gerardo.ok, GermanX, Gins90, Handradec, Heimy, Helmy oved, Hidoy kukyo, Hornet69, Ignacios, Ithasyou, JacobRodrigues, Jkbw, Jorge 2701, Jorge c2010, JorgeGG, Joseaperez, Juan Manuel, Juanfer2k, Kaoru&ken, Kokoo, LP, Lnegro, MONIMINO, Mafores, Marielacl, Mortadelo2005, Netito777, Oblongo, Oszala, Oxartum, PAULOGARCIA2005, Plux, Rafajuntoalmar, Raidentk, Resped, RoyFocker, Sergio Edgardo Malf, Tano4595, Tomatejc, UA31, Varano, Wilfredor, 148 ediciones annimas Teora de la complejidad computacional Fuente: http://es.wikipedia.org/w/index.php?oldid=67684492 Contribuyentes: -jem-, AchedDamiman, Alexav8, AlfonsoERomero, Argentumm, Ascnder, Azevedo bandeira, Barcex, Cesarsorm, Davius, Elabra sanchez, Farisori, Fer31416, Focojoaco, Gato ocioso, Halfdrag, Ivan.Romero, Jstitch, Juan Mayordomo, LuqueII, Macarrones, Macarse, Martin78B, Maxidigital, Moriel, Naki, Nicolasdiaz, Pablohe, RoyFocker, Ruben.mg, Surscrd, Tano4595, Technopat, Uruk, V.mendiola, Zild, 69 ediciones annimas Cota superior asinttica Fuente: http://es.wikipedia.org/w/index.php?oldid=69238964 Contribuyentes: Alexav8, Ascnder, Davius, Diegoignaciosanzo, Fibonacci, GermanX, Gothmog, Ignacio Icke, JuaneAba, Pabloab, Porao, Raulshc, Riveravaldez, Romero Schmidtke, Sabbut, Sotrix, Ssola, Sytabaresa, 24 ediciones annimas Cota inferior asinttica Fuente: http://es.wikipedia.org/w/index.php?oldid=65668210 Contribuyentes: Ascnder, Farisori, Gothmog, JuaneAba, Sabbut, Sotrix, 8 ediciones annimas Cota ajustada asinttica Fuente: http://es.wikipedia.org/w/index.php?oldid=68681041 Contribuyentes: Acratta, Alexav8, Ascnder, Davius, Diego Godoy, Farisori, Garbanyo, Gothmog, JuaneAba, Mcetina, Sabbut, 4 ediciones annimas Algoritmo de ordenamiento Fuente: http://es.wikipedia.org/w/index.php?oldid=70592013 Contribuyentes: Alexav8, Almorca, Ascnder, Caos, Cesarsorm, Chuffo, Dark Bane, Darkspawn, Elabra sanchez, Emijrp, Fernandomirandamuro, Fractaltigre, Groucho NL, Helios vmg, JGus, JMPerez, Jesuja, JorgeGG, Lahi, Libertad y Saber, Loxosceles Laeta, Magister Mathematicae, Michada, Miguel.baillon, Miguelo on the road, Moriel, Pablo.cl, Plux, Sauron, Snakeyes, Tano4595, Triku, UA31, Zerial, 72 ediciones annimas Heapsort Fuente: http://es.wikipedia.org/w/index.php?oldid=70807676 Contribuyentes: Ascnder, Bgangioni, Biasoli, Dodo, Elabra sanchez, Emijrp, GermanX, J. A. Glvez, Jacobo Tarrio, JoaquinFerrero, Matdrodes, Maucendon, Mcapdevila, Montgomery, Rotovator, Santhy, Triku, 24 ediciones annimas Quicksort Fuente: http://es.wikipedia.org/w/index.php?oldid=70981479 Contribuyentes: Aclapes, Ambigus9, Arlm1000, Ascnder, Camilo, CarlosHoyos, Chebi, Dealonso, Dem, DevilishFreak, Eduardosalg, Elabra sanchez, Execoot, Fortran, Gafotas, GermanX, Gothmog, Human, Igna, J. A. Glvez, JMPerez, Jacobo Tarrio, Jatch21, Jkbw, Joanumbert, JoaquinFerrero, JotaMC, Juen, Kelwin, LevanenG, LordT, Manuelt15, Matdrodes, Milder.q, Mkucharuk, Netito777, Pablo.cl, Pandemon, Papagorila, Paredero, Pepetacos, Pino, Rafael josem, Raulshc, Tostadora, UA31, Wariou, Xavigivax, Xerox 5B, Yago AB, Yonseca, 199 ediciones annimas Estructura de datos Fuente: http://es.wikipedia.org/w/index.php?oldid=70117375 Contribuyentes: Alexan, Alexandravargas, Alexav8, Aquiel, Asfarer, Biasoli, Comae, Crg 85, Danthux, David0811, Developer, Diegusjaimes, Dodo, Edulix, Emijrp, Fercufer, Fortran, Fsd141, Furti, Gtz, Hidoy kukyo, Icvav, Jesuja, Jetjanoli, Jkbw, Jsanchezes, Juan renombrado, Julie, LPR, Laura Fiorucci, Maldoror, Matdrodes, Miguelo on the road, Moriel, Murphy era un optimista, Platonides, Porao, Rasilga, Ricardogpn, Rrupo, Rsg, Sabbut, Sauron, Seasz, Soniautn, SuperBraulio13, Tomatejc, Triku, Txo, Xerox 5B, 114 ediciones annimas Pila (informtica) Fuente: http://es.wikipedia.org/w/index.php?oldid=71164532 Contribuyentes: AchedDamiman, Andreasmperu, Angelito7, Biasoli, Creosota, David f.1993, Diegusjaimes, Ealmagro, Emijrp, Ezarate, Farisori, Fernd, Fortran, GCaracuel, Gbduende, GermanX, Greek, Harpagornis, Helmy oved, JacobRodrigues, Jesuja, Jkbw, Juan Mayordomo, Kn, Laura Fiorucci, LyingB, Martaka, Matdrodes, Ocaroline, Phaetton, Poco a poco, Plux, Rbonvall, Rjelves, Sebado, Shooke, Sire, Sirpuppet, Sms, Technopat, Vengadora, Vivero, Wilfredor, 118 ediciones annimas Cola (informtica) Fuente: http://es.wikipedia.org/w/index.php?oldid=70938523 Contribuyentes: Alvaromedina, Amadeupons, Ctrl Z, DOOM17, Diegusjaimes, Diosa, Eduardo Lima, Eduardosalg, El3ctron, Emijrp, Farisori, Hprmedina, Igna, Jarke, Jduarte, Jesuja, JorgeGG, Josemgm89, Miguel940829, Mithy, Moriel, Nubecosmica, Ocaroline, PabloRCR, Poco a poco, Plux, Qwertymith, Sms, Technopat, Tirithel, Waka Waka, Wilfredor, 86 ediciones annimas rbol (informtica) Fuente: http://es.wikipedia.org/w/index.php?oldid=71645605 Contribuyentes: 4lex, Aeb, Alex485232008, Alexav8, AlfonsoERomero, Antur, AquiLesBailoYo, Ascnder, Biasoli, BlackBeast, CA., Clementito, Damifb, Diegusjaimes, Dodo, Ejrrjs, Farisori, GRHugo, Gaboramirezm, GermanX, Goingvisit, Googolplanck, Helmy oved, Humberto, Jkbw, Josell2, Laura Fiorucci, Maleiva, Manuelt15, Marcoantoniothomas, Matdrodes, Nubecosmica, Periku, Pinar, Poco a poco, Porao, Ramzysamman, Rmmv, Rosarinagazo, Sabbut, Sanbec, Schwallex, Sms, Technopat, The$oul, Ty25, Vcarceler, Wikilptico, Will vm, Yrithinnd, 102 ediciones annimas rbol binario Fuente: http://es.wikipedia.org/w/index.php?oldid=71265980 Contribuyentes: Alfredogtzh, Angus, Ascnder, Aipni-Lovrij, C'est moi, Chewie, Cinabrium, Dagavi, Diegusjaimes, Dodo, Dvdgc, Eduardosalg, Farisori, Fenrihr, Galandil, Gmarquez, Humbefa, Icvav, Isha, JMPerez, JaNoX, Jaag12, Johnanth, JoseTAD, Laura Fiorucci, Maldoror, Mortadelo2005, Muro de Aguas, Osiris fancy, PabloCastellano, Periku, Petronas, Porao, Pyr0, Plux, Rimeju, Rodoelgrande, Rosewitchy, Sabbut, Sanbec, SuperBraulio13, Templeir, Tigrera, Tomatejc, Toxa Kniotee, Triku, Tux juanda95, Victormoz, 187 ediciones annimas rbol binario de bsqueda Fuente: http://es.wikipedia.org/w/index.php?oldid=71540276 Contribuyentes: 3coma14, Albries, Alelapenya, Aluna2007, Andresluna2007, Apj, Bibliofilotranstornado, Chewie, Ciberjovial, Darkmeow, Er Komandante, ErSame, FAR, Fercufer, Humbefa, Joanga, Kimizombie, Knzio, Loly bc15, Maucendon, MetalGuns, Mr.Ajedrez, NaBUru38, Platonides, Porao, Ricardogpn, SuperBraulio13, Tirabo, ViajeroEspacial, Wjuarezq, Yago AB, 55 ediciones annimas Tabla hash Fuente: http://es.wikipedia.org/w/index.php?oldid=69575683 Contribuyentes: Arlekean, Bernard, Camilo, Caos, Cesarsorm, Cinevoro, Comae, Dem, Diegusjaimes, Dodo, Federicojasson, Fortran, Gonsalet, Halfdrag, Humbefa, Jfgarcia, Julie, LeonardoGregianin, Loboferoz8, LyingB, Maldoror, Mchll0011, Roberto Parrillas, Sms, The Yils, Vicucha, Wastingmytime, 89 ediciones annimas Funcin hash Fuente: http://es.wikipedia.org/w/index.php?oldid=71694360 Contribuyentes: Aalvarez12, Airunp, Alexav8, Antonorsi, Antur, Barri, Bernard, Centroamericano, ColdWind, Cybercrank, Diogeneselcinico42, Dodo, EgrojSoft, Elwikipedista, Fercufer, Fmariluis, Halfdrag, Hardcoded, Isha, Itz37, Jarisleif, Jfgarcia, Jkbw, Juana de Arco, Jviares, KnightRider, Knockergrowl, LyingB, Magister Mathematicae, Maose, Miguelo on the road, Moleculax, Netito777, Plux, Qwertyytrewqqwerty, Rayearth, Sabbut, Salomn Varshavsky, Shooke, Swatnio, Taichi, Technopat, Telemonica, Tony Rotondas, Vitamine, Yodigo, Zam, 136 ediciones annimas

Fuentes de imagen, Licencias y contribuyentes

99

Fuentes de imagen, Licencias y contribuyentes


Archivo:LampFlowchart-es.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:LampFlowchart-es.svg Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: LampFlowchart.svg: svg by Booyabazookaoriginal png by Wapcaplet derivative work: Huhsunqu (talk) Archivo:AlgoritmoRaiz.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:AlgoritmoRaiz.png Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Kn Archivo:EsquemticaAlgoritmo1.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:EsquemticaAlgoritmo1.svg Licencia: Creative Commons Attribution-Share Alike Contribuyentes: Kn Archivo:Wikibooks-logo.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Wikibooks-logo.svg Licencia: logo Contribuyentes: User:Bastique, User:Ramac et al. Archivo:Wiktionary-logo-es.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Wiktionary-logo-es.png Licencia: logo Contribuyentes: es:Usuario:Pybalo Archivo:CotaSuperiorAsintotica.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:CotaSuperiorAsintotica.png Licencia: GNU Free Documentation License Contribuyentes: Original uploader was Ascnder at es.wikipedia Later versions were uploaded by Sanbec at es.wikipedia. Archivo:CotaInferiorAsintotica.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:CotaInferiorAsintotica.png Licencia: GNU Free Documentation License Contribuyentes: Original uploader was Ascnder at es.wikipedia Archivo:CotaAjustadaAsintotica.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:CotaAjustadaAsintotica.png Licencia: GNU Free Documentation License Contribuyentes: Original uploader was Ascnder at es.wikipedia Archivo:Sorting quicksort anim.gif Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Sorting_quicksort_anim.gif Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Wikipedia:en:User:RolandH Archivo:Sorting heapsort anim.gif Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Sorting_heapsort_anim.gif Licencia: Creative Commons Attribution-Sharealike 2.0 Contribuyentes: de:User:RolandH Image:Pila.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Pila.svg Licencia: Creative Commons Zero Contribuyentes: User:Boivie, User:Ocaroline Archivo:Cola.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Cola.svg Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: User:Boivie, User:Ocaroline, User:Vegpuff Archivo:ColaProg.JPG Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:ColaProg.JPG Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Jduarte Archivo:binary_tree_(oriented digraph).png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Binary_tree_(oriented_digraph).png Licencia: Public Domain Contribuyentes: F, Haui, Helix84, Maximaximax File:BinaryTreeRotations.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:BinaryTreeRotations.svg Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: User:Josell7 Archivo:binary tree (oriented digraph).png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Binary_tree_(oriented_digraph).png Licencia: Public Domain Contribuyentes: F, Haui, Helix84, Maximaximax Archivo:Arboles binarios.jpg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Arboles_binarios.jpg Licencia: Public Domain Contribuyentes: Albedo-ukr, Ilmari Karonen, JoseTAD, 1 ediciones annimas Archivo:Lista nodos.JPG Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Lista_nodos.JPG Licencia: Public Domain Contribuyentes: Albedo-ukr, JoseTAD Archivo:N-ary to binary.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:N-ary_to_binary.svg Licencia: Public Domain Contribuyentes: CyHawk Archivo:Binary search tree.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Binary_search_tree.svg Licencia: Public Domain Contribuyentes: User:Booyabazooka, User:Dcoetzee Archivo:insertar.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Insertar.svg Licencia: Public Domain Contribuyentes: Gorivero Archivo:ABBHOJA3.jpg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:ABBHOJA3.jpg Licencia: Public Domain Contribuyentes: Joanga Archivo:ABBHOJA5.jpg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:ABBHOJA5.jpg Licencia: Public Domain Contribuyentes: Joanga Archivo:ABBHOJA4.jpg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:ABBHOJA4.jpg Licencia: Public Domain Contribuyentes: Joanga Archivo:ABBEJEM.jpg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:ABBEJEM.jpg Licencia: Public Domain Contribuyentes: Joanga Imagen:Hash table-es.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Hash_table-es.svg Licencia: Creative Commons Attribution-Sharealike 2.5 Contribuyentes: LyingB Imagen:Tabla hash2.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Tabla_hash2.png Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Cesarsorm Imagen:Tabla hash 3.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Tabla_hash_3.png Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Cesarsorm Archivo:Hash function2-es.svg Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Hash_function2-es.svg Licencia: Creative Commons Attribution-Sharealike 3.0 Contribuyentes: User:Fercufer

Licencia

100

Licencia
Creative Commons Attribution-Share Alike 3.0 //creativecommons.org/licenses/by-sa/3.0/

También podría gustarte