Esempio n. 1
0
 /// <summary>
 /// Constructor con parámetros incluidos
 /// </summary>
 /// <param name="dato">El dato a insertar</param>
 /// <param name="hijoIzquierdo">Si posee hijo izquierdo lo agregamos de una vez</param>
 /// <param name="hijoDerecho">Si posee hijo derecho lo agregamos de un vez</param>
 public ArbolBinarioBase(T dato, IArbolBinario <T> hijoIzquierdo,
                         IArbolBinario <T> hijoDerecho)
 {
     this.valor         = dato;
     this.izquierdo     = hijoIzquierdo;
     this.derecho       = hijoDerecho;
     this.Padre         = null;
     this.FactorBalance = 0;
 }
Esempio n. 2
0
 public ArbolBinario(T dato, IArbolBinario <T> hijoIzquierdo,
                     IArbolBinario <T> hijoDerecho)
 {
     this.Dato          = dato;
     this.HijoIzquierdo = hijoIzquierdo;
     this.HijoDerecho   = hijoDerecho;
     this.Padre         = null;
     this.FactorBalance = 0;
 }
Esempio n. 3
0
        /// <summary>
        /// Rotación simple a derecha, se usa cuando el FE de un arbol es -2
        /// </summary>
        /// <param name="nodo">El nodo padre que presenta el des-equilibrio</param>
        internal void RSD(IArbolBinario <T> nodo)
        {
            //Punteros necesarios para realizar la rotación.
            IArbolBinario <T> Padre = nodo.Padre; //Parde el árbol desequilibrado.
            IArbolBinario <T> P     = nodo;       //Nodo desequilibrado
            IArbolBinario <T> Q     = P.izquierdo;
            IArbolBinario <T> B     = Q.derecho;  //Nodo con altura igual al hijo derecho de P

            //Si el padre del nodo desequilibrado no es null verifico si el nodo desequilibrado es el derecho
            //o el izquierdo, si el padre es null, significa que es la raiz.
            if (Padre != null)
            {
                if (Padre.derecho == P)
                {
                    Padre.derecho = Q;
                }
                else
                {
                    Padre.izquierdo = Q;
                }
            }
            else
            {
                _raiz       = Q as ArbolBinarioBase <T>;
                _raiz.Padre = null; //para que siga funcionando el padre de la raiz debe ser nulo.
            }

            //Reconstruyo el arbol
            P.izquierdo = B;
            Q.derecho   = P;

            //Actualizando los nuevos padres
            P.Padre = Q;
            if (B != null)
            {
                B.Padre = P;
            }
            Q.Padre = Padre;


            //Ajuste de valores del factor de balance
            if (Q.FactorBalance == 0)
            {
                P.FactorBalance = -1;
                Q.FactorBalance = 1;
            }
            else
            {
                P.FactorBalance = 0;
                Q.FactorBalance = 0;
            }
        }
Esempio n. 4
0
        internal void RDI(IArbolBinario <T> nodo)
        {
            //Punteros necesarios para realizar la rotación
            IArbolBinario <T> Padre = nodo.Padre;
            IArbolBinario <T> P     = nodo;
            IArbolBinario <T> Q     = nodo.HijoDerecho;
            IArbolBinario <T> R     = Q.HijoIzquierdo;
            IArbolBinario <T> B     = R.HijoIzquierdo;
            IArbolBinario <T> C     = R.HijoDerecho;

            //Si el padre del nodo desequilibrado no es null verifico si el nodo desequilibrado es el derecho
            //o el izquierdo, si el padre es null, significa que es la raiz.
            if (Padre != null)
            {
                if (Padre.HijoDerecho == P)
                {
                    Padre.HijoDerecho = R;
                }
                else
                {
                    Padre.HijoIzquierdo = R;
                }
            }
            else
            {
                _raiz       = R as ArbolBinario <T>;
                _raiz.Padre = null;                 //para que siga funcionando el padre de la raiz debe ser nulo.
            }
            // Recontrucción del árbol
            P.HijoDerecho   = B;
            Q.HijoIzquierdo = C;
            R.HijoIzquierdo = P;
            R.HijoDerecho   = Q;
            //Actualizando a los padres
            R.Padre = Padre;
            P.Padre = Q.Padre = R;
            if (B != null)
            {
                B.Padre = P;
            }
            if (C != null)
            {
                C.Padre = Q;
            }
            // Ajustar valores de Factores de Balance
            switch (R.FactorBalance)
            {
            case -1:
            {
                P.FactorBalance = 0;
                Q.FactorBalance = 1;
            }
            break;

            case 0:
            {
                P.FactorBalance = 0;
                Q.FactorBalance = 0;
            }
            break;

            case 1:
            {
                P.FactorBalance = -1;
                Q.FactorBalance = 0;
            }
            break;
            }
            R.FactorBalance = 0;
        }
Esempio n. 5
0
        internal void Equilibrar(IArbolBinario <T> nodo, bool esIzquierdo, bool esNuevo)
        {
            bool salir = false;             //al terminar de recorrer una rama si no es necesario rotar entonces se convierte en verdadero.

            // Recorrer camino inverso actualizando valores de FE:
            while ((nodo != null) && !salir)
            {
                bool hizoRotacion = false;                 //Al inicio digo que no se rotó
                if (esNuevo)
                {
                    if (esIzquierdo)
                    {
                        nodo.FactorBalance--;                         // Estamos añidiendo
                    }
                    else
                    {
                        nodo.FactorBalance++;
                    }
                }
                else
                {
                    if (nodo.FactorBalance == 0)
                    {
                        salir = true;
                    }
                    if (esIzquierdo)
                    {
                        nodo.FactorBalance++;                         // Borrando un nodo
                    }
                    else
                    {
                        nodo.FactorBalance--;
                    }
                }
                if (nodo.FactorBalance == 0)
                {
                    salir = true;                     // La altura de el arbol que empieza en nodo no ha variado, salir de Equilibrar
                }
                //Si existe algún desbalance en esta porción de código se realizan las rotaciones
                else if (nodo.FactorBalance == -2)
                {                 // Rotación a la derecha doble o simple según sea el caso y salir.
                    if (nodo.HijoIzquierdo.FactorBalance == 1)
                    {
                        RDD(nodo);                         // Rotación doble
                        hizoRotacion = true;
                    }
                    else
                    {
                        RSD(nodo);                         // Rotación simple
                        hizoRotacion = true;
                    }
                    salir = true;
                }
                else if (nodo.FactorBalance == 2)
                {                  // Rotar a la izquierda doble o simple según sea el caso y salir.
                    if (nodo.HijoDerecho.FactorBalance == -1)
                    {
                        RDI(nodo);                         // Rotación doble
                        hizoRotacion = true;
                    }
                    else
                    {
                        RSI(nodo);                         // Rotación simple
                        hizoRotacion = true;
                    }
                    salir = true;
                }
                if ((hizoRotacion) && (nodo.Padre != null) && (!esNuevo))
                {
                    nodo = nodo.Padre;
                }
                if (nodo.Padre != null)
                {
                    if (nodo.Padre.HijoDerecho == nodo)
                    {
                        esIzquierdo = false;
                    }
                    else
                    {
                        esIzquierdo = true;
                    }
                    if ((!esNuevo) && (nodo.FactorBalance == 0))
                    {
                        salir = false;
                    }
                }
                nodo = nodo.Padre;                 // Calcular Factor de balance, siguiente nodo del camino ossea el padre.
            }
        }
Esempio n. 6
0
 internal void VisitarArbol(IArbolBinario <T> arbol)
 {
     miLista.Agregar(arbol.Dato);
 }
Esempio n. 7
0
        /// <summary>
        /// Rotación doble a la izquierda, se usa cuando la FE del nodo que recibe como parámetro es -2
        /// (Eso significa que su arbol izquierdo es mas grande que el derecho) y
        /// la raiz del subarbol iquierdo tenga FE 1
        /// </summary>
        /// <param name="nodo">El nodo con el desbalance</param>
        internal void RDD(IArbolBinario <T> nodo)
        {
            //Punteros necesarios para realizar la rotación
            IArbolBinario <T> Padre = nodo.Padre;
            IArbolBinario <T> P     = nodo;
            IArbolBinario <T> Q     = P.izquierdo;
            IArbolBinario <T> R     = Q.derecho;
            IArbolBinario <T> B     = R.izquierdo;
            IArbolBinario <T> C     = R.derecho;

            //Si el padre del nodo desequilibrado no es null verifico si el nodo desequilibrado es el derecho
            //o el izquierdo, si el padre es null, significa que es la raiz.
            if (Padre != null)
            {
                if (Padre.derecho == P)
                {
                    Padre.derecho = R;
                }
                else
                {
                    Padre.izquierdo = R;
                }
            }
            else
            {
                _raiz       = R as ArbolBinarioBase <T>;
                _raiz.Padre = null; //para que siga funcionando el padre de la raiz debe ser nulo.
            }

            // Reconstruir árbol:
            Q.derecho   = B;
            P.izquierdo = C;
            R.izquierdo = Q;
            R.derecho   = P;

            // Reasignar padres:
            R.Padre = Padre;
            P.Padre = Q.Padre = R;
            if (B != null)
            {
                B.Padre = Q;
            }
            if (C != null)
            {
                C.Padre = P;
            }


            // Ajustar valores de FE:
            switch (R.FactorBalance)
            {
            case -1:
            {
                Q.FactorBalance = 0;
                P.FactorBalance = 1;
            }
            break;

            case 0:
            {
                Q.FactorBalance = 0;
                P.FactorBalance = 0;
            }
            break;

            case 1:
            {
                Q.FactorBalance = -1;
                P.FactorBalance = 0;
            }
            break;
            }
            R.FactorBalance = 0;
        }