init commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
public class App {
|
||||
public static void main(String[] args) {
|
||||
GUI.setup();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.text.Position;
|
||||
|
||||
import edu.princeton.cs.algs4.Edge;
|
||||
|
||||
public class DisplayPanel extends JPanel {
|
||||
|
||||
private static ST<Integer, Vertex> st;
|
||||
private int n;
|
||||
private static final int SIZE = 256;
|
||||
private int a = SIZE / 2;
|
||||
private int b = a;
|
||||
private int r = 4 * SIZE / 5;
|
||||
|
||||
public DisplayPanel() {
|
||||
super();
|
||||
setPreferredSize(new Dimension(300, 300));
|
||||
setSize(getPreferredSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
st = new ST<>();
|
||||
EdgeWeightedGraph G = GraphFunctions.getGraph();
|
||||
for(int v = 0; v < G.V(); v++)
|
||||
st.put(v, new Vertex(v));
|
||||
n = st.size();
|
||||
// draw the entire graph first
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(
|
||||
RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setColor(Color.WHITE);
|
||||
a = getWidth() / 2;
|
||||
b = getHeight() / 2;
|
||||
int m = Math.min(a, b);
|
||||
r = 4 * m / 5;
|
||||
int r2;
|
||||
if(n > 0) r2 = Math.abs(m - r) / n;
|
||||
else r2 = Math.abs(m - r) / 2;
|
||||
for (int i = 0; i < n; i++) {
|
||||
double t = 2 * Math.PI * i / n;
|
||||
int x = (int) Math.round(a + r * Math.cos(t));
|
||||
int y = (int) Math.round(b + r * Math.sin(t));
|
||||
g2d.fillOval(x - r2, y - r2, 2 * r2, 2 * r2);
|
||||
st.put(i, new Vertex(x, y));
|
||||
}
|
||||
|
||||
g.getFont().deriveFont(Font.BOLD);
|
||||
g2d.setColor(Color.ORANGE);
|
||||
if(n < 50) {
|
||||
for(int i = 0; i < n; i++) {
|
||||
int x = st.get(i).getX();
|
||||
int y = st.get(i).getY();
|
||||
|
||||
g.drawString(i + "", x - (2 * r2), y + (2 * r2));
|
||||
}
|
||||
}
|
||||
|
||||
drawLine(r2, g, g2d, G.edges(), Color.WHITE);
|
||||
drawLine(r2, g, g2d, GraphFunctions.getMST(), Color.GREEN);
|
||||
}
|
||||
|
||||
private void drawLine(int r2, Graphics g, Graphics2D g2d, Iterable<Edge> edges, Color color) {
|
||||
g2d.setColor(color);
|
||||
for (Edge e: edges) {
|
||||
int v = e.either();
|
||||
int w = e.other(v);
|
||||
|
||||
int vX = st.get(v).getX();
|
||||
int wX = st.get(w).getX();
|
||||
int vY = st.get(v).getY();
|
||||
int wY = st.get(w).getY();
|
||||
|
||||
g.drawLine(vX, vY, wX, wY);
|
||||
g.drawString(String.format("%.0f", e.weight()), ((vX + wX) / 2) + r2, ((vY + wY) / 2) + r2);
|
||||
}
|
||||
}
|
||||
|
||||
private class Vertex { // extends JComponent for @Override of paint()?
|
||||
private int x;
|
||||
private int y;
|
||||
private int v;
|
||||
|
||||
public Vertex(int v) {
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
public Vertex(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getV() {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
import edu.princeton.cs.algs4.In;
|
||||
import edu.princeton.cs.algs4.Bag;
|
||||
import edu.princeton.cs.algs4.StdOut;
|
||||
import edu.princeton.cs.algs4.Edge;
|
||||
import edu.princeton.cs.algs4.StdRandom;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* Modification of Sedgewick and Wayne's EdgeWeightedGraph, to allow a dynamic number of vertices based upon user input.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
* @author Josh Ashton
|
||||
*/
|
||||
public class EdgeWeightedGraph {
|
||||
private static final String NEWLINE = System.getProperty("line.separator");
|
||||
|
||||
private int V;
|
||||
private int E;
|
||||
private ArrayList<Bag<Edge>> adj;
|
||||
|
||||
/**
|
||||
* Create a new EdgeWeightedGraph with no vertices or edges. These may be added dynamically by the user.
|
||||
*/
|
||||
public EdgeWeightedGraph() {
|
||||
this.V = 0;
|
||||
this.E = 0;
|
||||
adj = new ArrayList<>();
|
||||
}
|
||||
|
||||
public EdgeWeightedGraph(In in) {
|
||||
if (in == null) throw new IllegalArgumentException("argument is null");
|
||||
|
||||
try {
|
||||
V = in.readInt();
|
||||
adj = new ArrayList<Bag<Edge>>();
|
||||
for (int v = 0; v < V; v++) {
|
||||
adj.add(new Bag<Edge>());
|
||||
}
|
||||
|
||||
int E = in.readInt();
|
||||
if (E < 0) throw new IllegalArgumentException("Number of edges must be non-negative");
|
||||
for (int i = 0; i < E; i++) {
|
||||
int v = in.readInt();
|
||||
int w = in.readInt();
|
||||
validateVertex(v);
|
||||
validateVertex(w);
|
||||
double weight = in.readDouble();
|
||||
Edge e = new Edge(v, w, weight);
|
||||
addEdge(e);
|
||||
}
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new IllegalArgumentException("invalid input format in EdgeWeightedGraph constructor", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes a random edge-weighted graph with {@code V} vertices and <em>E</em> edges.
|
||||
*
|
||||
* @param V the number of vertices
|
||||
* @param E the number of edges
|
||||
* @throws IllegalArgumentException if {@code V < 0}
|
||||
* @throws IllegalArgumentException if {@code E < 0}
|
||||
*/
|
||||
public EdgeWeightedGraph(int V, int E) {
|
||||
this.V = V;
|
||||
adj = new ArrayList<Bag<Edge>>();
|
||||
for (int v = 0; v < V; v++) {
|
||||
adj.add(new Bag<Edge>());
|
||||
}
|
||||
|
||||
if (E < 0) throw new IllegalArgumentException("Number of edges must be non-negative");
|
||||
for (int i = 0; i < E; i++) {
|
||||
int v = StdRandom.uniformInt(V);
|
||||
int w = StdRandom.uniformInt(V);
|
||||
int weight = StdRandom.uniformInt(0, 100);
|
||||
Edge e = new Edge(v, w, (double) weight);
|
||||
addEdge(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new vertex to the edge-weighted graph.
|
||||
*/
|
||||
public void addVertex() {
|
||||
Bag<Edge> b = new Bag<>();
|
||||
V++;
|
||||
adj.add(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the undirected edge {@code e} to this edge-weighted graph.
|
||||
*
|
||||
* @param e the edge
|
||||
* @throws IllegalArgumentException unless both endpoints are between {@code 0} and {@code V-1}
|
||||
*/
|
||||
public void addEdge(Edge e) {
|
||||
int v = e.either();
|
||||
int w = e.other(v);
|
||||
validateVertex(v);
|
||||
validateVertex(w);
|
||||
adj.get(v).add(e);
|
||||
adj.get(w).add(e);
|
||||
E++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of vertices in this edge-weighted graph.
|
||||
*
|
||||
* @return the number of vertices in this edge-weighted graph
|
||||
*/
|
||||
public int V() {
|
||||
return V;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of edges in this edge-weighted graph.
|
||||
*
|
||||
* @return the number of edges in this edge-weighted graph
|
||||
*/
|
||||
public int E() {
|
||||
return E;
|
||||
}
|
||||
|
||||
// throw an IllegalArgumentException unless {@code 0 <= v < V}
|
||||
private void validateVertex(int v) {
|
||||
if (v < 0 || v >= V)
|
||||
throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the edges incident on vertex {@code v}.
|
||||
*
|
||||
* @param v the vertex
|
||||
* @return the edges incident on vertex {@code v} as an Iterable
|
||||
* @throws IllegalArgumentException unless {@code 0 <= v < V}
|
||||
*/
|
||||
public Iterable<Edge> adj(int v) {
|
||||
validateVertex(v);
|
||||
return adj.get(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the degree of vertex {@code v}.
|
||||
*
|
||||
* @param v the vertex
|
||||
* @return the degree of vertex {@code v}
|
||||
* @throws IllegalArgumentException unless {@code 0 <= v < V}
|
||||
*/
|
||||
public int degree(int v) {
|
||||
validateVertex(v);
|
||||
return adj.get(v).size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all edges in this edge-weighted graph.
|
||||
* To iterate over the edges in this edge-weighted graph, use foreach notation:
|
||||
* {@code for (Edge e : G.edges())}.
|
||||
*
|
||||
* @return all edges in this edge-weighted graph, as an iterable
|
||||
*/
|
||||
public Iterable<Edge> edges() {
|
||||
Bag<Edge> list = new Bag<Edge>();
|
||||
for (int v = 0; v < V; v++) {
|
||||
int selfLoops = 0;
|
||||
for (Edge e : adj(v)) {
|
||||
if (e.other(v) > v) {
|
||||
list.add(e);
|
||||
}
|
||||
// add only one copy of each self loop (self loops will be consecutive)
|
||||
else if (e.other(v) == v) {
|
||||
if (selfLoops % 2 == 0) list.add(e);
|
||||
selfLoops++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the edge-weighted graph.
|
||||
* This method takes time proportional to <em>E</em> + <em>V</em>.
|
||||
*
|
||||
* @return the number of vertices <em>V</em>, followed by the number of edges <em>E</em>,
|
||||
* followed by the <em>V</em> adjacency lists of edges
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append("vertices: " + V + " || edges: " + E + NEWLINE);
|
||||
for (int v = 0; v < V; v++) {
|
||||
s.append("vertex " + v + " edges: ");
|
||||
for (Edge e : adj.get(v)) {
|
||||
s.append(e + " ");
|
||||
}
|
||||
s.append(NEWLINE);
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
import edu.princeton.cs.algs4.StdRandom;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.BevelBorder;
|
||||
|
||||
public class GUI {
|
||||
private final static Color bg = Color.DARK_GRAY;
|
||||
private final static Color fg = Color.WHITE;
|
||||
private static JFrame frame;
|
||||
private static JPanel contentPane;
|
||||
|
||||
public static void setup() {
|
||||
frame = new JFrame("Graph");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setPreferredSize(new Dimension(1000, 1000));
|
||||
frame.setSize(frame.getPreferredSize());
|
||||
frame.setResizable(false);
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error with cross platform look/feel in frameSetup().");
|
||||
}
|
||||
GraphFunctions.init();
|
||||
frame.add(createContentPane());
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private static JPanel createContentPane() {
|
||||
contentPane = new JPanel(new BorderLayout());
|
||||
contentPane.add(new DisplayPanel(), BorderLayout.CENTER);
|
||||
contentPane.add(createButtonPane(), BorderLayout.NORTH);
|
||||
contentPane.setForeground(fg);
|
||||
contentPane.setBackground(bg);
|
||||
|
||||
return contentPane;
|
||||
}
|
||||
|
||||
private static JPanel createButtonPane() {
|
||||
JPanel pane = new JPanel();
|
||||
pane.setForeground(fg);
|
||||
pane.setBackground(bg);
|
||||
pane.setAlignmentX(0.5f);
|
||||
pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
|
||||
pane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
|
||||
|
||||
pane.add(createAddVPanel());
|
||||
|
||||
JTextField vertex1 = new JTextField();
|
||||
JTextField vertex2 = new JTextField();
|
||||
JTextField eWeight = new JTextField();
|
||||
vertex1.setForeground(fg);
|
||||
vertex1.setBackground(bg);
|
||||
vertex2.setForeground(fg);
|
||||
vertex2.setBackground(bg);
|
||||
eWeight.setForeground(fg);
|
||||
eWeight.setBackground(bg);
|
||||
|
||||
pane.add(vertex1);
|
||||
pane.add(vertex2);
|
||||
pane.add(eWeight);
|
||||
|
||||
JButton b = new JButton("Add an edge");
|
||||
b.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if(vertex1.getText().equals("") || vertex2.getText().equals("") || eWeight.getText().equals("")) {
|
||||
int v = StdRandom.uniformInt(GraphFunctions.getGraph().V());
|
||||
int w = StdRandom.uniformInt(GraphFunctions.getGraph().V());
|
||||
double weight = StdRandom.uniformInt(0, 100);
|
||||
GraphFunctions.addEdge(v, w, weight);
|
||||
}
|
||||
else {
|
||||
GraphFunctions.addEdge(Integer.parseInt(vertex1.getText()),
|
||||
Integer.parseInt(vertex2.getText()),
|
||||
Double.parseDouble(eWeight.getText()));
|
||||
}
|
||||
contentPane.removeAll();
|
||||
frame.setContentPane(createContentPane());
|
||||
contentPane.repaint();
|
||||
contentPane.revalidate();
|
||||
}
|
||||
});
|
||||
b.setFocusPainted(false);
|
||||
b.setFocusable(false);
|
||||
b.setForeground(fg);
|
||||
b.setBackground(bg);
|
||||
pane.add(b);
|
||||
|
||||
JPanel p = new JPanel(new GridLayout(1, 2));
|
||||
JPanel subPanel = new JPanel(new GridLayout(2, 1));
|
||||
b = new JButton("Reset graph");
|
||||
b.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
GraphFunctions.reset();
|
||||
contentPane.removeAll();
|
||||
frame.setContentPane(createContentPane());
|
||||
contentPane.repaint();
|
||||
contentPane.revalidate();
|
||||
}
|
||||
});
|
||||
b.setFocusPainted(false);
|
||||
b.setFocusable(false);
|
||||
b.setForeground(fg);
|
||||
b.setBackground(bg);
|
||||
subPanel.add(b);
|
||||
|
||||
b = new JButton("Load graph");
|
||||
b.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
JFileChooser fc = new JFileChooser("~");
|
||||
int returnVal = fc.showOpenDialog(frame);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
GraphFunctions.loadGraph(fc.getSelectedFile());
|
||||
contentPane.removeAll();
|
||||
frame.setContentPane(createContentPane());
|
||||
contentPane.repaint();
|
||||
contentPane.revalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
b.setFocusPainted(false);
|
||||
b.setFocusable(false);
|
||||
b.setForeground(fg);
|
||||
b.setBackground(bg);
|
||||
subPanel.add(b);
|
||||
|
||||
p.add(subPanel);
|
||||
p.add(createRandomPanel());
|
||||
|
||||
contentPane.add(p, BorderLayout.SOUTH);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
private static JPanel createAddVPanel() {
|
||||
JPanel vertPnl = new JPanel(new GridLayout(1, 3));
|
||||
vertPnl.setForeground(fg);
|
||||
vertPnl.setBackground(bg);
|
||||
JLabel verticesLbl = new JLabel("Number of vertices to add: ");
|
||||
verticesLbl.setForeground(fg);
|
||||
verticesLbl.setBackground(bg);
|
||||
vertPnl.add(verticesLbl);
|
||||
JTextField addVertices = new JTextField();
|
||||
addVertices.setForeground(fg);
|
||||
addVertices.setBackground(bg);
|
||||
vertPnl.add(addVertices);
|
||||
JButton b = new JButton("Add vertices");
|
||||
b.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if(addVertices.getText().equals("")) GraphFunctions.addVertex();
|
||||
else {
|
||||
for(int i = 0; i < Integer.parseInt(addVertices.getText()); i++)
|
||||
GraphFunctions.addVertex();
|
||||
}
|
||||
contentPane.removeAll();
|
||||
frame.setContentPane(createContentPane());
|
||||
contentPane.repaint();
|
||||
contentPane.revalidate();
|
||||
}
|
||||
});
|
||||
b.setFocusPainted(false);
|
||||
b.setFocusable(false);
|
||||
b.setForeground(fg);
|
||||
b.setBackground(bg);
|
||||
vertPnl.add(b);
|
||||
return vertPnl;
|
||||
}
|
||||
|
||||
private static JPanel createRandomPanel() {
|
||||
JPanel randomPanel = new JPanel(new GridLayout(2, 1));
|
||||
randomPanel.setForeground(fg);
|
||||
randomPanel.setBackground(bg);
|
||||
JPanel subPanel = new JPanel(new GridLayout(2, 2));
|
||||
subPanel.setForeground(fg);
|
||||
subPanel.setBackground(bg);
|
||||
JLabel veLabel = new JLabel("Number of Vertices:");
|
||||
veLabel.setForeground(fg);
|
||||
JTextField vertexCount = new JTextField();
|
||||
vertexCount.setForeground(fg);
|
||||
vertexCount.setBackground(bg);
|
||||
JLabel edLabel = new JLabel("Number of edges:");
|
||||
edLabel.setForeground(fg);
|
||||
JTextField edgesCount = new JTextField();
|
||||
edgesCount.setForeground(fg);
|
||||
edgesCount.setBackground(bg);
|
||||
subPanel.add(veLabel);
|
||||
subPanel.add(vertexCount);
|
||||
subPanel.add(edLabel);
|
||||
subPanel.add(edgesCount);
|
||||
randomPanel.add(subPanel);
|
||||
JButton b = new JButton("Random graph");
|
||||
b.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if(vertexCount.getText().equals("") || edgesCount.getText().equals(""))GraphFunctions.random(10, 20);
|
||||
else GraphFunctions.random(Integer.parseInt(vertexCount.getText()), Integer.parseInt(edgesCount.getText()));
|
||||
contentPane.removeAll();
|
||||
frame.setContentPane(createContentPane());
|
||||
contentPane.repaint();
|
||||
contentPane.revalidate();
|
||||
}
|
||||
});
|
||||
b.setFocusPainted(false);
|
||||
b.setFocusable(false);
|
||||
b.setForeground(fg);
|
||||
b.setBackground(bg);
|
||||
randomPanel.add(b);
|
||||
|
||||
return randomPanel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import edu.princeton.cs.algs4.In;
|
||||
import edu.princeton.cs.algs4.KruskalMST;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Random;
|
||||
|
||||
import edu.princeton.cs.algs4.Edge;
|
||||
|
||||
/**
|
||||
* @author Josh Ashton
|
||||
*/
|
||||
public class GraphFunctions {
|
||||
|
||||
private static KruskalMST mst;
|
||||
private static EdgeWeightedGraph g = new EdgeWeightedGraph(); // TODO: Convert to a DirectedEdgeWeightedGraph at some point.
|
||||
|
||||
public static void init() {
|
||||
String fileName = "./resources/GraphInternet.txt";
|
||||
g = new EdgeWeightedGraph(new In(fileName));
|
||||
|
||||
edu.princeton.cs.algs4.EdgeWeightedGraph G = new edu.princeton.cs.algs4.EdgeWeightedGraph(g.V());
|
||||
for (Edge e : g.edges()) {
|
||||
G.addEdge(e);
|
||||
}
|
||||
mst = new KruskalMST(G);
|
||||
}
|
||||
|
||||
public static void random(int V, int E) {
|
||||
g = new EdgeWeightedGraph(V, E);
|
||||
edu.princeton.cs.algs4.EdgeWeightedGraph G = new edu.princeton.cs.algs4.EdgeWeightedGraph(g.V());
|
||||
for (Edge e : g.edges()) {
|
||||
G.addEdge(e);
|
||||
}
|
||||
mst = new KruskalMST(G);
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
g = new EdgeWeightedGraph();
|
||||
|
||||
edu.princeton.cs.algs4.EdgeWeightedGraph G = new edu.princeton.cs.algs4.EdgeWeightedGraph(g.V());
|
||||
for (Edge e : g.edges()) {
|
||||
G.addEdge(e);
|
||||
}
|
||||
mst = new KruskalMST(G);
|
||||
}
|
||||
|
||||
public static void loadGraph(File f) {
|
||||
g = new EdgeWeightedGraph(new In(f));
|
||||
|
||||
edu.princeton.cs.algs4.EdgeWeightedGraph G = new edu.princeton.cs.algs4.EdgeWeightedGraph(g.V());
|
||||
for (Edge e : g.edges()) {
|
||||
G.addEdge(e);
|
||||
}
|
||||
mst = new KruskalMST(G);
|
||||
}
|
||||
|
||||
public static void addVertex() {
|
||||
g.addVertex();
|
||||
}
|
||||
|
||||
public static void addEdge(int v, int w, double cost) {
|
||||
g.addEdge(new Edge(v, w, cost));
|
||||
}
|
||||
|
||||
public static Iterable<Edge> getMST() {
|
||||
edu.princeton.cs.algs4.EdgeWeightedGraph G = new edu.princeton.cs.algs4.EdgeWeightedGraph(g.V());
|
||||
for (Edge e : g.edges()) {
|
||||
G.addEdge(e);
|
||||
}
|
||||
return new KruskalMST(G).edges();
|
||||
}
|
||||
|
||||
public static EdgeWeightedGraph getGraph() {
|
||||
return g;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
import edu.princeton.cs.algs4.StdIn;
|
||||
import edu.princeton.cs.algs4.StdOut;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* For additional documentation, see
|
||||
* <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
|
||||
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
*
|
||||
* @param <Key> the generic type of keys in this symbol table
|
||||
* @param <Value> the generic type of values in this symbol table
|
||||
*/
|
||||
public class ST<Key extends Comparable<Key>, Value> implements Iterable<Key> {
|
||||
|
||||
private TreeMap<Key, Value> st;
|
||||
|
||||
/**
|
||||
* Initializes an empty symbol table.
|
||||
*/
|
||||
public ST() {
|
||||
st = new TreeMap<Key, Value>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key in this symbol table.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the value associated with the given key if the key is in this symbol table;
|
||||
* {@code null} if the key is not in this symbol table
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
*/
|
||||
public Value get(Key key) {
|
||||
if (key == null) throw new IllegalArgumentException("calls get() with null key");
|
||||
return st.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified key-value pair into the symbol table, overwriting the old
|
||||
* value with the new value if the symbol table already contains the specified key.
|
||||
* Deletes the specified key (and its associated value) from this symbol table
|
||||
* if the specified value is {@code null}.
|
||||
*
|
||||
* @param key the key
|
||||
* @param val the value
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
*/
|
||||
public void put(Key key, Value val) {
|
||||
if (key == null) throw new IllegalArgumentException("calls put() with null key");
|
||||
if (val == null) st.remove(key);
|
||||
else st.put(key, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified key and its associated value from this symbol table
|
||||
* (if the key is in this symbol table).
|
||||
* This is equivalent to {@code remove()}, but we plan to deprecate {@code delete()}.
|
||||
*
|
||||
* @param key the key
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
*/
|
||||
public void delete(Key key) {
|
||||
if (key == null) throw new IllegalArgumentException("calls delete() with null key");
|
||||
st.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified key and its associated value from this symbol table
|
||||
* (if the key is in this symbol table).
|
||||
* This is equivalent to {@code delete()}, but we plan to deprecate {@code delete()}.
|
||||
*
|
||||
* @param key the key
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
*/
|
||||
public void remove(Key key) {
|
||||
if (key == null) throw new IllegalArgumentException("calls remove() with null key");
|
||||
st.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this symbol table contain the given key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return {@code true} if this symbol table contains {@code key} and
|
||||
* {@code false} otherwise
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
*/
|
||||
public boolean contains(Key key) {
|
||||
if (key == null) throw new IllegalArgumentException("calls contains() with null key");
|
||||
return st.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of key-value pairs in this symbol table.
|
||||
*
|
||||
* @return the number of key-value pairs in this symbol table
|
||||
*/
|
||||
public int size() {
|
||||
return st.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this symbol table is empty.
|
||||
*
|
||||
* @return {@code true} if this symbol table is empty and {@code false} otherwise
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all keys in this symbol table in ascending order,
|
||||
* as an {@code Iterable}.
|
||||
* <p>
|
||||
* To iterate over all of the keys in the symbol table named {@code st},
|
||||
* use the foreach notation: {@code for (Key key : st.keys())}.
|
||||
*
|
||||
* @return all keys in this symbol table in ascending order
|
||||
*/
|
||||
public Iterable<Key> keys() {
|
||||
return st.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all keys in this symbol table in ascending order.
|
||||
* To iterate over all of the keys in a symbol table named {@code st}, use the
|
||||
* foreach notation: {@code for (Key key : st)}.
|
||||
* <p>
|
||||
* This method is provided for backward compatibility with the version from
|
||||
* <em>Introduction to Programming in Java: An Interdisciplinary Approach.</em>
|
||||
*
|
||||
* @return all keys in this symbol table in ascending order
|
||||
* @deprecated Replaced by {@link #keys()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Iterator<Key> iterator() {
|
||||
return st.keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest key in this symbol table.
|
||||
*
|
||||
* @return the smallest key in this symbol table
|
||||
* @throws NoSuchElementException if this symbol table is empty
|
||||
*/
|
||||
public Key min() {
|
||||
if (isEmpty()) throw new NoSuchElementException("calls min() with empty symbol table");
|
||||
return st.firstKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest key in this symbol table.
|
||||
*
|
||||
* @return the largest key in this symbol table
|
||||
* @throws NoSuchElementException if this symbol table is empty
|
||||
*/
|
||||
public Key max() {
|
||||
if (isEmpty()) throw new NoSuchElementException("calls max() with empty symbol table");
|
||||
return st.lastKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest key in this symbol table greater than or equal to {@code key}.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the smallest key in this symbol table greater than or equal to {@code key}
|
||||
* @throws NoSuchElementException if there is no such key
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
*/
|
||||
public Key ceiling(Key key) {
|
||||
if (key == null) throw new IllegalArgumentException("argument to ceiling() is null");
|
||||
Key k = st.ceilingKey(key);
|
||||
if (k == null) throw new NoSuchElementException("argument to ceiling() is too large");
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest key in this symbol table less than or equal to {@code key}.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the largest key in this symbol table less than or equal to {@code key}
|
||||
* @throws NoSuchElementException if there is no such key
|
||||
* @throws IllegalArgumentException if {@code key} is {@code null}
|
||||
*/
|
||||
public Key floor(Key key) {
|
||||
if (key == null) throw new IllegalArgumentException("argument to floor() is null");
|
||||
Key k = st.floorKey(key);
|
||||
if (k == null) throw new NoSuchElementException("argument to floor() is too small");
|
||||
return k;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ST<String, Integer> st = new ST<String, Integer>();
|
||||
for (int i = 0; !StdIn.isEmpty(); i++) {
|
||||
String key = StdIn.readString();
|
||||
st.put(key, i);
|
||||
}
|
||||
for (String s : st.keys())
|
||||
StdOut.println(s + " " + st.get(s));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
9
|
||||
21
|
||||
0 1 38
|
||||
0 3 48
|
||||
0 5 35
|
||||
0 8 40
|
||||
1 2 50
|
||||
1 3 36
|
||||
1 7 42
|
||||
1 8 48
|
||||
2 4 25
|
||||
2 5 40
|
||||
2 7 43
|
||||
2 8 30
|
||||
3 5 30
|
||||
3 6 65
|
||||
3 8 35
|
||||
4 5 20
|
||||
4 8 28
|
||||
5 8 27
|
||||
6 7 60
|
||||
6 8 55
|
||||
7 8 52
|
||||
Reference in New Issue
Block a user