Posts Tagged ‘Programacion’
Arbol AVL [C Sharp]
Listas Enlazadas Dobles
Árbol AVL es un tipo especial de árbol binario ideado por los matemáticos rusos Adelson-Velskii y Landis. Fue el primer árbol de búsqueda binario auto-balanceable que se ideó.
Arbol binario No-AVLArbol Binario AVLPara mas info sobre arboles AVL ve a la Wikipedia - Arboles AVL
1.- Primero Creamos un Nuevo Proyecto al que llamaremos "arbol-AVL".
2.- Creamos una clase que nos servira de Nodo "Nodo.sc".
Estructura de la Clase Nodo.sc
-
class Nodo
-
{
-
private double dato;
-
private Nodo nodoIzquierdo;
-
private Nodo nodoDerecho;
-
private Nodo padre;
-
private int fEq;
-
-
private Arbol tree;
-
-
public Nodo(double dato)
-
{
-
this.dato = dato;
-
this.fEq = 0;
-
this.nodoIzquierdo = this.nodoDerecho = this.padre = null;
-
}
-
-
public double Dato
-
{
-
get { return dato; }
-
set { dato = value; }
-
}
-
-
public int FactEq
-
{
-
get { return fEq; }
-
set { fEq = value; }
-
}
-
-
public Nodo NodoIzquierdo
-
{
-
get { return nodoIzquierdo; }
-
set { nodoIzquierdo = value; }
-
}
-
-
public Nodo NodoDerecho
-
{
-
get { return nodoDerecho; }
-
set { nodoDerecho = value; }
-
}
-
-
public Nodo Padre
-
{
-
get { return padre; }
-
set { padre = value; }
-
}
-
-
public Arbol Tree
-
{
-
get { return tree; }
-
set { tree = value; }
-
}
-
}
3.- Creamos una clase "Arbol.sc" para poder enlazar nodo a nodo
Estructura de la Clase Arbol.sc.
-
class Arbol
-
{
-
private Nodo root;
-
-
private int size;
-
-
public void limpiar()
-
{
-
this.root = null;
-
}
-
-
public Arbol()
-
{
-
this.root = null;
-
}
-
-
public Nodo Root
-
{
-
get { return root; }
-
set { root = value; }
-
}
-
-
public void aInsertarNodos()
-
{
-
Console.Write("Ingresar Dato : ");
-
double dato = double.Parse(Console.ReadLine());
-
Add(dato);
-
}
-
-
public void aInsertarVariosNodos(string nodos)
-
{
-
string[] noditos = nodos.Trim().Split(' ');
-
double x;
-
for (int z = 0; z <noditos.Length; z++)
-
{
-
if (double.TryParse(noditos[z], out x))
-
{
-
Add(x);
-
}
-
else
-
{
-
Console.WriteLine("Error de Parsing");
-
}
-
}
-
}
-
-
private void Add(double valor)
-
{
-
Add(nuevo);
-
-
Nodo nodoPadre = nuevo.Padre;
-
-
while (nodoPadre != null)
-
{
-
int balance = getBalance(nodoPadre);
-
if (Math.Abs(balance) == 2) //-2 o 2 = Desvalanceado
-
{
-
//Rebalancear arbol
-
balancear(nodoPadre, balance);
-
}
-
nodoPadre = nodoPadre.Padre;
-
}
-
Console.ReadKey();
-
}
-
-
private void Add(Nodo nuevo)
-
{
-
if (root == null)
-
{
-
this.root = nuevo;
-
nuevo.Tree = this; //asignar a este nodo de árbol binario
-
Console.WriteLine("\n\tInsertando -->> {0}", nuevo.Dato);
-
size++;
-
}
-
else
-
{
-
if (nuevo.Padre == null)
-
nuevo.Padre = root;
-
-
if (nuevo.Dato <nuevo.Padre.Dato)
-
{
-
if (nuevo.Padre.NodoIzquierdo == null)
-
{
-
nuevo.Padre.NodoIzquierdo = nuevo;
-
Console.WriteLine("\tInsertando a la Izquierda -->> {0}", nuevo.Dato);
-
//Console.WriteLine("factor de equilibrio -->> {0}", getBalance(node));
-
size++;
-
nuevo.Tree = this;//asignar a este nodo de árbol binario
-
}
-
else
-
{
-
nuevo.Padre = nuevo.Padre.NodoIzquierdo;
-
Add(nuevo);
-
}
-
}
-
else
-
{
-
if (nuevo.Dato> nuevo.Padre.Dato)
-
{
-
if (nuevo.Padre.NodoDerecho == null)
-
{
-
nuevo.Padre.NodoDerecho = nuevo;
-
Console.WriteLine("\tInsertando a la Derecha -->> {0}", nuevo.Dato);
-
//Console.WriteLine("factor de equilibrio -->> {0}", getBalance(node));
-
size++;
-
nuevo.Tree = this; //asignar a este nodo de árbol binario
-
}
-
else
-
{
-
nuevo.Padre = nuevo.Padre.NodoDerecho;
-
Add(nuevo);
-
}
-
}
-
else
-
{
-
Console.WriteLine("\tNo se pudo insertar -->> {0}", nuevo.Dato);
-
}
-
}
-
}
-
}
-
-
private void balancear(Nodo nodito, int balance)
-
{
-
if (balance == 2)
-
{
-
int balanceDerecho = getBalance(nodito.NodoDerecho);
-
-
if (balanceDerecho == 1 || balanceDerecho == 0)
-
{
-
Console.WriteLine("\t -->> Rotando a la Izquierda Nodo [{0}] Balance -> {1}", nodito.Dato, getBalance(nodito));
-
rotarIzquierda(nodito);
-
}
-
else if (balanceDerecho == -1)
-
{
-
Console.WriteLine("\t -->> Rotando a la Derecha Nodo [{0}] Balance -> {1}", nodito.NodoDerecho.Dato, getBalance(nodito.NodoIzquierdo));
-
rotarDerecha(nodito.NodoDerecho);
-
-
Console.WriteLine("\t -->> Rotando a la Izquierda Nodo [{0}] Balance -> {1}", nodito.Dato, getBalance(nodito));
-
rotarIzquierda(nodito);
-
}
-
}
-
else if (balance == -2)
-
{
-
int leftBalance = getBalance(nodito.NodoIzquierdo);
-
if (leftBalance == 1)
-
{
-
Console.WriteLine("\t -->> Rotando a la Izquierda Nodo [{0}] Balance -> {1}", nodito.NodoIzquierdo.Dato, getBalance(nodito.NodoIzquierdo));
-
rotarIzquierda(nodito.NodoIzquierdo);
-
-
Console.WriteLine("\t -->> Rotando a la Derecha Nodo [{0}] Balance -> {1}", nodito.Dato, getBalance(nodito));
-
rotarDerecha(nodito);
-
}
-
else if (leftBalance == -1 || leftBalance == 0)
-
{
-
Console.WriteLine("\t -->> Rotando a la Derecha Nodo [{0}] Balance -> {1}", nodito.Dato, getBalance(nodito));
-
rotarDerecha(nodito);
-
}
-
}
-
}
-
-
private void rotarIzquierda(Nodo root)
-
{
-
if (root == null)
-
return;
-
-
Nodo pivote = root.NodoDerecho;
-
-
if (pivote == null)
-
return;
-
else
-
{
-
Nodo padreRoot = root.Padre;
-
bool esNodoIzquierdo = (padreRoot != null) && padreRoot.NodoIzquierdo == root;
-
bool xd = root.Tree.Root == root;
-
-
//Rotando
-
root.NodoDerecho = pivote.NodoIzquierdo;
-
pivote.NodoIzquierdo = root;
-
-
//Actualizando padre
-
root.Padre = pivote;
-
pivote.Padre = padreRoot;
-
-
if (root.NodoDerecho != null)
-
root.NodoDerecho.Padre = root;
-
-
if (xd)
-
pivote.Tree.Root = pivote;
-
-
if (esNodoIzquierdo)
-
padreRoot.NodoIzquierdo = pivote;
-
else
-
if (padreRoot != null)
-
padreRoot.NodoDerecho = pivote;
-
}
-
}
-
-
private void rotarDerecha(Nodo root)
-
{
-
if (root == null)
-
return;
-
-
Nodo pivote = root.NodoIzquierdo;
-
-
if (pivote == null)
-
return;
-
else
-
{
-
Nodo padreRoot = root.Padre;
-
bool esNodoIzquierdo = (padreRoot != null) && padreRoot.NodoIzquierdo == root;
-
bool xd = root.Tree.Root == root;
-
-
//Rotando
-
root.NodoIzquierdo = pivote.NodoDerecho;
-
pivote.NodoDerecho = root;
-
-
//Actualizando padre
-
root.Padre = pivote;
-
pivote.Padre = padreRoot;
-
-
if (root.NodoIzquierdo != null)
-
root.NodoIzquierdo.Padre = root;
-
-
if (xd)
-
pivote.Tree.Root = pivote;
-
-
if (esNodoIzquierdo)
-
padreRoot.NodoIzquierdo = pivote;
-
else
-
if (padreRoot != null)
-
padreRoot.NodoDerecho = pivote;
-
}
-
}
-
-
private int getAltura(Nodo nodoActual)
-
{
-
if (nodoActual == null)
-
return 0;
-
else
-
return 1 + Math.Max(getAltura(nodoActual.NodoIzquierdo), getAltura(nodoActual.NodoDerecho));
-
}
-
-
private int getBalance(Nodo root)
-
{
-
return this.getAltura(root.NodoDerecho) - this.getAltura(root.NodoIzquierdo);
-
}
-
-
public void aMostrarEstructura(int index)
-
{
-
if (root == null)
-
{
-
Console.WriteLine("NO se puede visualizar la estructura...");
-
return;
-
}
-
-
Console.WriteLine("\tNodo Raiz -->> {0}", this.root.Dato);
-
Console.WriteLine();
-
mostrarPreInPostOrden(this.root, index);
-
return;
-
}
-
-
private void mostrarNodoInfo(Nodo nodito)
-
{
-
if (nodito == null)
-
{
-
Console.WriteLine("No existe el nodo en la estructura!");
-
return;
-
}
-
Console.WriteLine("\tNODO ACTUAL---->>> {0}", nodito.Dato);
-
Console.WriteLine("\tFact. Equilibrio-> {0}", getBalance(nodito));
-
Console.WriteLine("\tAltura del Nodo--> {0}", getAltura(nodito));
-
Console.Write("\tPunteros:\t\t");
-
if (nodito.NodoIzquierdo == null)
-
{
-
Console.Write("[X]\t<---");
-
}
-
else
-
{
-
Console.Write("{0}\t<---", nodito.NodoIzquierdo.Dato);
-
}
-
-
Console.Write("\t[{0}]\t", nodito.Dato);
-
if (nodito.NodoDerecho == null)
-
{
-
Console.WriteLine("--->\t[X]");
-
}
-
else
-
{
-
Console.WriteLine("--->\t{0}", nodito.NodoDerecho.Dato);
-
}
-
Console.WriteLine();
-
}
-
-
private void mostrarPreInPostOrden(Nodo nActual, int index)
-
{
-
if (nActual == null) return;
-
switch (index)
-
{
-
case 0: //preOrden();
-
mostrarNodoInfo(nActual);
-
mostrarPreInPostOrden(nActual.NodoIzquierdo, index);
-
mostrarPreInPostOrden(nActual.NodoDerecho, index);
-
break;
-
case 1: //inOrden;
-
mostrarPreInPostOrden(nActual.NodoIzquierdo, index);
-
mostrarNodoInfo(nActual);
-
mostrarPreInPostOrden(nActual.NodoDerecho, index);
-
break;
-
case 2: //postOrden;
-
mostrarPreInPostOrden(nActual.NodoIzquierdo, index);
-
mostrarPreInPostOrden(nActual.NodoDerecho, index);
-
mostrarNodoInfo(nActual);
-
break;
-
}
-
return;
-
}
-
-
}
4.- Y por ultimo la clase "Program.sc".
-
static void Main(string[] args)
-
{
-
Console.Title = "Arbol AVL : Mikiman";
-
int op;
-
do
-
{
-
try
-
{
-
Console.Clear();
-
Console.WriteLine("==============================");
-
Console.WriteLine(" Arbol AVL ");
-
Console.WriteLine("------------------------------");
-
Console.WriteLine("[1] - Ingresar Varios Nodos (Parsing de Numeros)");
-
Console.WriteLine("[2] - Insertar Nodo (Uno por Uno)");
-
Console.WriteLine("[3] - Recorrido preOrden");
-
Console.WriteLine("[4] - Recorrido inOrden");
-
Console.WriteLine("[5] - Recorrido postOrden");
-
if (avl.Root != null)
-
Console.WriteLine("[6] - Limpiar Arbol");
-
Console.WriteLine("[0] - Salir");
-
Console.WriteLine("------------------------------");
-
Console.Write("opcion : ");
-
op = int.Parse(Console.ReadLine());
-
Console.WriteLine("------------------------------");
-
switch (op)
-
{
-
case 1:
-
Console.Write("Ingrese Numeros Separados por Espacios: ");
-
avl.aInsertarVariosNodos(Console.ReadLine());
-
Console.WriteLine("\nNodos Insertados...");
-
Console.ReadLine();
-
break;
-
case 2:
-
avl.aInsertarNodos();
-
break;
-
case 3:
-
avl.aMostrarEstructura(0);
-
Console.ReadLine();
-
break;
-
case 4:
-
avl.aMostrarEstructura(1);
-
Console.ReadLine();
-
break;
-
case 5:
-
avl.aMostrarEstructura(2);
-
Console.ReadLine();
-
break;
-
case 6:
-
avl.limpiar();
-
Console.WriteLine("Arbol Limpiado");
-
Console.ReadLine();
-
break;
-
case 0:
-
string chao = "\n\tMikiman - Con Estilo y Elegancia ..........";
-
Console.Write("\t\t");
-
for (int x = 0; x <chao.Length; x++)
-
{
-
Console.Write(chao.Substring(x, 1));
-
Console.Beep(1760, 60);
-
}
-
Console.WriteLine();
-
break;
-
}
-
}
-
catch (Exception ex)
-
{
-
Console.WriteLine(ex.Message);
-
Console.ReadLine();
-
op = 10;
-
}
-
} while (op != 0);
-
}
Cualquier duda, queja o sugerencia puedes comentarla y yo tratare de responder lo mas pronto posible.










