Exemplo n.º 1
0
        /// <summary>
        /// Implementación recursiva que agrega un elemento en un árbol AVL
        /// </summary>
        /// <param name="root">Nodo del subárbol a considerar</param>
        /// <param name="item">Elemento a agregar</param>
        /// <param name="flag">Indica si cambió la altura</param>
        /// <returns>Nodo del subárbol considerado</returns>
        protected virtual AVLNode <E> AddAVL(AVLNode <E> root, E item, ref bool flag)
        {
            AVLNode <E> n1;

            // Si el árbol está vacio, simplement se agrega
            // y se indica que cambió la altura
            if (root == null)
            {
                root = new AVLNode <E>(item);
                flag = true;
            }
            else
            {
                // El valor del elemento a agregar es menor
                // que el valor de la raíz del subárbol a considerar
                if (item.CompareTo(root.Item) < 0)
                {
                    // Se agrega recursivamente por la izquierda
                    root.Left = AddAVL(root.Left, item, ref flag);
                    if (flag) // si cambió la altura ?
                    {
                        switch (root.Balance)
                        {
                        case -1:
                            // antes izquierda < derecha, después se equilibra
                            // y cambia la bandera
                            root.Balance = 0;
                            flag         = false;
                            break;

                        case 0:
                            // antes izquierda = derecha, después izquierda mas grande
                            // en algún nivel superior puede hacer falta un rebalanceo
                            // la bandera queda como estaba (true)
                            root.Balance = 1;
                            break;

                        case 1:
                            // antes izquierda > derecha, hay que rebalancear
                            n1 = root.Left;
                            if (n1.Balance == 1)
                            {
                                // la izquierda de la izquierda es mayor
                                // rotación simple izquierda-izquierda
                                root = LeftLeftRotation(root, n1);
                            }
                            else
                            {
                                // rotación doble izquierda-derecha
                                root = LeftRightRotation(root, n1);
                            }
                            // subárbol ajustado cambia la bandera
                            flag = false;
                            break;
                        }
                    }
                }
                else
                {
                    // El valor del elemento a agregar es mayor
                    // que el valor de la raíz del subárbol a considerar
                    if (item.CompareTo(root.Item) > 0)
                    {
                        // Se agrega recursivamente por la derecha
                        root.Right = AddAVL(root.Right, item, ref flag);
                        if (flag) // si cambió la altura ?
                        {
                            switch (root.Balance)
                            {
                            case -1:
                                // antes izquierda < derecha, hay que rebalancer
                                n1 = root.Right;
                                if (n1.Balance == -1)
                                {
                                    // la derecha de la derecha es mayor
                                    // rotación simple derecha-derecha
                                    root = RightRightRotation(root, n1);
                                }
                                else
                                {
                                    // rotación doble derecha-izquierda
                                    root = RightLeftRoation(root, n1);
                                }
                                // subárbol ajustado cambia la bandera
                                flag = false;
                                break;

                            case 0:
                                // antes izquierda = derecha, después la derecha mas grande
                                // en algún nivel superior puede hacer falta un rebalanceo
                                // la bandera queda como estaba (true)
                                root.Balance = -1;
                                break;

                            case 1:
                                // antes izquierda > derecha, despues se equilibra
                                // y cambia la bandera
                                root.Balance = 0;
                                flag         = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        // No se puede almacenar claves repetidas
                        throw new Exception("Claves repetidas");
                    }
                }
            }
            return(root);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Implementación recursiva que extraer un elemento del árbol AVL
 /// </summary>
 /// <param name="root">Nodo del subárbol a considerar</param>
 /// <param name="item">Elemento a extraer</param>
 /// <param name="flag">Indica que cambió la altura</param>
 /// <returns>Nodo raiz del subárbol considerado</returns>
 protected virtual AVLNode <E> RemoveAVL(AVLNode <E> root, E item, ref bool flag)
 {
     // No se puede extraer nodos de un árbol vacío
     if (root == null)
     {
         throw new Exception("No existe");
     }
     // El valor del elemento a extraer es menor
     // que el valor de la raíz del subárbol a considerar
     if (item.CompareTo(root.Item) < 0)
     {
         // Se procesa recursivamente por la izquierda
         root.Left = RemoveAVL(root.Left, item, ref flag);
         if (flag)
         {
             // Cambió la altura, analizar el balance
             root = LeftBalance(root, ref flag);
         }
     }
     else
     {
         // El valor del elemento a extraer es mayor
         // que el valor de la raíz del subárbol a considerar
         if (item.CompareTo(root.Item) > 0)
         {
             // Se procesa recursivamente por la derecha
             root.Right = RemoveAVL(root.Right, item, ref flag);
             if (flag)
             {
                 // Cambió la altura, analizar el balance
                 root = RightBalance(root, ref flag);
             }
         }
         else
         { // encontrado
             AVLNode <E> q;
             q = root;
             if (q.Left == null)
             {
                 // Un único descendiente, cambia la altura
                 root = q.Right;
                 flag = true;
             }
             else
             {
                 if (q.Right == null)
                 {
                     // Un único descendiente, cambia la altura
                     root = q.Left;
                     flag = true;
                 }
                 else
                 { // tiene dos subárboles !!!
                     root.Left = Repleace(root, root.Left, ref flag);
                     if (flag)
                     {
                         // Cambió la altura, analizar el balance
                         root = LeftBalance(root, ref flag);
                     }
                     q = null;
                 }
             }
         }
     }
     return(root);
 }
Exemplo n.º 3
0
 /// <summary>
 /// Constructor especializado, permite fijar el elemento del nodo
 /// y el valor de los enlaces a subárboles izquierdo y derecho
 /// </summary>
 /// <param name="item">Elemento en el nodo</param>
 /// <param name="next">Enlace al subárbol izquierdo</param>
 /// <param name="prev">Enlace al subárbol derecho</param>
 public AVLNode(E item = default(E), AVLNode <E> left = null, AVLNode <E> right = null)
 {
     this.Item  = item;
     this.Left  = left;
     this.Right = right;
 }