Many changes.
This commit is contained in:
parent
391f1d549d
commit
61ce9e2a70
@ -8,7 +8,6 @@ public class Arbol {
|
||||
private ArbolNodo arbol;
|
||||
private int size;
|
||||
private int altura;
|
||||
private int ancho;
|
||||
private List<List<ArbolNodo>> niveles;
|
||||
|
||||
public enum PrimerLado {
|
||||
@ -19,14 +18,12 @@ public class Arbol {
|
||||
public Arbol() {
|
||||
this.arbol = null;
|
||||
this.altura = 0;
|
||||
this.ancho = 0;
|
||||
this.niveles = new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean insertar(int valor) {
|
||||
if (this.arbol == null) {
|
||||
arbol = new ArbolNodo(valor, null);
|
||||
setAncho(1);
|
||||
setAltura(1);
|
||||
return true;
|
||||
}
|
||||
@ -51,16 +48,13 @@ public class Arbol {
|
||||
nuevo.setPadre(padre);
|
||||
padre.setIzquerda(nuevo);
|
||||
size++;
|
||||
if (primerLado == PrimerLado.IZQUERDA) {
|
||||
setAncho(getAncho() + 1);
|
||||
}
|
||||
setAltura(getAlturaRecursivo(arbol));
|
||||
|
||||
niveles = new ArrayList<>();
|
||||
for (int i = 0; i < getAltura(); i++) {
|
||||
for (int i = 0; i <= getAltura(); i++) {
|
||||
niveles.add(new ArrayList<>());
|
||||
}
|
||||
getNivelesRecursivo(arbol);
|
||||
calcularNiveles(arbol, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -75,16 +69,13 @@ public class Arbol {
|
||||
nuevo.setPadre(padre);
|
||||
padre.setDerecha(nuevo);
|
||||
size++;
|
||||
if (primerLado == PrimerLado.DERECHA) {
|
||||
setAncho(getAncho() + 1);
|
||||
}
|
||||
setAltura(getAlturaRecursivo(arbol));
|
||||
|
||||
niveles = new ArrayList<>();
|
||||
for (int i = 0; i < getAltura(); i++) {
|
||||
for (int i = 0; i <= getAltura(); i++) {
|
||||
niveles.add(new ArrayList<>());
|
||||
}
|
||||
getNivelesRecursivo(arbol);
|
||||
calcularNiveles(arbol, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -113,15 +104,6 @@ public class Arbol {
|
||||
return niveles;
|
||||
}
|
||||
|
||||
public int getAncho() {
|
||||
return ancho;
|
||||
}
|
||||
|
||||
public void setAncho(int ancho) {
|
||||
//this.ancho = ancho;
|
||||
this.ancho = (int) Math.pow(2, altura - 1) - 1;
|
||||
}
|
||||
|
||||
public int getAlturaRecursivo(ArbolNodo nodo) {
|
||||
if (nodo == null) {
|
||||
return 0;
|
||||
@ -130,53 +112,32 @@ public class Arbol {
|
||||
int alturaIzquerda = getAlturaRecursivo(nodo.getIzquerda());
|
||||
int alturaDercha = getAlturaRecursivo(nodo.getDerecha());
|
||||
if (alturaIzquerda > alturaDercha) {
|
||||
nodo.setNivel(alturaIzquerda);
|
||||
return (alturaIzquerda + 1);
|
||||
}
|
||||
else {
|
||||
nodo.setNivel(alturaDercha);
|
||||
return (alturaDercha + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getNivelesRecursivo(ArbolNodo nodo) {
|
||||
if (nodo == null) {
|
||||
return 0;
|
||||
public void calcularNiveles(ArbolNodo nodo, int nivel) {
|
||||
try {
|
||||
if (nodo != null) {
|
||||
nodo.setNivel(nivel);
|
||||
niveles.get(nivel).add(nodo);
|
||||
nivel++;
|
||||
calcularNiveles(nodo.getIzquerda(), nivel);
|
||||
calcularNiveles(nodo.getDerecha(), nivel);
|
||||
}
|
||||
else if (nivel != getAltura()) {
|
||||
niveles.get(nivel).add(null);
|
||||
nivel++;
|
||||
calcularNiveles(null, nivel);
|
||||
calcularNiveles(null, nivel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
int alturaIzquerda = getNivelesRecursivo(nodo.getIzquerda());
|
||||
int alturaDerecha = getNivelesRecursivo(nodo.getDerecha());
|
||||
if (alturaIzquerda > alturaDerecha) {
|
||||
if (!niveles.get(niveles.size() - alturaIzquerda - 1).contains(nodo)) {
|
||||
niveles.get(niveles.size() - alturaIzquerda - 1).add(nodo);
|
||||
}
|
||||
if (nodo.getDerecha() == null) {
|
||||
niveles.get(niveles.size() - nodo.getNivel() - 1).add(null);
|
||||
}
|
||||
if (nodo.getIzquerda() == null) {
|
||||
niveles.get(niveles.size() - nodo.getNivel() - 1).add(null);
|
||||
}
|
||||
return (alturaIzquerda + 1);
|
||||
}
|
||||
else {
|
||||
if (!niveles.get(niveles.size() - alturaDerecha - 1).contains(nodo)) {
|
||||
niveles.get(niveles.size() - alturaDerecha - 1).add(nodo);
|
||||
}
|
||||
if (nodo.getDerecha() == null) {
|
||||
niveles.get(niveles.size() - nodo.getNivel() - 1).add(null);
|
||||
}
|
||||
if (nodo.getIzquerda() == null) {
|
||||
niveles.get(niveles.size() - nodo.getNivel() - 1).add(null);
|
||||
}
|
||||
return (alturaDerecha + 1);
|
||||
}
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Logs.log(Level.SEVERE, exception);
|
||||
return 0;
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Logs.log(Level.SEVERE, exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,6 @@ public class ArbolController implements Initializable {
|
||||
}
|
||||
catch (NumberFormatException exception) {
|
||||
// El error no es fatal, sigue
|
||||
Logs.log(Level.WARNING, "No es tipo int.");
|
||||
Main.mostrarError(resourceBundle.getString("arbolNoValor"), resourceBundle);
|
||||
}
|
||||
}
|
||||
@ -145,21 +144,31 @@ public class ArbolController implements Initializable {
|
||||
|
||||
List<List<ArbolNodo>> niveles = arbol.getNiveles();
|
||||
|
||||
Colores colores = new Colores();
|
||||
int k = niveles.get(niveles.size() - 1).size();
|
||||
for (int i = niveles.size() - 1; i >= 0 ; i--) {
|
||||
int l = k - niveles.get(i).size();
|
||||
if (i != niveles.size() - 1) {
|
||||
l--;
|
||||
int altura = arbol.getAltura() - 1;
|
||||
int ancho = (int) Math.pow(2, altura) + (int) ((Math.pow(2, altura)) - 1);
|
||||
System.out.println(ancho);
|
||||
|
||||
Text text;
|
||||
for (int i = 0; i < altura; i++) {
|
||||
contenidoArbol.addRow(i);
|
||||
for (int j = 0; j < ancho; j++) {
|
||||
contenidoArbol.addColumn(j);
|
||||
text = new Text();
|
||||
text.setText(" ");
|
||||
text.setId(j + "_" + i);
|
||||
contenidoArbol.add(text, j, i);
|
||||
}
|
||||
}
|
||||
|
||||
Colores colores = new Colores();
|
||||
for (int i = niveles.size() - 1; i >= 0 ; i--) {
|
||||
for (int j = 0; j < niveles.get(i).size(); j++) {
|
||||
contenidoArbol.add(Grafico.crearCirculo(colores, j + "_" + i), l, i);
|
||||
contenidoArbol.add(Grafico.crearCirculo(colores, j + "_" + i), j, i);
|
||||
colores.siguinteColor();
|
||||
if (niveles.get(i).get(j) != null) {
|
||||
Text text = (Text) scene.lookup("#texto_" + j + "_" + i);
|
||||
text = (Text) scene.lookup("#texto_" + j + "_" + i);
|
||||
text.setText(String.valueOf(niveles.get(i).get(j).getValor()));
|
||||
}
|
||||
l++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,6 @@ public class ArrayController implements Initializable {
|
||||
}
|
||||
catch (NumberFormatException exception) {
|
||||
// El error no es fatal, sigue
|
||||
Logs.log(Level.WARNING, "No es tipo int.");
|
||||
Main.mostrarError(resourceBundle.getString("arrayNoValor"), resourceBundle);
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,6 @@ public class ColaController implements Initializable {
|
||||
}
|
||||
catch (NumberFormatException exception) {
|
||||
// El error no es fatal, sigue
|
||||
Logs.log(Level.WARNING, "No es tipo int.");
|
||||
Main.mostrarError(resourceBundle.getString("colaNoValor"), resourceBundle);
|
||||
}
|
||||
}
|
||||
|
301
src/cl/cromer/estructuras/GrafoController.java
Normal file
301
src/cl/cromer/estructuras/GrafoController.java
Normal file
@ -0,0 +1,301 @@
|
||||
package cl.cromer.estructuras;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Esta clase es para controlar todos la interfaz de Arbol.
|
||||
*
|
||||
* @author Chris Cromer
|
||||
*/
|
||||
public class GrafoController implements Initializable {
|
||||
/**
|
||||
* La caja para el valor.
|
||||
*/
|
||||
@FXML
|
||||
private TextFieldLimited valorGrafo;
|
||||
|
||||
/**
|
||||
* La caja por nodo 1.
|
||||
*/
|
||||
@FXML
|
||||
private TextFieldLimited valorNodo1;
|
||||
|
||||
/**
|
||||
* La caja por nodo 2.
|
||||
*/
|
||||
@FXML
|
||||
private TextFieldLimited valorNodo2;
|
||||
|
||||
/**
|
||||
* Donde poner el contenido de array.
|
||||
*/
|
||||
@FXML
|
||||
private Canvas contenidoGrafo;
|
||||
|
||||
/**
|
||||
* Donde va el codigo a mostrar a la pantalla.
|
||||
*/
|
||||
@FXML
|
||||
private Text codigoGrafo;
|
||||
|
||||
/**
|
||||
* La escena donde está cosas graficas.
|
||||
*/
|
||||
private Scene scene;
|
||||
|
||||
/**
|
||||
* Donde está guardado los idiomas.
|
||||
*/
|
||||
private ResourceBundle resourceBundle;
|
||||
|
||||
/**
|
||||
* El arbol usado en la aplicación.
|
||||
*/
|
||||
private GrafoNoDirigido<Node> grafoNoDirigido;
|
||||
|
||||
/**
|
||||
* Grafico rectangulos.
|
||||
*/
|
||||
private Grafico grafico;
|
||||
|
||||
/**
|
||||
* Nodos.
|
||||
*/
|
||||
private Node[] nodes;
|
||||
|
||||
/**
|
||||
* Inicializar todos los datos y dibujar las graficas.
|
||||
*
|
||||
* @param location URL: El URL de fxml en uso.
|
||||
* @param resourceBundle ResourceBundle: Tiene datos de idioma.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resourceBundle) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
|
||||
grafoNoDirigido = null;
|
||||
scene = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insertar un valor al array y mostrar el codigo en la pantalla.
|
||||
*/
|
||||
@FXML
|
||||
protected void botonInsertar() {
|
||||
if (scene == null) {
|
||||
initializeGrafo();
|
||||
}
|
||||
|
||||
// Mostrar el codigo
|
||||
/*String codigoTexto = new Scanner(getClass().getResourceAsStream("/cl/cromer/estructuras/code/array" + tipo + "/insertar")).useDelimiter("\\Z").next();
|
||||
codigoArray.setText(codigoTexto);*/
|
||||
|
||||
if (valorGrafo.getText() != null && ! valorGrafo.getText().trim().equals("")) {
|
||||
try {
|
||||
int i;
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (nodes[i] == null) {
|
||||
nodes[i] = new Node(Integer.valueOf(valorGrafo.getText()));
|
||||
break;
|
||||
}
|
||||
else if (nodes[i].getValue() == Integer.valueOf(valorGrafo.getText())) {
|
||||
i = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 5) {
|
||||
// Maximo 5 nodos
|
||||
Main.mostrarError(resourceBundle.getString("grafoLleno"), resourceBundle);
|
||||
}
|
||||
else {
|
||||
boolean exito = grafoNoDirigido.addNode(nodes[i]);
|
||||
if (exito) {
|
||||
valorGrafo.setText("");
|
||||
generarGrafico();
|
||||
}
|
||||
else {
|
||||
Main.mostrarError(resourceBundle.getString("arbolValorExiste"), resourceBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException exception) {
|
||||
// El error no es fatal, sigue
|
||||
Main.mostrarError(resourceBundle.getString("arbolNoValor"), resourceBundle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Main.mostrarError(resourceBundle.getString("arbolNoValor"), resourceBundle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insertar un valor al array y mostrar el codigo en la pantalla.
|
||||
*/
|
||||
@FXML
|
||||
protected void botonInsertarEdge() {
|
||||
if (scene == null) {
|
||||
initializeGrafo();
|
||||
}
|
||||
|
||||
if (valorNodo1.getText() != null && ! valorNodo1.getText().trim().equals("") && valorNodo2.getText() != null && ! valorNodo2.getText().trim().equals("")) {
|
||||
|
||||
}
|
||||
else {
|
||||
// TODO: Error no nodos
|
||||
}
|
||||
|
||||
generarGrafico();
|
||||
}
|
||||
|
||||
/**
|
||||
* Crear un arbol nuevo.
|
||||
*/
|
||||
private void initializeGrafo() {
|
||||
scene = contenidoGrafo.getScene();
|
||||
grafico = new Grafico(scene);
|
||||
this.grafoNoDirigido = new GrafoNoDirigido<>();
|
||||
this.nodes = new Node[5];
|
||||
}
|
||||
|
||||
private void generarGrafico() {
|
||||
grafico.removerDestacar();
|
||||
|
||||
Colores colores = new Colores();
|
||||
|
||||
GraphicsContext graphicsContext = contenidoGrafo.getGraphicsContext2D();
|
||||
graphicsContext.clearRect(0, 0, contenidoGrafo.getWidth(), contenidoGrafo.getHeight());
|
||||
|
||||
if (nodes[0] != null) {
|
||||
graphicsContext.setFill(colores.getFondo());
|
||||
graphicsContext.setStroke(colores.getBorder());
|
||||
|
||||
graphicsContext.fillOval(10, 10, 40, 40);
|
||||
graphicsContext.strokeOval(10, 10, 40, 40);
|
||||
|
||||
graphicsContext.setFill(colores.getTexto());
|
||||
int x = textX(25, String.valueOf(nodes[0].getValue()));
|
||||
graphicsContext.fillText(String.valueOf(nodes[0].getValue()), x, 35);
|
||||
}
|
||||
colores.siguinteColor();
|
||||
|
||||
if (nodes[1] != null) {
|
||||
graphicsContext.setFill(colores.getFondo());
|
||||
graphicsContext.setStroke(colores.getBorder());
|
||||
|
||||
graphicsContext.fillOval(210, 10, 40, 40);
|
||||
graphicsContext.strokeOval(210, 10, 40, 40);
|
||||
|
||||
graphicsContext.setStroke(colores.getTexto());
|
||||
graphicsContext.strokeText(String.valueOf(nodes[1].getValue()), 225, 35);
|
||||
}
|
||||
colores.siguinteColor();
|
||||
|
||||
if (nodes[2] != null) {
|
||||
graphicsContext.setFill(colores.getFondo());
|
||||
graphicsContext.setStroke(colores.getBorder());
|
||||
|
||||
graphicsContext.fillOval(10, 210, 40, 40);
|
||||
graphicsContext.strokeOval(10, 210, 40, 40);
|
||||
|
||||
graphicsContext.setStroke(colores.getTexto());
|
||||
graphicsContext.strokeText(String.valueOf(nodes[2].getValue()), 25, 235);
|
||||
}
|
||||
colores.siguinteColor();
|
||||
|
||||
if (nodes[3] != null) {
|
||||
graphicsContext.setFill(colores.getFondo());
|
||||
graphicsContext.setStroke(colores.getBorder());
|
||||
|
||||
graphicsContext.fillOval(210, 210, 40, 40);
|
||||
graphicsContext.strokeOval(210, 210, 40, 40);
|
||||
|
||||
graphicsContext.setStroke(colores.getTexto());
|
||||
graphicsContext.strokeText(String.valueOf(nodes[3].getValue()), 225, 235);
|
||||
}
|
||||
colores.siguinteColor();
|
||||
|
||||
if (nodes[4] != null) {
|
||||
graphicsContext.setFill(colores.getFondo());
|
||||
graphicsContext.setStroke(colores.getBorder());
|
||||
|
||||
graphicsContext.fillOval(105, 410, 40, 40);
|
||||
graphicsContext.strokeOval(105, 410, 40, 40);
|
||||
|
||||
graphicsContext.setStroke(colores.getTexto());
|
||||
graphicsContext.strokeText(String.valueOf(nodes[4].getValue()), 120, 435);
|
||||
}
|
||||
|
||||
graphicsContext.setStroke(colores.getBorder());
|
||||
|
||||
// Line between 0 and 1.
|
||||
if (nodes[0] != null && nodes[1] != null && grafoNoDirigido.edgeExists(nodes[0], nodes[1])) {
|
||||
graphicsContext.strokeLine(50, 30, 210, 30);
|
||||
}
|
||||
// Line between 0 and 2.
|
||||
if (nodes[0] != null && nodes[2] != null && grafoNoDirigido.edgeExists(nodes[0], nodes[2])) {
|
||||
graphicsContext.strokeLine(30, 50, 30, 210);
|
||||
}
|
||||
// Line between 0 and 3.
|
||||
if (nodes[0] != null && nodes[3] != null && grafoNoDirigido.edgeExists(nodes[0], nodes[3])) {
|
||||
graphicsContext.strokeLine(45, 45, 215, 215);
|
||||
}
|
||||
// Line between 0 and 4.
|
||||
if (nodes[0] != null && nodes[1] != null && grafoNoDirigido.edgeExists(nodes[0], nodes[1])) {
|
||||
graphicsContext.strokeLine(38, 50, 125, 410);
|
||||
}
|
||||
// Line between 1 and 2.
|
||||
if (nodes[1] != null && nodes[2] != null && grafoNoDirigido.edgeExists(nodes[1], nodes[2])) {
|
||||
graphicsContext.strokeLine(45, 215, 215, 45);
|
||||
}
|
||||
// Line between 1 and 3.
|
||||
if (nodes[1] != null && nodes[3] != null && grafoNoDirigido.edgeExists(nodes[1], nodes[3])) {
|
||||
graphicsContext.strokeLine(230, 50, 230, 210);
|
||||
}
|
||||
// Line between 1 and 4.
|
||||
if (nodes[1] != null && nodes[4] != null && grafoNoDirigido.edgeExists(nodes[1], nodes[4])) {
|
||||
graphicsContext.strokeLine(221, 50, 125, 410);
|
||||
}
|
||||
// Line between 2 and 3
|
||||
if (nodes[2] != null && nodes[3] != null && grafoNoDirigido.edgeExists(nodes[2], nodes[3])) {
|
||||
graphicsContext.strokeLine(50, 230, 210, 230);
|
||||
}
|
||||
// Line between 2 and 4.
|
||||
if (nodes[2] != null && nodes[4] != null && grafoNoDirigido.edgeExists(nodes[2], nodes[4])) {
|
||||
graphicsContext.strokeLine(38, 250, 125, 410);
|
||||
}
|
||||
// Line between 3 and 4.
|
||||
if (nodes[3] != null && nodes[4] != null && grafoNoDirigido.edgeExists(nodes[3], nodes[4])) {
|
||||
graphicsContext.strokeLine(221, 250, 125, 410);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcular la posición del texto basado en la cantidad de caracters.
|
||||
*
|
||||
* @param x int: La posición donde desea el texto.
|
||||
* @param texto String: El texto a posicionar.
|
||||
*
|
||||
* @return int: La posición nueva.
|
||||
*/
|
||||
private int textX(int x, String texto) {
|
||||
if (texto.length() == 1) {
|
||||
return x;
|
||||
}
|
||||
else if (texto.length() == 2) {
|
||||
return x - 3;
|
||||
}
|
||||
else {
|
||||
return x - 7;
|
||||
}
|
||||
}
|
||||
}
|
1016
src/cl/cromer/estructuras/GrafoDirigido.java
Normal file
1016
src/cl/cromer/estructuras/GrafoDirigido.java
Normal file
File diff suppressed because it is too large
Load Diff
187
src/cl/cromer/estructuras/GrafoNoDirigido.java
Normal file
187
src/cl/cromer/estructuras/GrafoNoDirigido.java
Normal file
@ -0,0 +1,187 @@
|
||||
package cl.cromer.estructuras;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/*****************************************************************************
|
||||
* File: UndirectedGraph.java
|
||||
* Author: Keith Schwarz (htiek@cs.stanford.edu)
|
||||
*
|
||||
* A class representing an undirected graph where each edge has an associated
|
||||
* real-valued length. Internally, the class is represented by an adjacency
|
||||
* list where each edges appears twice - once in the forward direction and
|
||||
* once in the reverse. In fact, this implementation was formed by taking
|
||||
* a standard adjacency list and then duplicating the logic to ensure each
|
||||
* edge appears twice.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
public final class GrafoNoDirigido<T> implements Iterable<T> {
|
||||
/* A map from nodes in the graph to sets of outgoing edges. Each
|
||||
* set of edges is represented by a map from edges to doubles.
|
||||
*/
|
||||
private final Map<T, Set<T>> mGraph = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Adds a new node to the graph. If the node already exists, this
|
||||
* function is a no-op.
|
||||
*
|
||||
* @param node The node to add.
|
||||
* @return Whether or not the node was added.
|
||||
*/
|
||||
public boolean addNode(T node) {
|
||||
/* If the node already exists, don't do anything. */
|
||||
if (mGraph.containsKey(node))
|
||||
return false;
|
||||
|
||||
/* Otherwise, add the node with an empty set of outgoing edges. */
|
||||
mGraph.put(node, new HashSet<>());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node, returns whether that node exists in the graph.
|
||||
*
|
||||
* @param node The node in question.
|
||||
* @return Whether that node eixsts in the graph.
|
||||
*/
|
||||
public boolean nodeExists(T node) {
|
||||
return mGraph.containsKey(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two nodes, adds an arc of that length between those nodes. If
|
||||
* either endpoint does not exist in the graph, throws a
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* @param one The first node.
|
||||
* @param two The second node.
|
||||
* @throws NoSuchElementException If either the start or destination nodes
|
||||
* do not exist.
|
||||
*/
|
||||
public void addEdge(T one, T two) {
|
||||
/* Confirm both endpoints exist. */
|
||||
if (!mGraph.containsKey(one) || !mGraph.containsKey(two))
|
||||
throw new NoSuchElementException("Both nodes must be in the graph.");
|
||||
|
||||
/* Add the edge in both directions. */
|
||||
mGraph.get(one).add(two);
|
||||
mGraph.get(two).add(one);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the edge between the indicated endpoints from the graph. If the
|
||||
* edge does not exist, this operation is a no-op. If either endpoint does
|
||||
* not exist, this throws a NoSuchElementException.
|
||||
*
|
||||
* @param one The start node.
|
||||
* @param two The destination node.
|
||||
* @throws NoSuchElementException If either node is not in the graph.
|
||||
*/
|
||||
public void removeEdge(T one, T two) {
|
||||
/* Confirm both endpoints exist. */
|
||||
if (!mGraph.containsKey(one) || !mGraph.containsKey(two))
|
||||
throw new NoSuchElementException("Both nodes must be in the graph.");
|
||||
|
||||
/* Remove the edges from both adjacency lists. */
|
||||
mGraph.get(one).remove(two);
|
||||
mGraph.get(two).remove(one);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two endpoints, returns whether an edge exists between them. If
|
||||
* either endpoint does not exist in the graph, throws a
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* @param one The first endpoint.
|
||||
* @param two The second endpoint.
|
||||
* @return Whether an edge exists between the endpoints.
|
||||
* @throws NoSuchElementException If the endpoints are not nodes in the
|
||||
* graph.
|
||||
*/
|
||||
public boolean edgeExists(T one, T two) {
|
||||
/* Confirm both endpoints exist. */
|
||||
if (!mGraph.containsKey(one) || !mGraph.containsKey(two))
|
||||
throw new NoSuchElementException("Both nodes must be in the graph.");
|
||||
|
||||
/* Graph is symmetric, so we can just check either endpoint. */
|
||||
return mGraph.get(one).contains(two);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node in the graph, returns an immutable view of the edges
|
||||
* leaving that node.
|
||||
*
|
||||
* @param node The node whose edges should be queried.
|
||||
* @return An immutable view of the edges leaving that node.
|
||||
* @throws NoSuchElementException If the node does not exist.
|
||||
*/
|
||||
public Set<T> edgesFrom(T node) {
|
||||
/* Check that the node exists. */
|
||||
Set<T> arcs = mGraph.get(node);
|
||||
if (arcs == null)
|
||||
throw new NoSuchElementException("Source node does not exist.");
|
||||
|
||||
return Collections.unmodifiableSet(arcs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a given node is contained in the graph.
|
||||
*
|
||||
* @param node The node to test for inclusion.
|
||||
* @return Whether that node is contained in the graph.
|
||||
*/
|
||||
public boolean containsNode(T node) {
|
||||
return mGraph.containsKey(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator that can traverse the nodes in the graph.
|
||||
*
|
||||
* @return An iterator that traverses the nodes in the graph.
|
||||
*/
|
||||
public Iterator<T> iterator() {
|
||||
return mGraph.keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of nodes in the graph.
|
||||
*
|
||||
* @return The number of nodes in the graph.
|
||||
*/
|
||||
public int size() {
|
||||
return mGraph.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the graph is empty.
|
||||
*
|
||||
* @return Whether the graph is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return mGraph.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable representation of the graph.
|
||||
*
|
||||
* @return A human-readable representation of the graph.
|
||||
*/
|
||||
public String toString() {
|
||||
return mGraph.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class Node {
|
||||
private int value;
|
||||
|
||||
public Node(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -265,7 +265,6 @@ public class ListaEnlazdaController implements Initializable {
|
||||
}
|
||||
catch (NumberFormatException exception) {
|
||||
// El error no es fatal, sigue
|
||||
Logs.log(Level.WARNING, "No es tipo int.");
|
||||
Main.mostrarError(resourceBundle.getString("listaNoValor"), resourceBundle);
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,22 @@ public class Logs {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Agregar un log al logger con un mensaje.
|
||||
*
|
||||
* @param mensaje String: El mensaje de lo que pasó.
|
||||
*/
|
||||
static public void log(String mensaje) {
|
||||
if (DEBUG) {
|
||||
if (DEBUG_TIPO == DEBUG_TIPOS.ARCHIVO) {
|
||||
Logger.getLogger(LOGNAME).log(Level.INFO, mensaje);
|
||||
}
|
||||
else {
|
||||
System.out.println(mensaje + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Agregar un log al logger con un mensaje.
|
||||
*
|
||||
|
@ -114,6 +114,7 @@ public class Main extends Application {
|
||||
dialog.setContentText(mensaje);
|
||||
dialog.getDialogPane().getButtonTypes().add(botonCerrar);
|
||||
dialog.getDialogPane().getScene().getWindow().sizeToScene();
|
||||
dialog.getDialogPane().setPrefWidth(mensaje.length() * 8);
|
||||
Main.setIcon(dialog, Main.class);
|
||||
dialog.show();
|
||||
}
|
||||
|
@ -218,13 +218,25 @@ public class MenuController extends VBox implements Initializable {
|
||||
protected void menuArbolGeneral() {
|
||||
Arbol.Tipos arbolTipos = new Arbol.Tipos(Arbol.Tipos.GENERAL);
|
||||
loadStage(
|
||||
resourceBundle.getString("tituloCola"),
|
||||
resourceBundle.getString("tituloArbolGeneral"),
|
||||
"/cl/cromer/estructuras/fxml/arbol.fxml",
|
||||
"/cl/cromer/estructuras/css/main.css",
|
||||
arbolTipos
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Click en Grafo No Dirigidos.
|
||||
*/
|
||||
@FXML
|
||||
protected void menuGrafoNoDirigidos() {
|
||||
loadStage(
|
||||
resourceBundle.getString("tituloGrafoNoDirigido"),
|
||||
"/cl/cromer/estructuras/fxml/grafo.fxml",
|
||||
"/cl/cromer/estructuras/css/main.css"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Click en Hash Table.
|
||||
*/
|
||||
@ -250,6 +262,8 @@ public class MenuController extends VBox implements Initializable {
|
||||
dialog.getDialogPane().getButtonTypes().add(botonCancelar);
|
||||
dialog.getDialogPane().getButtonTypes().add(botonCambiar);
|
||||
dialog.getDialogPane().getScene().getWindow().sizeToScene();
|
||||
dialog.getDialogPane().setPrefHeight(125);
|
||||
dialog.getDialogPane().setPrefWidth(400);
|
||||
Main.setIcon(dialog, getClass());
|
||||
|
||||
Optional<ButtonType> result = dialog.showAndWait();
|
||||
@ -275,6 +289,8 @@ public class MenuController extends VBox implements Initializable {
|
||||
dialog.getDialogPane().getButtonTypes().add(botonCancelar);
|
||||
dialog.getDialogPane().getButtonTypes().add(botonCambiar);
|
||||
dialog.getDialogPane().getScene().getWindow().sizeToScene();
|
||||
dialog.getDialogPane().setPrefHeight(125);
|
||||
dialog.getDialogPane().setPrefWidth(400);
|
||||
Main.setIcon(dialog, getClass());
|
||||
|
||||
Optional<ButtonType> result = dialog.showAndWait();
|
||||
|
@ -131,7 +131,6 @@ public class PilaController implements Initializable {
|
||||
}
|
||||
catch (NumberFormatException exception) {
|
||||
// El error no es fatal, sigue
|
||||
Logs.log(Level.WARNING, "No es tipo int.");
|
||||
Main.mostrarError(resourceBundle.getString("pilaNoValor"), resourceBundle);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ tituloMerge=Merge
|
||||
tituloListaEnlazadaSimple=Simple Linked List
|
||||
tituloListaEnlazadaCircular=Circular Linked List
|
||||
tituloListaEnlazadaDoble=Double Linked List
|
||||
tituloArbolGeneral=General Tree
|
||||
tituloGrafoDirigido=Grafo Dirigido
|
||||
tituloGrafoNoDirigido=Grafo No Dirigido
|
||||
tituloTablaHash=Hash Table
|
||||
|
||||
estructuras=Structures
|
||||
@ -89,6 +92,14 @@ colaNoValor=Please input a numeric value.
|
||||
arbolValorExiste=Value already exists.
|
||||
arbolNoEsta=Value does not exist.
|
||||
arbolNoValor=Please input a numeric value.
|
||||
|
||||
grafoNodos=Nodos:
|
||||
grafoEdges=Edges:
|
||||
grafoLleno=Node not inserted because of a maxium of 5 nodes in this implementation.
|
||||
grafoNodoExiste=Node alredy exists.
|
||||
grafoNoEsta=Node does not exist.
|
||||
grafoNoNodo=Please input a numeric node number.
|
||||
|
||||
tablaHashLleno=Key not inserted because the hash table is full.
|
||||
tablaHashLlaveExiste=Key already exists.
|
||||
tablaHashNoEsta=Key does not exist.
|
||||
|
@ -12,6 +12,9 @@ tituloMerge=Merge
|
||||
tituloListaEnlazadaSimple=Lista Enlazada Simple
|
||||
tituloListaEnlazadaCircular=Lista Enlazada Circular
|
||||
tituloListaEnlazadaDoble=Lista Enlazada Doble
|
||||
tituloArbolGeneral=Arbol General
|
||||
tituloGrafoDirigido=Grafo Dirigido
|
||||
tituloGrafoNoDirigido=Grafo No Dirigido
|
||||
tituloTablaHash=Tabla Hash
|
||||
estructuras=Estructuras
|
||||
array=Array
|
||||
@ -88,6 +91,14 @@ colaNoValor=Ingresar un valor num\u00E9rico por favor.
|
||||
arbolValorExiste=El valor ya existe.
|
||||
arbolNoEsta=El valor no existe.
|
||||
arbolNoValor=Ingresar un valor num\u00E9rico por favor.
|
||||
|
||||
grafoNodos=Nodos:
|
||||
grafoEdges=Edges:
|
||||
grafoLleno=El nodo no fue insertado porque esta implementaci\u00F3n tiene un maxiumo de 5 nodos.
|
||||
grafoNodoExiste=El nodo ya existe.
|
||||
grafoNoEsta=El nodo no existe.
|
||||
grafoNoNodo=Ingresar una llave y un valor num\u00E9rico por favor.
|
||||
|
||||
tablaHashLleno=La llave no fue insertado porque la tabla hash est\u00E1 lleno.
|
||||
tablaHashLlaveExiste=La llave ya existe.
|
||||
tablaHashNoEsta=La llave no existe.
|
||||
|
38
src/cl/cromer/estructuras/fxml/grafo.fxml
Normal file
38
src/cl/cromer/estructuras/fxml/grafo.fxml
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
|
||||
<?import cl.cromer.estructuras.TextFieldLimited?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<?import javafx.scene.canvas.Canvas?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml/1" prefHeight="768.0" prefWidth="1024.0" spacing="10"
|
||||
xmlns="http://javafx.com/javafx/8.0.92" fx:controller="cl.cromer.estructuras.GrafoController">
|
||||
<fx:include source="menu.fxml"/>
|
||||
<ScrollPane fitToHeight="true" fitToWidth="true" VBox.vgrow="ALWAYS">
|
||||
<HBox alignment="TOP_CENTER" VBox.vgrow="ALWAYS" spacing="50">
|
||||
<VBox spacing="10">
|
||||
<HBox alignment="CENTER" spacing="10">
|
||||
<!--<Button text="%llenar" onAction="#botonLlenar"/>-->
|
||||
<!--<Button text="%vaciar" onAction="#botonVaciar"/>-->
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" spacing="10">
|
||||
<Button text="%insertar" onAction="#botonInsertar"/>
|
||||
<!--<Button text="%pop" onAction="#botonPop"/>-->
|
||||
<!--<Button text="%peek" onAction="#botonPeek"/>-->
|
||||
<TextFieldLimited fx:id="valorGrafo" maxLength="3" prefWidth="50"/>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" spacing="10">
|
||||
<Text text="%grafoEdges"/>
|
||||
<Button text="%insertar" onAction="#botonInsertarEdge"/>
|
||||
<TextFieldLimited fx:id="valorNodo1" maxLength="3" prefWidth="50"/>
|
||||
<TextFieldLimited fx:id="valorNodo2" maxLength="3" prefWidth="50"/>
|
||||
</HBox>
|
||||
<Canvas fx:id="contenidoGrafo" width="300" height="500"/>
|
||||
</VBox>
|
||||
<StackPane alignment="TOP_LEFT" minWidth="450">
|
||||
<Text fx:id="codigoGrafo"/>
|
||||
</StackPane>
|
||||
</HBox>
|
||||
</ScrollPane>
|
||||
</VBox>
|
@ -33,7 +33,7 @@
|
||||
</Menu>
|
||||
<Menu text="%grafos">
|
||||
<MenuItem text="%dirigidos"/>
|
||||
<MenuItem text="%noDirigidos"/>
|
||||
<MenuItem text="%noDirigidos" onAction="#menuGrafoNoDirigidos"/>
|
||||
</Menu>
|
||||
<MenuItem text="%tablaHash" onAction="#menuHashTable"/>
|
||||
</Menu>
|
||||
|
Loading…
Reference in New Issue
Block a user