necesito ayuda para poder guardar, leer y ampliar un arbol de conocimiento con preguntas. Mi duda es en si como le hago para que se guarde y lo lea y este arbol de conocimiento se haga mas grande conforme valla preguntando
aqui se encuentra el codigo
/**
* NodoAB.java
* @author JuanCarlos
*
* Un nodoAB proporciona una unidad para un árbol binario. Cada nodo tiene una
* pieza de información (la cual es una referencia a un objeto) y dos ligas
* (las cuales son referencias a los correspondientes sub-árboles izquierdo y
* derecho). Si el nodo es una hoja entonces ambas ligas tendrán un valor null.
*
* @note
* Un árbol de nodos pueden ser de cualquier longitud, el único límite es
* la cantidad de memoria libre en el heap.
*/
import java.lang.*;
import java.util.*;
class NodoAB {
private Object dato;
private NodoAB hijoIzquierdo;
private NodoAB hijoDerecho;
/**
* Inicializar un nodo con un dato inicial especifico y ligas a los hijos.
* Notar que una referencia a un hijo puede ser null, lo cual indica que no
* hay hijo.
*
* @param datoInicial
* El dato inicial de este nuevo nodo.
*
* @param izquierdoInicial
* Referencia al hijo izquierdo de este nodo.
* @param derechoInicial
* Referencia al hijo derecho de este nodo.
*
* @postcondition
* Este nuevo nodo contiene el dato especificado y ligas a sus hijos
*/
public NodoAB(Object datoInicial,
NodoAB izquierdoInicial,
NodoAB derechoInicial) {
dato = datoInicial;
hijoIzquierdo = izquierdoInicial;
hijoDerecho = derechoInicial;
}// Constructor
/**
* Método de acceso para obtener el dato de un nodo.
*/
public Object consigueDato() {
return dato;
}// consigueDato
/**
* Método de acceso para obtener la referencia al hijo izquierdo de este
* nodo.
*/
public NodoAB consigueHijoIzquierdo() {
return hijoIzquierdo;
}// consigueHijoIzquierdo
/**
* Método de acceso para obtener la referencia al hijo derecho de este
* nodo.
*/
public NodoAB consigueHijoDerecho() {
return hijoDerecho;
}// consigueHijoDerecho
/**
* Método de modificación para cambiar el dato de este nodo.
*
* @param nuevoDato
* El nuevo dato que actualizara el valor presente en este nodo.
*
* @postcondition
* El valor del dato de este nodo se ha actualizado con nuevoDato.
*/
public void ponDato(Object nuevoDato) {
dato = nuevoDato;
}// ponDato
/**
* Método de modificación para cambiar la referencia al hijo izquierdo de
* este nodo.
*
* @param nuevoIzquierda
* La nueva referencia al hijo izquierdo del nodo.
*
* @postcondition
* El valor de la referencia al hijo izquierdo de este nodo ha cambiado
* por nuevoIzquierda.
*/
public void ponIzquierda(NodoAB nuevoIzquierda) {
hijoIzquierdo = nuevoIzquierda;
}// ponIzquierda
/**
* Método de modificación para cambiar la referencia al hijo derecho de este
* nodo.
*
* @param nuevoDerecha
* La nueva referencia al hijo derecho del nodo.
*
* @postcondition
* El valor de la referencia al hijo derecho de este nodo ha cambiado
* por nuevoDerecha.
*/
public void ponDerecha(NodoAB nuevoDerecha) {
hijoDerecho = nuevoDerecha;
}// ponDerecha
/**
* Método de acceso usado para determinar si un nodo es una hoja.
*
* @return
* true si este nodo es una hoja y false en cualquier otro caso.
*/
public boolean esHoja() {
return ((hijoIzquierdo == null) && (hijoDerecho == null));
}// esHoja
/**
* Método de acceso para obtener el dato del nodo de más a la izquierda del
* árbol debajo de este nodo.
*
* @return
* El dato del nodo de mayor profundidad que puede ser alcanzado a partir
* de este nodo siguiendo las ligas izquierdas.
*/
public Object consigueDatoDeMasALaIzquierda() {
if (hijoIzquierdo == null)
return dato;
else
return hijoIzquierdo.consigueDatoDeMasALaIzquierda();
}// consigueDatoDeMasALaIzquierda
/**
* Método de acceso para obtener el dato del nodo de más a la derecha del
* árbol debajo de este nodo.
*
* @return
* El dato del nodo de mayor profundidad que puede ser alcanzado a partir
* de este nodo siguiendo las ligas derechas.
*/
public Object consigueDatoDeMasALaDerecha() {
if (hijoDerecho == null)
return dato;
else
return hijoDerecho.consigueDatoDeMasALaDerecha();
}// consigueDatoDeMasALaDerecha
/**
* Elimina el nodo de más a la izquierda del árbol con este nodo como raiz.
*
* @postcondition
* Se ha eliminado el nodo de más a la izquierda comenzando en este nodo
* (es decir el nodo de mayor profundidad que puede alcanzarse siguiendo
* las ligas izquierdas)
* @return
* Una referencia a la raiz del nuevo árbol (más pequeño). El valor de
* regreso puede ser null si el árbol original tiene un sólo nodo.
*/
public NodoAB eliminaNodoDeMasALaIzquierda() {
if (hijoIzquierdo == null)
return hijoDerecho;
else {
hijoIzquierdo = hijoIzquierdo.eliminaNodoDeMasALaIzquierda();
return this;
}
}// eliminaNodoDeMasALaIzquierda
/**
* Elimina el nodo de más a la derecha del árbol con este nodo como raiz.
*
* @postcondition
* Se ha eliminado el nodo de más a la derecha comenzando en este nodo
* (es decir el nodo de mayor profundidad que puede alcanzarse siguiendo
* las ligas derechas)
* @return
* Una referencia a la raiz del nuevo árbol (más pequeño). El valor de
* regreso puede ser null si el árbol original tiene un sólo nodo.
*/
public NodoAB eliminaNodoDeMasALaDerecha() {
if (hijoDerecho == null)
return hijoIzquierdo;
else {
hijoDerecho = hijoDerecho.eliminaNodoDeMasALaDerecha();
return this;
}
}// eliminaNodoDeMasALaDerecha
/**
* Copia un árbol binario.
*
* @param fuente
* Una referencia al nodo raiz del árbol binario que será copiado (el cual
* puede ser un árbol vacío donde fuente es null).
* @return
* Una referencia a la raiz de la copia.
* @exception OutOfMemoryError
* Indica que hay memoria insuficiente para el nuevo árbol.
*/
public static NodoAB copiaDeArbol(NodoAB fuente) {
NodoAB copiaDeHijoIzquierdo,copiaDeHijoDerecho;
if (fuente == null)
return null;
else {
copiaDeHijoIzquierdo = copiaDeArbol(fuente.hijoIzquierdo);
copiaDeHijoDerecho = copiaDeArbol(fuente.hijoDerecho);
return new NodoAB(fuente.dato,copiaDeHijoIzquierdo,
copiaDeHijoDerecho);
}
}// copiaDeArbol
/**
* Usa un recorrido in-order para imprimir los datos de cada nodo en o debajo
* de este nodo del árbol binario.
*
* @postcondition
* Los datos de este nodo y todos sus descendientes han sido escritos por
* System.out.println
*/
public void impresionInOrder() {
if (hijoIzquierdo != null)
hijoIzquierdo.impresionInOrder();
System.out.println(dato);
if (hijoDerecho != null)
hijoDerecho.impresionInOrder();
}// impresionInOrder
/**
* Usa un recorrido pre-order para imprimir los datos de cada nodo en o
* debajo de este nodo del árbol binario.
*
* @postcondition
* Los datos de este nodo y todos sus descendientes han sido escritos por
* System.out.println
*/
public void impresionPreOrder() {
System.out.println(dato);
if (hijoIzquierdo != null)
hijoIzquierdo.impresionInOrder();
if (hijoDerecho != null)
hijoDerecho.impresionInOrder();
}// impresionPreOrder
/**
* Usa un recorrido post-order para imprimir los datos de cada nodo en o
* debajo de este nodo del árbol binario.
*
* @postcondition
* Los datos de este nodo y todos sus descendientes han sido escritos por
* System.out.println
*/
public void impresionPostOrder() {
if (hijoIzquierdo != null)
hijoIzquierdo.impresionInOrder();
if (hijoDerecho != null)
hijoDerecho.impresionInOrder();
System.out.println(dato);
}// impresionPostOrder
/**
* Usa un recorrido in-order para imprimir los datos de cada nodo en o debajo
* de este nodo del árbol binario (con identación para indicar la profundidad
* de cada nodo).
*
* @param profundidad
* La profundidad de este nodo (con 0 para la raiz, 1 para los hijos de la
* raiz, etc.)
* @precondition
* profundidad es la profundidad de este nodo.
* @postcondition
* Los datos de este nodo y todos sus descendientes han sido escritos por
* System.out.println usando un recorrido in-order. La identación de cada
* línea de datos es tres veces su profundidad en el árbol. Un guión se
* imprime donde un hijo no tiene un hermano.
*/
public void impresion(int profundidad) {
// Se imprime la identación y el dato del nodo actual
for (int i = 0; i < profundidad; i++)
System.out.print(" ");
System.out.println(dato);
// Imprime el sub-árbol izquierdo (o un guión si hay un hijo derecho y no
// un hijo izquierdo)
if (hijoIzquierdo != null)
hijoIzquierdo.impresion(profundidad + 1);
else if (hijoDerecho != null) {
for (int i = 0; i < (profundidad + 1); i++)
System.out.print(" ");
System.out.println("-");
}
// Imprime el sub-árbol derecho (o un guión si hay un hijo izquierdo y no
// un hijo derecho)
if (hijoDerecho != null)
hijoDerecho.impresion(profundidad + 1);
else if (hijoIzquierdo != null) {
for (int i = 0; i < (profundidad + 1); i++)
System.out.print(" ");
System.out.println("-");
}
}// impresion
/**
* Calcula el número de nodos en un árbol binario.
*
* @param raiz
* La referencia a la raiz de un árbol binario (la cual puede ser null
* para un árbol vacío).
*
* @return
* El número de nodos en el árbol con la raiz dada.
* @note
* Una respuesta falsa ocurre para árboles con más nodos que
* Integer.MAX_VALUE
*/
public static int tamañoDeArbol(NodoAB raiz) {
if (raiz == null)
return 0;
else
return (1 + tamañoDeArbol(raiz.hijoIzquierdo) +
tamañoDeArbol(raiz.hijoDerecho));
}// tamañoDeArbol
}// Clase NodoAB
//En esta parte se incluye el ejemplo del árbol binario taxonómico.
class ArbolBinarioTaxonomico {
public static void instrucciones() {
System.out.println ("Programa inteligente que trata de adivinar \n" +
"de que mascota se trata, dado una breve sesión \n" +
"interactiva de preguntas con respuestas [s/n].\n");
}// instrucciones
public static NodoAB arbolInicial() {
NodoAB arbol = new NodoAB("Eres un mamifero? [s/n]: ",null,null);
NodoAB subAIzq = new NodoAB("Eres mas grande que un gato? [s/n]: ",null,
null);
NodoAB subADer = new NodoAB("Vives bajo el agua? [s/n]: ",null,null);
NodoAB hojaIzqSubAIzq = new NodoAB("Canguro",null,null);
NodoAB hojaDerSubAIzq = new NodoAB("Raton",null,null);
NodoAB hojaIzqSubADer = new NodoAB("Trucha",null,null);
NodoAB hojaDerSubADer = new NodoAB("Cardenal",null,null);
arbol.ponIzquierda(subAIzq);
arbol.ponDerecha(subADer);
subAIzq.ponIzquierda(hojaIzqSubAIzq);
subAIzq.ponDerecha(hojaDerSubAIzq);
subADer.ponIzquierda(hojaIzqSubADer);
subADer.ponDerecha(hojaDerSubADer);
return arbol;
}// arbolInicial
public static boolean consulta(String enunciado) {
Scanner teclado = new Scanner(System.in);
System.out.print(enunciado);
String respuesta = teclado.nextLine();
if (respuesta.equalsIgnoreCase("s"))
return true;
else
return false;
}// consulta
public static void adivinanza(NodoAB actual) {
NodoAB refAux = actual;
while (refAux.esHoja() == false) {
if (consulta((String) refAux.consigueDato()))
refAux = refAux.consigueHijoIzquierdo();
else
refAux = refAux.consigueHijoDerecho();
}
System.out.println("Creo que eres un(a) " + refAux.consigueDato());
if (consulta("Estoy en lo correcto? [s/n]: "))
System.out.println ("Siempre lo supe...");
else
aprendizaje(refAux);
}// adivinanza
public static void aprendizaje(NodoAB actual) {
Scanner teclado = new Scanner(System.in);
System.out.print("Me rindo, Que eres?: ");
String nuevoAnimal = teclado.nextLine();
System.out.print ("Por favor captura una pregunta de respuesta [s/n]\n"
+ "que distinga un " + nuevoAnimal + " de un "
+ actual.consigueDato() + ": ");
String nuevaPregunta = teclado.nextLine();
NodoAB hoja = new NodoAB((String) actual.consigueDato(),null,null);
NodoAB hojaNueva = new NodoAB(nuevoAnimal,null,null);
actual.ponDato(nuevaPregunta);
System.out.println("Tu pregunta: " + nuevaPregunta);
if (consulta("Como " + nuevoAnimal + "... " + nuevaPregunta +
" [s/n] ")) {
actual.ponIzquierda(hojaNueva);
actual.ponDerecha(hoja);
}
else {
actual.ponIzquierda(hoja);
actual.ponDerecha(hojaNueva);
}
}// aprendizaje
public static void main(String[] args) {
instrucciones();
NodoAB raiz = arbolInicial();
do
adivinanza(raiz);
while (consulta("Seguimos jugando? [s/n]: "));
System.out.println ("Gracias por ensenarme dos que tres cosas...");
}// main
}// Clase ArbolBinarioTaxonomico




