fbpx
Wikipedia

Árbol AVL

Un árbol AVL es un tipo especial de árbol binario ideado por los matemáticos soviéticos Adelson-Velskii y Landis. Fue el primer árbol de búsqueda binario auto-balanceable que se ideó.

Animación que muestra la construcción de un árbol AVL e incluye todas sus rotaciones.

Descripción

 
Un ejemplo de árbol binario no equilibrado (no es AVL)
 
Un ejemplo de árbol binario equilibrado (sí es AVL)

El árbol AVL toma su nombre de las iniciales de los apellidos de sus inventores, Georgii Adelson-Velskii y Yevgeniy Landis. Lo dieron a conocer en la publicación de un artículo en 1962, «An algorithm for the organization of information» («Un algoritmo para la organización de la información»).

Los árboles AVL están siempre equilibrados de tal modo que para todos los nodos, la altura de la rama izquierda no difiere en más de una unidad de la altura de la rama derecha o viceversa. Gracias a esta forma de equilibrio (o balanceo), la complejidad de una búsqueda en uno de estos árboles se mantiene siempre en orden de complejidad O(log n). El factor de equilibrio puede ser almacenado directamente en cada nodo o ser computado a partir de las alturas de los subárboles.

Para conseguir esta propiedad de equilibrio, la inserción y el borrado de los nodos se ha de realizar de una forma especial. Si al realizar una operación de inserción o borrado se rompe la condición de equilibrio, hay que realizar una serie de rotaciones de los nodos.

Los árboles AVL más profundos son los árboles de Fibonacci.

Definición formal

Definición de la altura de un árbol

Sea   un árbol binario de búsqueda y sean   y   sus subárboles, su altura  , es:

  •   si el árbol   contiene solo la raíz
  •   si contiene más nodos

Definición de árbol AVL

  • Un árbol vacío es un árbol AVL
  • Si   es un árbol no vacío y   y   sus subárboles, entonces   es AVL si y solo si:
  •   es AVL
  •   es AVL
  •  

Factor de equilibrio

Cada nodo, además de la información que se pretende almacenar, debe tener los dos punteros a los árboles derecho e izquierdo, igual que los árboles binarios de búsqueda (ABB), y además el dato que controla el factor de equilibrio.

El factor de equilibrio es la diferencia entre las alturas del árbol derecho y el izquierdo:

FE = altura subárbol derecho - altura subárbol izquierdo
Por definición, para un árbol AVL, este valor debe ser -1, 0 o 1.

Si el factor de equilibrio de un nodo es:

0 -> el nodo está equilibrado y sus subárboles tienen exactamente la misma altura.
1 -> el nodo está equilibrado y su subárbol derecho es un nivel más alto.
-1 -> el nodo está equilibrado y su subárbol izquierdo es un nivel más alto.

Si el factor de equilibrio   es necesario reequilibrar.

Operaciones

Las operaciones básicas de un árbol AVL implican generalmente el realizar los mismos algoritmos que serían realizados en un árbol binario de búsqueda desequilibrado, pero precedido o seguido por una o más de las llamadas "rotaciones AVL".

Rotaciones

 
Las rotaciones internas 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 logarítmico

El reequilibrado se produce de abajo hacia arriba sobre los nodos en los que se produce el desequilibrio. Pueden darse dos casos: rotación simple o rotación doble; a su vez ambos casos pueden ser hacia la derecha o hacia la izquierda.

Rotación simple a la derecha

De un árbol de raíz (r) y de hijos izquierdo (i) y derecho (d), lo que haremos será formar un nuevo árbol cuya raíz sea la raíz del hijo izquierdo, como hijo izquierdo colocamos el hijo izquierdo de i (nuestro i’) y como hijo derecho construimos un nuevo árbol que tendrá como raíz, la raíz del árbol (r), el hijo derecho de i (d’) será el hijo izquierdo y el hijo derecho será el hijo derecho del árbol (d).

 

op rotDer: AVL{X} -> [AVL{X}] . eq rotDer(arbolBin(R1, arbolBin(R2, I2, D2), D1)) == arbolBin(R2, I2, arbolBin(R1, D2, D)) . 
Rotación simple a la izquierda

De un árbol de raíz (r) y de hijos izquierdo (i) y derecho (d), consiste en formar un nuevo árbol cuya raíz sea la raíz del hijo derecho, como hijo derecho colocamos el hijo derecho de d (nuestro d’) y como hijo izquierdo construimos un nuevo árbol que tendrá como raíz la raíz del árbol (r), el hijo izquierdo de d será el hijo derecho (i’) de r y el hijo izquierdo será el hijo izquierdo del árbol (i).

Precondición : Tiene que tener hijo derecho no vacío.


op rotIzq: AVL{X} -> [AVL{X}] . eq rotIzq(arbolBin(R1, I, arbolBin(R2, I2, D2))) == arbolBin(R2, arbolBin(R1, I, I2), D2) . 

Si la inserción se produce en el hijo derecho del hijo izquierdo del nodo desequilibrado (o viceversa) hay que realizar una doble rotación.

Rotación doble a la derecha

La Rotación doble a la Derecha son dos rotaciones simples, primero rotación simple izquierda y luego rotación simple derecha.

  

Rotación doble a la izquierda

La Rotación doble a la Izquierda son dos rotaciones simples, primero rotación simple derecha y luego rotación simple izquierda.

  

Inserción

La inserción en un árbol de AVL puede ser realizada insertando el valor dado en el árbol como si fuera un árbol de búsqueda binario desequilibrado y después retrocediendo hacia la raíz, rotando sobre cualquier nodo que pueda haberse desequilibrado durante la inserción.

Proceso de inserción:

1 Buscar hasta encontrar la posición de inserción o modificación (proceso idéntico a inserción en árbol binario de búsqueda)
2 Insertar el nuevo nodo con factor de equilibrio “equilibrado”
3 Desandar el camino de búsqueda, verificando el equilibrio de los nodos, y re-equilibrando si es necesario

           

Debido a que las rotaciones son una operación que tienen complejidad constante y a que la altura está limitada a O (log(n)), el tiempo de ejecución para la inserción es del orden O (log(n)).

op insertar: X$Elt AVL{X} -> AVLNV{X} . eq insertar(R, crear) == arbolBin(R, crear, crear) . ceq insertar(R1, arbolBin(R2, I, D)) == if (R1==R2) then arbolBin(R2, I, D) elseif (R1<R2) then if ( (altura(insertar(R1,I))  altura(D)) < 2) then arbolBin(R2, insertar(R1, I), D) else ***hay que reequilibrar if (R1 < raíz(I)) then rotarDer(arbolBin(R2, insertar(R1, I), D)) else rotarDer(arbolBin(R2, rotarIzq(insertar(R1, I)), D)) fi . fi . else if ( (altura(insertar(R1,I))  altura(D)) < 2) then arbolBin(R2, insertar(R1, I), D) else *** hay que reequilibrar if (R1 > raíz(D)) then rotarIzq(arbolBin(R, I, insertar(R1, D))) else rotatIzq(arbolBin(R, I, rotarDer(insertar(R1, D)))) fi . fi . fi . 

Extracción

El procedimiento de borrado es el mismo que en el caso de árbol binario de búsqueda. La diferencia se encuentra en el proceso de reequilibrado posterior. El problema de la extracción puede resolverse en O (log(n)) pasos. Una extracción trae consigo una disminución de la altura de la rama donde se extrajo y tendrá como efecto un cambio en el factor de equilibrio del nodo padre de la rama en cuestión, pudiendo necesitarse una rotación.

Esta disminución de la altura y la corrección de los factores de equilibrio con sus posibles rotaciones asociadas pueden propagarse hasta la raíz.

  Borrar A, y la nueva raíz será M.

  Borrado A, la nueva raíz es M. Aplicamos la rotación a la izquierda.

  El árbol resultante ha perdido altura.

En el borrado pueden ser necesarias varias operaciones de restauración del equilibrio, y hay que seguir comprobando hasta llegar a la raíz.

op eliminar: X$Elt AVL{X} -> AVL{X} . eq eliminar(R, crear) == crear . ceq eliminar(R1, arbolBin(R2, I, D)) == if (R1 == R2) then if esVacio(I) then D elseif esVacio(D) then I else for (i=0; i<=2 i++) if (altura(I) - altura(eliminar(min(D),D)) < 2) then arbolBin(min(D), I, eliminar(min(D), D)) ***tenemos que reequilibrar elseif (altura(hijoIzq(I) >= altura(hijoDer(I)))) then rotDer(arbolBin(min(D), I, eliminar(min(D),D))) else rotDer(arbolBin(min(D), rotIzq(I), eliminar(min(D),D))) 

Búsqueda

Ejemplo en Java

public class Nodo { int numMat; Nodo izqda, drcha; public Nodo(int mat){ numMat = mat; izqda = drcha = null; } public void re_enorden(){ if(izqda != null) izqda.re_enorden(); System.out.println("Matricula: " +numMat); if(drcha != null) drcha.re_enorden(); } } public class AVL { private Nodo raíz; public AVL (){ raíz = null; } public void insertar(int nuevoM){ if(raíz==null){ raíz = new Nodo(nuevoM); } else{ insertar(raíz,nuevoM); } } private void insertar(Nodo rz, int nm){ if (rz == null) rz = new Nodo(nm); else if(nm < rz.numMat) insertar(rz.izqda,nm); else if(nm > rz.numMat) insertar(rz.drcha,nm); else System.out.println("Numero Duplicados"); } public void visualizar(){ if(raíz!=null) raíz.re_enorden(); } } public class Ejecutar { public static void main(String []args){ AVL árbol = new AVL (); árbol.insertar(6); árbol.insertar(3); árbol.insertar(7); árbol.visualizar(); } } 

Ejemplo de TAD AVL en C++

#include <cstdio> struct AVL{  int dato, FB; // FB es la altura del subarbol izquierdo menos la altura del subarbol derecho  AVL *izq, *der;  bool borrado; }; void rotarLL(AVL* &A){ //precond: el árbol necesita una rotacion LL  AVL* aux = A->izq->der;  A->izq->der = A;  A->izq->FB = 0;   AVL* aux2 = A->izq;  A->izq = aux;  A->FB = 0;  A = aux2; } void rotarRR(AVL* &A){ //precond: el árbol necesita una rotacion RR  AVL* aux = A->der->izq;  A->der->izq = A;  A->der->FB = 0;   AVL* aux2 = A->der;  A->der = aux;  A->FB = 0;  A = aux2; } void rotarLRalter(AVL* &A){ //precond: el árbol necesita una rotacion LR  rotarRR(A->izq);  rotarLL(A); } void rotarRLalter(AVL* &A){ //precond: el árbol necesita una rotacion RL  rotarLL(A->der);  rotarRR(A); } AVL* Crear(){  return NULL; } void Insert(int n, bool &aumento, AVL* &A){  if (A == NULL){  A = new AVL;  A->dato = n;  A->FB = 0;  A->izq = NULL;  A->der = NULL;  aumento = true;  A->borrado = false;  }else{  if (n < A->dato){   Insert(n, aumento, A->izq);   if (aumento){  switch (A->FB){  case -1:{  A->FB = 0;  aumento = false;  break;  }  case 0:{  A->FB = 1;  aumento = true;  break;  }  case 1:{  if (A->izq->FB == 1){ // Si es 1 necesita una rotacion LL si es -1 necesita una rotacion LR  rotarLL(A);  }else{  rotarLRalter(A);  }  aumento = false;  break;  }  }  }  }else{  Insert(n, aumento, A->der);   if (aumento){  switch (A->FB){  case -1:{  if (A->der->FB == 1){ // Si es 1 necesita una rotacion RL si es -1 necesita una rotacion RR  rotarRLalter(A);  }else{  rotarRR(A);  }  aumento = false;   break;  }  case 0:{  A->FB = -1;  aumento = true;  break;  }  case 1:{  A->FB = 0;  aumento = false;  break;  }  }  }  }  } } void Insertar(AVL* &A, int n){  bool aumento;  Insert(n, aumento, A); } bool EsVacio(AVL* A){  return A == NULL; } bool Pertenece(AVL* A, int n){  if (A == NULL){  return false;  }else{  if (A->dato == n){  if (A->borrado){  return false;  }else{  return true;  }  }else if (n < A->dato){   return Pertenece(A->izq, n);  }else{  return Pertenece(A->der, n);  }   } } void Borrar(AVL* &A, int n){  if (A->dato == n){  A->borrado = true;  }else if (n < A->dato){   Borrar(A->izq, n);  }else{  Borrar(A->der, n);  } } 

Véase también

Enlaces externos

  • Visualización del árbol AVL
  • Más información sobre árboles AVL
  •   Datos: Q300159
  •   Multimedia: AVL-trees / Q300159

Árbol, este, artículo, sección, necesita, referencias, aparezcan, publicación, acreditada, este, aviso, puesto, noviembre, 2013, árbol, tipo, especial, árbol, binario, ideado, matemáticos, soviéticos, adelson, velskii, landis, primer, árbol, búsqueda, binario,. Este articulo o seccion necesita referencias que aparezcan en una publicacion acreditada Este aviso fue puesto el 24 de noviembre de 2013 Un arbol AVL es un tipo especial de arbol binario ideado por los matematicos sovieticos Adelson Velskii y Landis Fue el primer arbol de busqueda binario auto balanceable que se ideo Animacion que muestra la construccion de un arbol AVL e incluye todas sus rotaciones Indice 1 Descripcion 2 Definicion formal 2 1 Definicion de la altura de un arbol 2 2 Definicion de arbol AVL 3 Factor de equilibrio 4 Operaciones 4 1 Rotaciones 4 2 Insercion 4 3 Extraccion 4 4 Busqueda 5 Vease tambien 6 Enlaces externosDescripcion Editar Un ejemplo de arbol binario no equilibrado no es AVL Un ejemplo de arbol binario equilibrado si es AVL El arbol AVL toma su nombre de las iniciales de los apellidos de sus inventores Georgii Adelson Velskii y Yevgeniy Landis Lo dieron a conocer en la publicacion de un articulo en 1962 An algorithm for the organization of information Un algoritmo para la organizacion de la informacion Los arboles AVL estan siempre equilibrados de tal modo que para todos los nodos la altura de la rama izquierda no difiere en mas de una unidad de la altura de la rama derecha o viceversa Gracias a esta forma de equilibrio o balanceo la complejidad de una busqueda en uno de estos arboles se mantiene siempre en orden de complejidad O log n El factor de equilibrio puede ser almacenado directamente en cada nodo o ser computado a partir de las alturas de los subarboles Para conseguir esta propiedad de equilibrio la insercion y el borrado de los nodos se ha de realizar de una forma especial Si al realizar una operacion de insercion o borrado se rompe la condicion de equilibrio hay que realizar una serie de rotaciones de los nodos Los arboles AVL mas profundos son los arboles de Fibonacci Definicion formal EditarDefinicion de la altura de un arbol Editar Sea T displaystyle T un arbol binario de busqueda y sean T i displaystyle T i y T d displaystyle T d sus subarboles su altura H T displaystyle H T es 0 displaystyle 0 si el arbol T displaystyle T contiene solo la raiz 1 max H T i H T d displaystyle 1 max H T i H T d si contiene mas nodosDefinicion de arbol AVL Editar Un arbol vacio es un arbol AVL Si T displaystyle T es un arbol no vacio y T i displaystyle T i y T d displaystyle T d sus subarboles entonces T displaystyle T es AVL si y solo si T i displaystyle T i es AVL T d displaystyle T d es AVL H T i H T d lt 1 displaystyle H T i H T d lt 1 Factor de equilibrio EditarCada nodo ademas de la informacion que se pretende almacenar debe tener los dos punteros a los arboles derecho e izquierdo igual que los arboles binarios de busqueda ABB y ademas el dato que controla el factor de equilibrio El factor de equilibrio es la diferencia entre las alturas del arbol derecho y el izquierdo FE altura subarbol derecho altura subarbol izquierdoPor definicion para un arbol AVL este valor debe ser 1 0 o 1 Si el factor de equilibrio de un nodo es 0 gt el nodo esta equilibrado y sus subarboles tienen exactamente la misma altura 1 gt el nodo esta equilibrado y su subarbol derecho es un nivel mas alto 1 gt el nodo esta equilibrado y su subarbol izquierdo es un nivel mas alto Si el factor de equilibrio F e gt 2 displaystyle Fe gt 2 es necesario reequilibrar Operaciones EditarLas operaciones basicas de un arbol AVL implican generalmente el realizar los mismos algoritmos que serian realizados en un arbol binario de busqueda desequilibrado pero precedido o seguido por una o mas de las llamadas rotaciones AVL Rotaciones Editar Las rotaciones internas en arboles binarios son operaciones internas comunes utilizadas para mantener el balance perfecto o casi perfecto del arbol binario Un arbol balanceado permite operaciones en tiempo logaritmico El reequilibrado se produce de abajo hacia arriba sobre los nodos en los que se produce el desequilibrio Pueden darse dos casos rotacion simple o rotacion doble a su vez ambos casos pueden ser hacia la derecha o hacia la izquierda Rotacion simple a la derechaDe un arbol de raiz r y de hijos izquierdo i y derecho d lo que haremos sera formar un nuevo arbol cuya raiz sea la raiz del hijo izquierdo como hijo izquierdo colocamos el hijo izquierdo de i nuestro i y como hijo derecho construimos un nuevo arbol que tendra como raiz la raiz del arbol r el hijo derecho de i d sera el hijo izquierdo y el hijo derecho sera el hijo derecho del arbol d op rotDer AVL X gt AVL X eq rotDer arbolBin R1 arbolBin R2 I2 D2 D1 arbolBin R2 I2 arbolBin R1 D2 D Rotacion simple a la izquierdaDe un arbol de raiz r y de hijos izquierdo i y derecho d consiste en formar un nuevo arbol cuya raiz sea la raiz del hijo derecho como hijo derecho colocamos el hijo derecho de d nuestro d y como hijo izquierdo construimos un nuevo arbol que tendra como raiz la raiz del arbol r el hijo izquierdo de d sera el hijo derecho i de r y el hijo izquierdo sera el hijo izquierdo del arbol i Precondicion Tiene que tener hijo derecho no vacio op rotIzq AVL X gt AVL X eq rotIzq arbolBin R1 I arbolBin R2 I2 D2 arbolBin R2 arbolBin R1 I I2 D2 Si la insercion se produce en el hijo derecho del hijo izquierdo del nodo desequilibrado o viceversa hay que realizar una doble rotacion Rotacion doble a la derechaLa Rotacion doble a la Derecha son dos rotaciones simples primero rotacion simple izquierda y luego rotacion simple derecha Rotacion doble a la izquierdaLa Rotacion doble a la Izquierda son dos rotaciones simples primero rotacion simple derecha y luego rotacion simple izquierda Insercion Editar La insercion en un arbol de AVL puede ser realizada insertando el valor dado en el arbol como si fuera un arbol de busqueda binario desequilibrado y despues retrocediendo hacia la raiz rotando sobre cualquier nodo que pueda haberse desequilibrado durante la insercion Proceso de insercion 1 Buscar hasta encontrar la posicion de insercion o modificacion proceso identico a insercion en arbol binario de busqueda 2 Insertar el nuevo nodo con factor de equilibrio equilibrado 3 Desandar el camino de busqueda verificando el equilibrio de los nodos y re equilibrando si es necesario Debido a que las rotaciones son una operacion que tienen complejidad constante y a que la altura esta limitada a O log n el tiempo de ejecucion para la insercion es del orden O log n op insertar X Elt AVL X gt AVLNV X eq insertar R crear arbolBin R crear crear ceq insertar R1 arbolBin R2 I D if R1 R2 then arbolBin R2 I D elseif R1 lt R2 then if altura insertar R1 I altura D lt 2 then arbolBin R2 insertar R1 I D else hay que reequilibrar if R1 lt raiz I then rotarDer arbolBin R2 insertar R1 I D else rotarDer arbolBin R2 rotarIzq insertar R1 I D fi fi else if altura insertar R1 I altura D lt 2 then arbolBin R2 insertar R1 I D else hay que reequilibrar if R1 gt raiz D then rotarIzq arbolBin R I insertar R1 D else rotatIzq arbolBin R I rotarDer insertar R1 D fi fi fi Extraccion Editar El procedimiento de borrado es el mismo que en el caso de arbol binario de busqueda La diferencia se encuentra en el proceso de reequilibrado posterior El problema de la extraccion puede resolverse en O log n pasos Una extraccion trae consigo una disminucion de la altura de la rama donde se extrajo y tendra como efecto un cambio en el factor de equilibrio del nodo padre de la rama en cuestion pudiendo necesitarse una rotacion Esta disminucion de la altura y la correccion de los factores de equilibrio con sus posibles rotaciones asociadas pueden propagarse hasta la raiz Borrar A y la nueva raiz sera M Borrado A la nueva raiz es M Aplicamos la rotacion a la izquierda El arbol resultante ha perdido altura En el borrado pueden ser necesarias varias operaciones de restauracion del equilibrio y hay que seguir comprobando hasta llegar a la raiz op eliminar X Elt AVL X gt AVL X eq eliminar R crear crear ceq eliminar R1 arbolBin R2 I D if R1 R2 then if esVacio I then D elseif esVacio D then I else for i 0 i lt 2 i if altura I altura eliminar min D D lt 2 then arbolBin min D I eliminar min D D tenemos que reequilibrar elseif altura hijoIzq I gt altura hijoDer I then rotDer arbolBin min D I eliminar min D D else rotDer arbolBin min D rotIzq I eliminar min D D Busqueda Editar Ejemplo en Java public class Nodo int numMat Nodo izqda drcha public Nodo int mat numMat mat izqda drcha null public void re enorden if izqda null izqda re enorden System out println Matricula numMat if drcha null drcha re enorden public class AVL private Nodo raiz public AVL raiz null public void insertar int nuevoM if raiz null raiz new Nodo nuevoM else insertar raiz nuevoM private void insertar Nodo rz int nm if rz null rz new Nodo nm else if nm lt rz numMat insertar rz izqda nm else if nm gt rz numMat insertar rz drcha nm else System out println Numero Duplicados public void visualizar if raiz null raiz re enorden public class Ejecutar public static void main String args AVL arbol new AVL arbol insertar 6 arbol insertar 3 arbol insertar 7 arbol visualizar Ejemplo de TAD AVL en C include lt cstdio gt struct AVL int dato FB FB es la altura del subarbol izquierdo menos la altura del subarbol derecho AVL izq der bool borrado void rotarLL AVL amp A precond el arbol necesita una rotacion LL AVL aux A gt izq gt der A gt izq gt der A A gt izq gt FB 0 AVL aux2 A gt izq A gt izq aux A gt FB 0 A aux2 void rotarRR AVL amp A precond el arbol necesita una rotacion RR AVL aux A gt der gt izq A gt der gt izq A A gt der gt FB 0 AVL aux2 A gt der A gt der aux A gt FB 0 A aux2 void rotarLRalter AVL amp A precond el arbol necesita una rotacion LR rotarRR A gt izq rotarLL A void rotarRLalter AVL amp A precond el arbol necesita una rotacion RL rotarLL A gt der rotarRR A AVL Crear return NULL void Insert int n bool amp aumento AVL amp A if A NULL A new AVL A gt dato n A gt FB 0 A gt izq NULL A gt der NULL aumento true A gt borrado false else if n lt A gt dato Insert n aumento A gt izq if aumento switch A gt FB case 1 A gt FB 0 aumento false break case 0 A gt FB 1 aumento true break case 1 if A gt izq gt FB 1 Si es 1 necesita una rotacion LL si es 1 necesita una rotacion LR rotarLL A else rotarLRalter A aumento false break else Insert n aumento A gt der if aumento switch A gt FB case 1 if A gt der gt FB 1 Si es 1 necesita una rotacion RL si es 1 necesita una rotacion RR rotarRLalter A else rotarRR A aumento false break case 0 A gt FB 1 aumento true break case 1 A gt FB 0 aumento false break void Insertar AVL amp A int n bool aumento Insert n aumento A bool EsVacio AVL A return A NULL bool Pertenece AVL A int n if A NULL return false else if A gt dato n if A gt borrado return false else return true else if n lt A gt dato return Pertenece A gt izq n else return Pertenece A gt der n void Borrar AVL amp A int n if A gt dato n A gt borrado true else if n lt A gt dato Borrar A gt izq n else Borrar A gt der n Vease tambien EditarArbol binario de busqueda Arbol programacion Arbol AA Arbol rojo negro Arbol splay Arbol multirramaEnlaces externos EditarVisualizacion del arbol AVL Mas informacion sobre arboles AVL Applet que muestra el comportamiento de diferentes estructuras de datos arboreas Datos Q300159 Multimedia AVL trees Q300159 Obtenido de https es wikipedia org w index php title Arbol AVL amp oldid 135404983, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos