Foros del Web » Programación para mayores de 30 ;) » Java »

Duda al definir un árbol n-ario

Estas en el tema de Duda al definir un árbol n-ario en el foro de Java en Foros del Web. hola, hace poco empecé con el mundo de java y estoy trabajando ahora con árboles. Estoy investigando el tema de los los árboles n-arios y ...
  #1 (permalink)  
Antiguo 20/11/2014, 19:50
 
Fecha de Ingreso: mayo-2006
Mensajes: 70
Antigüedad: 17 años, 11 meses
Puntos: 0
Duda al definir un árbol n-ario

hola,
hace poco empecé con el mundo de java y estoy trabajando ahora con árboles. Estoy investigando el tema de los los árboles n-arios y he visto la siguiente definición por internet.

class Nodo{

int valor;
ArrayList <Nodo> hijos;


Nodo(int new data) {
hijos = new ArrayList <Nodo> ();
valor = new data;
}
}


En la primera parte define la clase nodo como una estructura con un int, y un array de Nodos, de acuerdo, ¿pero por qué hace la segunda parte? Nodo (int new data..) imagino que será quizás el operador para meter el valor en el nodo, pero no entiendo porqué lo hace dentro de la estructura, ni tampoco lo que hace.
  #2 (permalink)  
Antiguo 21/11/2014, 01:39
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Duda al definir un árbol n-ario

Buenas

Eso es el constructor de la clase y lo unico que hace es inicializar el nodo.
Esto:
Nodo(int new data) {

No existe ni compila en Java.

Un saludo
__________________
If to err is human, then programmers are the most human of us
  #3 (permalink)  
Antiguo 21/11/2014, 09:03
 
Fecha de Ingreso: mayo-2006
Mensajes: 70
Antigüedad: 17 años, 11 meses
Puntos: 0
Respuesta: Duda al definir un árbol n-ario

Gracias!
la cosa es que lo veo desde un video de youtube, y el programa compila. De todas formas hice mi versión y parece que va bien. ¿Me lo podrías confirmar?

public class nodoN {

private int valor;
private ArrayList <nodoN> hijos = new ArrayList <nodoN>();
private nodoN padre;
private nodoN raiz;

public void nodoN(){
valor=0;
hijos = new ArrayList<nodoN>();
padre=null;
}

public void nodoN(int v){
valor = v;
hijos.add(null);
padre = null;
}

public void setRaiz (nodoN n)
{
raiz = n;
}

public void agregarHijo(nodoN nodo, nodoN padre)
{
if(padre==null) {setRaiz(nodo);}
hijos.add(nodo);
nodo.padre=padre;

}


}

Última edición por samurai_7; 21/11/2014 a las 10:13
  #4 (permalink)  
Antiguo 21/11/2014, 13:20
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Duda al definir un árbol n-ario

Buenas,

Compila porque en ninguna parte estás haciendo lo que ponías al principio:

Nodo(int new data)

En principio parece correcto, pero no se porqué el método agregarHijo recibe un parámetro padre. Se supone que el padre es el nodo (this) al que le agregas el hijo ¿no?

Un saludo
__________________
If to err is human, then programmers are the most human of us
  #5 (permalink)  
Antiguo 22/11/2014, 09:35
 
Fecha de Ingreso: octubre-2008
Mensajes: 184
Antigüedad: 15 años, 6 meses
Puntos: 1
Respuesta: Duda al definir un árbol n-ario

Hola,
imagino que será para mantener el nivel conectado, e ir pudiendo subir y bajar, ¿no?.

Saludos.
  #6 (permalink)  
Antiguo 22/11/2014, 09:37
 
Fecha de Ingreso: mayo-2006
Mensajes: 70
Antigüedad: 17 años, 11 meses
Puntos: 0
Respuesta: Duda al definir un árbol n-ario

Hola,
exactamente, el padre será donde agrego el hijo, pero es una forma de enganchar los nodos para poder ir subiendo de nivel cuando me interese sin necesidad de empezar de nuevo. ¿no lo ves necesario?.

Un saludo.
  #7 (permalink)  
Antiguo 22/11/2014, 09:54
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Duda al definir un árbol n-ario

Buenas,

Yo no digo que un nodo no deba tener un padre. Eso es correcto.

Lo que digo es que el método debería ser más bien así:

Código Java:
Ver original
  1. public void agregarHijo(nodoN nodo)
  2. {
  3. hijos.add(nodo);
  4. nodo.padre=this;
  5. }

Por otro lado no es necesario hacer la gestión del raiz explícitamente. Elemento raíz será todo aquel que no tenga padre.


Un saludo
__________________
If to err is human, then programmers are the most human of us
  #8 (permalink)  
Antiguo 22/11/2014, 11:12
 
Fecha de Ingreso: mayo-2006
Mensajes: 70
Antigüedad: 17 años, 11 meses
Puntos: 0
Respuesta: Duda al definir un árbol n-ario

hola,
había pensando en para la función, darle 2 parámetros, la estructura nodo actual, (el registro de datos) la cual quiero introducir y que contiene los datos que quiero y luego el nodo padre que sería el nodo actual que indica mi posición.

Imagino que tu haces lo mismo con tu función, pero no estoy seguro de entender lo que haces:
1)hijos.add(nodo); no le faltaría indicar donde lo estás metiendo, a que hijo se lo asigna? en que nivel?

2)nodo.padre=this; a "this" le faltaría algo no?, estás igualando el padre al nodo?

Disculpa pero no lo entiendo.

Lo que si he modificado mi función de instertar ya que me he dado cuenta de que si el actual (padre) es nulo, no hay arbol, por o que solo apunto raiz a dicho nada, y ya no es necesario hacer el resto.

public void agregarHijo(nodoN nodo, nodoN padre)
{
if(padre==null) {setRaiz(nodo);}

else
{
hijos.add(nodo);
nodo.padre=padre;
}
}

Última edición por samurai_7; 22/11/2014 a las 11:26
  #9 (permalink)  
Antiguo 22/11/2014, 13:46
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Duda al definir un árbol n-ario

Buenas,

Estás mezclando programación estructurada con programación orientada a objetos.

Cita:
1)hijos.add(nodo); no le faltaría indicar donde lo estás metiendo, a que hijo se lo asigna? en que nivel?
No tengo que indicárselo. Estoy añadiendo un hijo al propio nodo.

Cita:
2)nodo.padre=this; a "this" le faltaría algo no?, estás igualando el padre al nodo?
Cuando a un nodo le añado un hijo, este nodo es padre de dicho hijo.

Te pongo la clase nodo tal y como la veo yo:

Código Java:
Ver original
  1. public class nodoN {
  2.  
  3.     private int valor;
  4.     private List <nodoN> hijos = new ArrayList <nodoN>();
  5.     private nodoN padre;
  6.  
  7.     public void nodoN(){
  8.         nodoN(0);
  9.     }
  10.  
  11.     public void nodoN(int v){
  12.         valor = v;
  13.     }
  14.  
  15.     public boolean isRaiz (){
  16.         return this.padre == null;
  17.     }
  18.  
  19.     public void agregarHijo(nodoN nodo) {
  20.         hijos.add(nodo);
  21.         nodo.padre=this;
  22.     }
  23.  
  24.     public List<NodoN> getHijos() {
  25.         return hijos;
  26.     }
  27.  
  28.    public int getValue() {
  29.        return value;
  30.    }
  31. }


Para utilizarlo y hacer una estructura como esta:
raiz
--Nodo1
----Nodo3
--Nodo2
---Nodo4
---Nodo5
-----Nodo6


Código Java:
Ver original
  1. //Definimos nodos
  2. NodoN raiz = new nodoN(0);
  3. NodoN nodo1 = new Nodo(1);
  4. NodoN nodo2 = new Nodo(2);
  5. NodoN nodo3 = new Nodo(3);
  6. NodoN nodo4 = new Nodo(4);
  7. NodoN nodo5 = new Nodo(5);
  8. NodoN nodo6 = new Nodo(6);
  9.  
  10. //Creamos la estructura de arbol
  11. raiz.agregarHijo(nodo1);
  12. raiz.agregarHijo(nodo2);
  13. nodo1.agregarHijo(nodo3);
  14. nodo2.agregarHijo(nodo4);
  15. nodo2.agregarHijo(nodo5);
  16. nodo5.agregarHijo(nodo6);

Para recorrer la estructura lo perfecto sería que implementases el patrón iterator en la clase nodo (http://www.tutorialspoint.com/design...or_pattern.htm).
Te pongo un ejemplo de recorrido recursivo del árbol pintando en consola:

Código Java:
Ver original
  1. public void recorrerArbol(nodoN nodoRaiz) {
  2.    if (nodoRaiz.getHijos() == null) {
  3.         System.out.println("Value=" + nodoRaiz.getValue();        
  4.    }
  5.    for (final nNodoN nodo : nodoRaiz.getHijos()) {
  6.        recorrerArbol(nodo);
  7.    }
  8. }
  9. [....]
  10. recorrerArbol(raiz);

Nota: lo he escrito directamente sobre el post, por lo que puede que me haya equivocado en alguna letra y/o símbolo en el código. Sin embargo espero que sirva al menos la idea.


Un saludo
__________________
If to err is human, then programmers are the most human of us

Última edición por Profesor_Falken; 23/11/2014 a las 13:58
  #10 (permalink)  
Antiguo 23/11/2014, 18:47
 
Fecha de Ingreso: mayo-2006
Mensajes: 70
Antigüedad: 17 años, 11 meses
Puntos: 0
Respuesta: Duda al definir un árbol n-ario

Buenas!, muchas gracias por tu ayuda y por todo el tiempo dedicado a escribir la respuesta.
Me has ayudado mucho, ya que me hiciste entenderlo todo, pero con tu definición tengo una duda para la búsqueda de elementos.
Al ser los hijos una lista de nodos, habría que aplicar recursividad en cada uno de ellos.


public nodoN buscarNodo(nodoN r, int v)
{
if(r==null)
{
System.out.println("no hay nodo para buscar");
return null;
}

else
{
if(r.valor==v)
{
return r;
}

else
{
for(int i=0;i<hijos.size();i++)
{
buscarNodo(r.hijos.get(i),v);
}
}
}
}
Código Java:
Ver original
  1. public nodoN buscarNodo(nodoN r, int v)
  2.     {
  3.         if(r==null)
  4.         {
  5.             System.out.println("no hay nodo para buscar");
  6.             return null;
  7.         }
  8.        
  9.         else
  10.         {
  11.             if(r.valor==v)
  12.             {
  13.                 return r;
  14.             }
  15.            
  16.             else
  17.             {
  18.                 for(int i=0;i<hijos.size();i++)
  19.                 {
  20.                 buscarNodo(r.hijos.get(i),v);
  21.                 }              
  22.             }
  23.         }
  24.     }

Aunque es bastante sencillo, no compila ya que me dice que el método debe volver un elemento tipo nodoN, cosa que ya hace, pero no se por qué me sigue dando ese error. He probado a meter el return en el primer if(para contemplar todos los casos) y sigue fallando.
¡¡gracias!!

Última edición por samurai_7; 23/11/2014 a las 22:58
  #11 (permalink)  
Antiguo 23/11/2014, 23:00
 
Fecha de Ingreso: mayo-2006
Mensajes: 70
Antigüedad: 17 años, 11 meses
Puntos: 0
Respuesta: Duda al definir un árbol n-ario

[QUOTE=samurai_7;4656919]Buenas!, muchas gracias por tu ayuda y por todo el tiempo dedicado a escribir la respuesta.
Me has ayudado mucho, ya que me hiciste entenderlo todo, pero con tu definición tengo una duda para la búsqueda de elementos.
Al ser los hijos una lista de nodos, habría que aplicar recursividad en cada uno de ellos.

}
Código Java:
Ver original
  1. public nodoN buscarNodo(nodoN r, int v)
  2.     {
  3.         if(r==null)
  4.         {
  5.             System.out.println("no hay nodo para buscar");
  6.             return null;
  7.         }
  8.        
  9.         else
  10.         {
  11.             if(r.valor==v)
  12.             {
  13.                 return r;
  14.             }
  15.            
  16.             else
  17.             {
  18.                 for(int i=0;i<hijos.size();i++)
  19.                 {
  20.                 buscarNodo(r.hijos.get(i),v);
  21.                 }              
  22.             }
  23.         }
  24.     }

Aunque es bastante sencillo, no compila ya que me dice que el método debe volver un elemento tipo nodoN, cosa que ya hace, pero no se por qué me sigue dando ese error hasta que meto el return debajo de la llamada a recursividad(en el segundo else), aunque no debería ya que el método de por si ya está devolviendo un tipo adecuado.
¡¡gracias!!
  #12 (permalink)  
Antiguo 24/11/2014, 01:43
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Duda al definir un árbol n-ario

Buenas,

Es compilador tiene razon al quejarse, ya que cuando haces la llamada recursiva no haces retorno.

En realidad hay dos errores en dicho for:
-No haces retorno de un nodo en la llamada recursiva
-Cuando recorres lo haces sobre los hijos de la instancia cuando en realidad deberias hacerlos sobre el nodo pasado por parametro.

for(int i=0;i<r.hijos.size();i++)
{
return buscarNodo(r.hijos.get(i),v);
}

Otra forma mas sencilla de hacer el bucle seria:

Código Java:
Ver original
  1. for(final nodoN nodoHijo : r.hijos) {
  2.     return buscarNodo(nodoHijo ,v);
  3. }

Por otro lado, este metodo de busqueda es stateless y no depende del estado de una instancia, por lo que lo mas adecuado es que lo hagas static.
En resumen, tu codigo quedaria mas o menos asi:


Código Java:
Ver original
  1. public static nodoN buscarNodo(nodoN r, int v)
  2.     {
  3.         if(r==null)
  4.         {
  5.             System.out.println("no hay nodo para buscar");
  6.             return null;
  7.         }
  8.        
  9.         else
  10.         {
  11.             if(r.valor==v)
  12.             {
  13.                 return r;
  14.             }
  15.            
  16.             else
  17.             {
  18.                 for(final nodoN nodoHijo : r.hijos) {
  19.                       return buscarNodo(nodoHijo ,v);
  20.                }          
  21.             }
  22.         }
  23.     }

Y cuando quieras llamarlo lo puedes hacer asi

Código Java:
Ver original
  1. nodoN nodoEncontado = nodoN.buscarNodo(raiz, 8);

Un saludo
__________________
If to err is human, then programmers are the most human of us
  #13 (permalink)  
Antiguo 24/11/2014, 12:31
 
Fecha de Ingreso: mayo-2006
Mensajes: 70
Antigüedad: 17 años, 11 meses
Puntos: 0
Respuesta: Duda al definir un árbol n-ario

Hola,
gracias de nuevo por tomarte tu tiempo :).

Muchas gracias por tu ayuda en la instancia de los hijos, se me pasó ese detalle de r., pero llevas tu razón. ;).

Pero no estoy de acuerdo contigo en eso de que debe retornar un valor siempre, ya que de los 3 posibles casos que tengo, en 2 de ellos (cuando r ==null y cuando encuentro en el valor que deseo) devuelvo un resultado tipo nodoN, es sólo en la última función que falta (en la de búsqueda de los hijos) cuando no devuelve, pero dicha función al resolverse por recursividad, devolverá al resolverse un valor de tipo nodoN, ya que en última instancia tirará por alguno de los 2 caminos por lo que si está devolviendo algo.

Quizás sea fallo de concepto en Java, creo que en c se hacia como digo, ya que al resolverse la recursividad dará el tipo dado.
De todas formas, como tampoco había muchas opciones, puse un return como bien indicas, quedando el cógido de la siguiente forma:

Código Java:
Ver original
  1. public nodoN buscarNodo(nodoN r, int v)  <--1
  2.     {
  3.         if(r==null)
  4.         {
  5.             System.out.println("no hay nodo para buscar");
  6.             return null;
  7.         }
  8.        
  9.         else
  10.         {
  11.             if(r.valor==v)
  12.             {
  13.                 return r;
  14.             }
  15.            
  16.             else
  17.             {
  18.                 for(int i=0;i<hijos.size();i++)  <--2
  19.                 {
  20.                 return buscarNodo(r.hijos.get(i),v);    
  21.                 }  
  22.             }
  23.         }
  24.     }

<--1, me indica el mismo fallo que entes, que no devuleve el tipo adecuado (nodoN).
<--2, indica en el i++, cógido muerto. Imagino que será ya que en la primera iteración revolverá el resultado, y ya saldrá del bucle, por lo que no se llega a ejecutar el primer i++. Pero si no es con un bucle, no se me ocurre como llamar a cada uno de los hijos.

Gracias!

Última edición por samurai_7; 24/11/2014 a las 18:29

Etiquetas: clase, definir, valor
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:28.