4-2do PA

Metodo Arbol en equipo

public class Arbol
{
  private boolean division = false; // variable para saber si el arreglo (Nodo) fue dividido con exito
  private boolean encontrado = false; // variable para saber si el numero fue encontrado
  protected Arbol.Node raiz; // Nodo Raiz del arbol 234
  private Integer profundidad; // un numero entero para ir almacenando la profundidad del arbol
 
  public Arbol()
  {
    raiz = CrearNodo(); // creamos un nuevo nodo lol :v
  }
 

  public boolean insertar(int numero) throws NodoExcepciones // ya sabes Exceptions personalizadas
  {
    if ((encontrado) && (buscar(numero))) {  // no se inserta numeros iguales te retorna false :v
      return false;
    }
    if ((division) && (raiz.numeros == 3))// si el nodo ya esta lleno, creo un nuevo nodo para almacenar nuevos numeros
    {
      raiz.alturaArbol = true;
      Arbol.Node nodoAuxilar = CrearNodo();
      nodoAuxilar.hijos[0] = raiz; // el hijo sera la raiz
      raiz.padre = nodoAuxilar;// el nuevo nodo padre sera el nuevo nodo creado
      raiz = nodoAuxilar;
      nodoAuxilar.hijos[0].dividirNodo();
    }
    boolean bool = raiz.insertarNumero(numero);
    mantenimiento();
   return bool;
  }
 
  public boolean buscar(int numero)
  {
    return raiz.buscarNumero(numero);
  }
 
  public boolean borrar(int numero) throws NodoExcepciones
  {
    if ((encontrado) && (!buscar(numero))) { // si el numero no es encontrado te retorna false
      return false;
    }
    boolean bool = raiz.borrarNumero(numero);
    mantenimiento(); // este metodo sirve para inicializar la profundidad y llamar al metodo chequeoArbol
    return bool;
  }
 
  private void mantenimiento() throws NodoExcepciones
  {
    try
    {
      profundidad = null;
      chequeoArbol(); // este metodo sirve reorganizar el arbol despues de haberse borrado un numero
    }
    catch (NodoExcepciones ex)
    {
      
      throw ex;
    }
  }
 
  private void chequeoArbol() throws NodoExcepciones
  {
    if (raiz.padre != null) {
      throw new NodoExcepciones("el padre debe ser null");
    }
    raiz.chequeoArbol(0); // si el padre es null, insertamos un cero al arbol
  }
 
 
  public void imprimir()
  {
    raiz.imprimirArbol();
  }
 
 
 
  protected Arbol.Node CrearNodo()
  {
    return new Arbol.Node(); // creamos un nuevo nodo
  }
 
  private class Node
  {
    protected int numeros; // los numeros que vamos a ingresar
    protected int[] valoresNodo; // es donde vamos a guardar los numeros
    protected Node padre; // nodo padre
    protected Node[] hijos; // es donde vamos a guardar los numeros que van hacer hijos
    protected boolean alturaArbol = false;
    
    public Node()
    {
      numeros = 0;
      valoresNodo = new int[3]; // cada nodo tiene un maximo de 3 numeros
      padre = null;
      hijos = new Node[4]; // cuando el arbol este lleno osea con 3 numeros, el numero maximo de hijos podra ser de 4
                            // ojo cada elemento del arreglo podra tener hasta 3 numeros
    }
    
    public boolean insertarNumero(int numero) throws NodoExcepciones
    {
      alturaArbol = true;

      try
      {
    
        if (hijos[0] == null)
        {
          if (numeros == 3)
          {
            if ((valoresNodo[0] == numero) || (valoresNodo[1] == numero) || (valoresNodo[2] == numero)) // no se inserta numeros repetidos
            {
              alturaArbol = false;
              return false;
            }
            return dividirNodo().insertarNumero(numero); // si el nodo es igual a 3 , se debe dividir el arreglo
          }
          for (int i = 0; i < numeros; i++)
          {
            if (valoresNodo[i] == numero) // es solo una comprobacion q no se repite el numero ingresado
            {
               alturaArbol = false;
              return false;
            }
            if (numero < valoresNodo[i])
            {
              for (int k = numeros; k > i; k--) {
                valoresNodo[k] = valoresNodo[(k - 1)];
              }
                valoresNodo[i] = numero;
              numeros += 1;
              return true;
            }
          }
              valoresNodo[(numeros++)] = numero;
          return true;
        }
         alturaArbol = false;
        for (int j = 0; j < numeros; j++)
        {
          if (numero == valoresNodo[j]) {
            return false;
          }
          if (numero < valoresNodo[j])
          {
            if ((Arbol.this.division) && (hijos[j].numeros == 3)) {
              return hijos[j].dividirNodo().insertarNumero(numero);
            }
            return hijos[j].insertarNumero(numero);
          }
        }
      
        if ((Arbol.this.division) && (hijos[numeros].numeros == 3)) {
          return hijos[numeros].dividirNodo().insertarNumero(numero);
        }
        return hijos[numeros].insertarNumero(numero);
      }
      finally
      {
        if (alturaArbol)
        {
          alturaArbol = false;
        }
      }
    }
    
    private Node dividirNodo() throws NodoExcepciones
    {
        Node nodoAuxilar;
      if (numeros != 3) {
        throw new NodoExcepciones("error el nodo tiene 3 elementos");
      }
      if (padre == null)
      {
        nodoAuxilar = Arbol.this.CrearNodo();
        nodoAuxilar.hijos[0] = this;
        padre = nodoAuxilar;
        Arbol.this.raiz = nodoAuxilar;
      }
      padre.alturaArbol = true;
      alturaArbol = true;
     
      if (padre.numeros == 3)
      {
        padre.dividirNodo(); // si el padre tiene 3 numeros en el nodo, hay que dividir el arreglo
    
      }
      padre.alturaArbol = false;
      alturaArbol = false;
      
      nodoAuxilar = Arbol.this.CrearNodo();
      nodoAuxilar.numeros = 1;
      nodoAuxilar.valoresNodo = new int[3];
      nodoAuxilar.valoresNodo[0] = valoresNodo[2];
      nodoAuxilar.padre = padre;
      nodoAuxilar.hijos = new Node[4];
      if (hijos[2] != null)
      {
        nodoAuxilar.hijos[0] = hijos[2];
        nodoAuxilar.hijos[0].padre = nodoAuxilar;
        nodoAuxilar.hijos[1] = hijos[3];
        nodoAuxilar.hijos[1].padre = nodoAuxilar;
      }
        numeros = 1;  
       Node temporal = null;
        hijos[3] = temporal;
        hijos[2] = temporal;
        padre.Meter(valoresNodo[1], nodoAuxilar); // con el metodo meter, vamos metiendo otra vez los numeros sacados
      return padre;
    }
    
    private void Meter(int numero, Node nodito) throws NodoExcepciones
    {
      int i = numeros;
      while ((i != 0) && (numero < valoresNodo[(i - 1)]))
      {
         valoresNodo[i] = valoresNodo[(i - 1)];
        hijos[(i + 1)] = hijos[i];
        i--;
      }
      numeros += 1;
      valoresNodo[i] = numero;
      hijos[(i + 1)] = nodito;
      nodito.padre = this;
    }

    public void imprimirArbol()
    {
    
      System.out.print("Cantidad de numeros en el nodo (" + numeros + "): " );
      for (int i = 0; i < numeros; i++) {
        System.out.print(valoresNodo[i] + " ");
      }
     
      
      System.out.println();
      if (hijos[0] != null) {
        hijos[0].imprimirArbol();
      }
       
      if (hijos[1] != null) {
            hijos[1].imprimirArbol();
      }
     if (hijos[2] != null) {
           hijos[2].imprimirArbol();
      }
      if (hijos[3] != null) {
            hijos[3].imprimirArbol();
     }
              
    }
    
    public boolean buscarNumero(int numero)
    {
      alturaArbol = true;
      alturaArbol = false;
      try
      {
        for (int i = 0; i < numeros; i++)
        {
          if (numero == valoresNodo[i]) {
            return true; // si el numero se encuentra en el arreglo retorna true
          }
          if (numero < valoresNodo[i])
          {
            if (hijos[i] == null) { // retorna false si los hijos stan vacios
              return false;
            }
            return hijos[i].buscarNumero(numero); // llamada recursiva
          }
        }
        if (hijos[numeros] == null) {
          return false;
        }
        return hijos[numeros].buscarNumero(numero); // llamada recursiva
      }
      finally
      {
        alturaArbol = false;
      }
    }
    
    private void UnirNodos(int numero) throws NodoExcepciones
    {
      if ((numeros == 1) && (this != Arbol.this.raiz)) {
        throw new NodoExcepciones("no hay suficiente valores para el nodo!");
      }
      Node localNode1 = hijos[numero];
      Node localNode2 = hijos[(numero + 1)];
      if (localNode1.numeros != 1) {
        throw new NodoExcepciones("demasiado valores en los hijos --> error!");
      }
      if (localNode2.numeros != 1) {
        throw new NodoExcepciones("demasiado valores en los hijos --> error!");
      }
      localNode1.alturaArbol = true;
      localNode2.alturaArbol = true;
    

      localNode1.valoresNodo[1] = valoresNodo[numero];
      localNode1.valoresNodo[2] = localNode2.valoresNodo[0];
      localNode1.numeros = 3;
      for (int i = numero; i < numeros - 1; i++)
      {
         valoresNodo[i] = valoresNodo[(i + 1)];
        hijos[(i + 1)] = hijos[(i + 2)];
      }
        hijos[numeros] = null;
      numeros -= 1;
      if (localNode1.hijos[0] != null)
      {
        localNode1.hijos[2] = localNode2.hijos[0];
        localNode1.hijos[2].padre = localNode1;
        localNode1.hijos[3] = localNode2.hijos[1];
        localNode1.hijos[3].padre = localNode1;
      }
     
      localNode1.alturaArbol = false;
      if ((this == Arbol.this.raiz) && (numeros == 0))
      {
        Arbol.this.raiz = localNode1;
        Arbol.this.raiz.padre = null;
        Arbol.this.raiz.alturaArbol = true;
      
      }
    }
    
    private Node mantenerValores(int numero, Node nodo1, Node nodo2, Node nodo3)
      throws NodoExcepciones
    {
      if (nodo2.numeros != 1) {
        return nodo2;
      }
      nodo2.alturaArbol = true;
      int i = 1;
      if ((nodo1 != null) && (nodo1.numeros > 1))
      {
        i = 1;
        nodo1.alturaArbol = true;
        numero--;
      }
      else if ((nodo3 != null) && (nodo3.numeros > 1))
      {
        i = 0;
        nodo3.alturaArbol = true;
      }
      else
      {
        if (nodo1 != null)
        {
          UnirNodos(numero - 1);
          return nodo1;
        }
        if (nodo3 != null)
        {
          UnirNodos(numero);
          return nodo2;
        }
        throw new NodoExcepciones("error !");
      }
     
      if (i != 0)
      {
        nodo2.valoresNodo[1] = nodo2.valoresNodo[0];
        nodo2.valoresNodo[0] = valoresNodo[numero];
        valoresNodo[numero] = nodo1.valoresNodo[(nodo1.numeros - 1)];
        if (nodo2.hijos[0] != null)
        {
          nodo2.hijos[2] = nodo2.hijos[1];
          nodo2.hijos[1] = nodo2.hijos[0];
          nodo2.hijos[0] = nodo1.hijos[nodo1.numeros];
          nodo1.hijos[nodo1.numeros] = null;
          nodo2.hijos[0].padre = nodo2;
        }
        nodo1.numeros -= 1;
        nodo2.numeros = 2;
      }
      else
      {
        nodo2.valoresNodo[1] = valoresNodo[numero];
        valoresNodo[numero] = nodo3.valoresNodo[0];
        if (nodo2.hijos[0] != null)
        {
          nodo2.hijos[2] = nodo3.hijos[0];
          nodo2.hijos[2].padre = nodo2;
        }
        for (int j = 0; j < nodo3.numeros - 1; j++)
        {
          nodo3.valoresNodo[j] = nodo3.valoresNodo[(j + 1)];
          nodo3.hijos[j] = nodo3.hijos[(j + 1)];
        }
        nodo3.hijos[(nodo3.numeros - 1)] = nodo3.hijos[nodo3.numeros];
        nodo3.hijos[nodo3.numeros] = null;
        nodo3.numeros -= 1;
        

        nodo2.numeros = 2;
      }
      
      if (nodo1 != null) {
        nodo1.alturaArbol = false;
      }
      if (nodo3 != null) {
        nodo3.alturaArbol = false;
      }
      nodo3.alturaArbol = false;
      return nodo3;
    }
    
    public int DeleteMax()
      throws NodoExcepciones
    {
      if (numeros == 1) {
        throw new NodoExcepciones("no hay como borrar!");
      }
          alturaArbol = true;
      
      try
      {
        int j;
        if (hijos[0] != null)
        {
          Node nodoAuxiliar1 = hijos[numeros];
          nodoAuxiliar1.alturaArbol = true;
         
          if (nodoAuxiliar1.numeros == 1)
          {
            Node nodoAuxiliar2 = hijos[(numeros - 1)];
            nodoAuxiliar2.alturaArbol = true;
           
            if (nodoAuxiliar2.numeros == 1) {
              UnirNodos(numeros - 1);
            } else {
              mantenerValores(numeros, hijos[(numeros - 1)], hijos[numeros], null);
            }
            return hijos[numeros].DeleteMax();
          }
          return nodoAuxiliar1.DeleteMax();
        }
        int i = valoresNodo[(--numeros)];
       
        return i;
      }
      finally
      {
         alturaArbol = false;
      }
    }
    
    public int DeleteMin()
      throws NodoExcepciones
    {
      if (numeros == 1) {
        throw new NodoExcepciones("no hay como borrar!");
      }
         alturaArbol = true;
     
      try
      {
        if (hijos[0] != null)
        {
          Node nodoAuxiliar1 = hijos[0];
          nodoAuxiliar1.alturaArbol = true;
         
          if (nodoAuxiliar1.numeros == 1)
          {
            Node nodoAuxilar2 = hijos[1];
            nodoAuxilar2.alturaArbol = true;
          
            if (nodoAuxilar2.numeros == 1) {
              UnirNodos(0);
            } else {
              mantenerValores(0, null, hijos[0], hijos[1]);
            }
            return hijos[0].DeleteMin();
          }
          return nodoAuxiliar1.DeleteMin();
        }
        int i = valoresNodo[0];
        for (int j = 0; j < numeros - 1; j++) {
          valoresNodo[j] = valoresNodo[(j + 1)];
        }
         numeros -= 1;
       
        return i;
      }
      finally
      {
         alturaArbol = false;
      }
    }
    
    public boolean borrarNumero(int numero) throws NodoExcepciones
    {
      if (numeros == 0) {
        return false;
      }
          alturaArbol = true;
     
      boolean bool1 = false;
      int i = 0;
      Object miObjeto = null;
      Node nodoAuxiliar1 = null;
      Node nodoAuxiliar2 = null;
      try
      {
        for (; i < numeros; i++)
        {
          miObjeto = nodoAuxiliar1;
          nodoAuxiliar1 = hijos[i];
          nodoAuxiliar2 = hijos[(i + 1)];
          if (numero == valoresNodo[i]) {
            bool1 = true;
          } else {
            if (numero < valoresNodo[i]) {
              break;
            }
          }
        }
        if (i == numeros)
        {
          miObjeto = hijos[(i - 1)];
          nodoAuxiliar1 = hijos[i];
          nodoAuxiliar2 = null;
        }
        boolean bool2;
        if (hijos[0] == null)
        {
          if (bool1)
          {
            for (; i < numeros - 1; i++) {
              valoresNodo[i] = valoresNodo[(i + 1)];
            }
               numeros -= 1;
           
          }
          return bool1;
        }
        if (bool1)
        {
          if (nodoAuxiliar1.numeros > 1)
          {
            valoresNodo[i] = nodoAuxiliar1.DeleteMax();
           
            return true;
          }
          if (nodoAuxiliar2.numeros > 1)
          {
             valoresNodo[i] = nodoAuxiliar2.DeleteMin();
           
            return true;
          }
          UnirNodos(i);
           alturaArbol = false;
          return nodoAuxiliar1.borrarNumero(numero);
        }
        Node nodoAuxiliar3 = mantenerValores(i, (Node)miObjeto, nodoAuxiliar1, nodoAuxiliar2);
        

        alturaArbol = false;
        return nodoAuxiliar3.borrarNumero(numero);
      }
      finally
      {
        alturaArbol = false;
      }
    }
    
    public void chequeoArbol(int numero) throws NodoExcepciones
    {
      for (int i = 0; i <= numeros; i++) {
        if (hijos[i] != null)
        {
          if (hijos[i].padre != this) {
            throw new NodoExcepciones(this + " error coño :v!");
          }
             hijos[i].chequeoArbol(numero + 1);
        }
        else if (Arbol.this.profundidad == null)
        {
          if (i != 0) {
            throw new NodoExcepciones(this + " problemas con el primer nodito!");
          }
          Arbol.this.profundidad = numero;
        }
        else if (Arbol.this.profundidad != numero)
        {
          throw new NodoExcepciones(this + " la profundidad no es igual al numero");
        }
      }
      for (int i = numeros + 1; i < 4; i++) {
        if (hijos[i] != null) {
          throw new NodoExcepciones(this + " los hijos deberian ser nulos coño");
        }
      }
    }
  }
}

Clase Main

public class Main {
    public static void main(String [] args) throws NodoExcepciones
    {
        Arbol arbol= new Arbol();
        arbol.insertar(5);
        arbol.insertar(10);
        arbol.insertar(20);
        arbol.insertar(7);
        arbol.insertar(11);
        arbol.insertar(0);
        arbol.insertar(8);
        arbol.insertar(60);
         // arbol.insertar(70);
        arbol.imprimir();
        
        boolean resul=arbol.buscar(0);
       
        System.out.println("el numero 0  se encuentra en el arbol? " + resul);
    }

Clase Nodo

public class NodoExcepciones extends Exception
{
  NodoExcepciones(String paramString)
  {
    super(paramString);
  }
}

Comentarios