This commit is contained in:
SowinskiBraeden committed 2026-03-28 11:07:43 -07:00
1 parent 1cffd619c7
commit 3f46d6a0bb
2 files changed
+424

No files matched your search

+395
View File
@@ -0,0 +1,395 @@
package ca.bcit.comp3760.lab04;
import java.util.LinkedList;
import java.util.Queue;
public class Graph
{
private static final int NO_EDGE = 0;
private static final int EDGE = 1;
private final String[] vertices;
private final int[][] edges;
private final boolean directed;
private String lastDFSOrder;
private String lastDFSDeadEndOrder;
private String lastBFSOrder;
/**
* Constructs a graph with the given vertex labels and direction setting.
*
* @param vertexLabels array of vertex names in internal order
* @param isDirected true if the graph is directed, false otherwise
*/
public Graph(final String[] vertexLabels, final boolean isDirected)
{
final int n;
n = vertexLabels.length;
this.vertices = vertexLabels;
this.edges = new int[n][n];
this.directed = isDirected;
this.lastDFSOrder = null;
this.lastDFSDeadEndOrder = null;
this.lastBFSOrder = null;
}
/**
* Returns whether this graph is directed.
*
* @return true if directed, false otherwise
*/
public boolean isDirected()
{
return this.directed;
}
/**
* Adds an edge from one vertex to another.
* If the graph is undirected, the reverse edge is also added.
* If either vertex label does not exist, nothing happens.
*
* @param va starting vertex label
* @param vb ending vertex label
*/
public void addEdge(final String va, final String vb)
{
final int fromIndex;
final int toIndex;
fromIndex = findVertexIndex(va);
toIndex = findVertexIndex(vb);
if (fromIndex == -1 || toIndex == -1)
{
return;
}
this.edges[fromIndex][toIndex] = EDGE;
if (!this.directed)
{
this.edges[toIndex][fromIndex] = EDGE;
}
}
/**
* Returns the number of vertices in the graph.
*
* @return number of vertices
*/
public int size()
{
return this.vertices.length;
}
/**
* Returns the label of the vertex at the given internal index.
*
* @param v internal vertex index
* @return label of the vertex
*/
public String getLabel(final int v)
{
return this.vertices[v];
}
/**
* Returns a string representation of the graph adjacency matrix.
*
* @return adjacency matrix as a string
*/
@Override
public String toString()
{
final StringBuilder graph;
graph = new StringBuilder();
for (int i = 0; i < this.vertices.length; ++i)
{
graph.append(this.vertices[i]);
graph.append(": ");
for (int j = 0; j < this.vertices.length; ++j)
{
graph.append(this.edges[i][j]);
if (j < this.vertices.length - 1)
{
graph.append(" ");
}
}
if (i < this.vertices.length - 1)
{
graph.append("\n");
}
}
return graph.toString();
}
private int findVertexIndex(final String label)
{
for (int i = 0; i < this.vertices.length; ++i)
{
if (this.vertices[i].equals(label))
{
return i;
}
}
return -1;
}
private void appendVertex(final StringBuilder order, final String label)
{
if (order.length() > 0)
{
order.append(" ");
}
order.append(label);
}
private void DFS(final int idx,
final boolean[] visited,
final boolean quiet,
final StringBuilder visitOrder,
final StringBuilder deadEndOrder)
{
visited[idx] = true;
appendVertex(visitOrder, this.vertices[idx]);
if (!quiet)
{
System.out.printf("Visiting vertex %s%n", this.vertices[idx]);
}
for (int i = 0; i < this.edges[idx].length; ++i)
{
if (this.edges[idx][i] == EDGE && !visited[i])
{
DFS(i, visited, quiet, visitOrder, deadEndOrder);
}
}
appendVertex(deadEndOrder, this.vertices[idx]);
}
/**
* Runs depth first search using the default first-on-the-list rule.
* If the graph is disconnected, all vertices are still included.
*
* @param quiet true to suppress console output, false to print traversal
*/
public void runDFS(final boolean quiet)
{
final boolean[] visited;
final StringBuilder visitOrder;
final StringBuilder deadEndOrder;
visited = new boolean[this.vertices.length];
visitOrder = new StringBuilder();
deadEndOrder = new StringBuilder();
if (!quiet)
{
System.out.println("DFS order traversal of graph:");
}
for (int i = 0; i < this.vertices.length; ++i)
{
if (!visited[i])
{
DFS(i, visited, quiet, visitOrder, deadEndOrder);
}
}
this.lastDFSOrder = visitOrder.toString();
this.lastDFSDeadEndOrder = deadEndOrder.toString();
}
/**
* Runs depth first search starting at the given vertex.
* Only vertices reachable from the start vertex are included.
*
* @param v starting vertex label
* @param quiet true to suppress console output, false to print traversal
*/
public void runDFS(final String v, final boolean quiet)
{
final int startIndex;
final boolean[] visited;
final StringBuilder visitOrder;
final StringBuilder deadEndOrder;
startIndex = findVertexIndex(v);
if (startIndex == -1)
{
return;
}
visited = new boolean[this.vertices.length];
visitOrder = new StringBuilder();
deadEndOrder = new StringBuilder();
if (!quiet)
{
System.out.println("DFS order traversal of graph:");
}
DFS(startIndex, visited, quiet, visitOrder, deadEndOrder);
this.lastDFSOrder = visitOrder.toString();
this.lastDFSDeadEndOrder = deadEndOrder.toString();
}
private void BFS(final int startIndex,
final boolean[] visited,
final boolean quiet,
final StringBuilder bfsOrder)
{
final Queue<Integer> queue;
queue = new LinkedList<>();
visited[startIndex] = true;
queue.offer(startIndex);
while (!queue.isEmpty())
{
final int current;
current = queue.poll();
appendVertex(bfsOrder, this.vertices[current]);
if (!quiet)
{
System.out.printf("Visiting vertex %s%n", this.vertices[current]);
}
for (int next = 0; next < this.edges[current].length; ++next)
{
if (this.edges[current][next] == EDGE && !visited[next])
{
visited[next] = true;
queue.offer(next);
}
}
}
}
/**
* Runs breadth first search using the default first-on-the-list rule.
* If the graph is disconnected, all vertices are still included.
*
* @param quiet true to suppress console output, false to print traversal
*/
public void runBFS(final boolean quiet)
{
final boolean[] visited;
final StringBuilder bfsOrder;
visited = new boolean[this.vertices.length];
bfsOrder = new StringBuilder();
if (!quiet)
{
System.out.println("BFS order traversal of graph:");
}
for (int i = 0; i < this.vertices.length; ++i)
{
if (!visited[i])
{
BFS(i, visited, quiet, bfsOrder);
}
}
this.lastBFSOrder = bfsOrder.toString();
}
/**
* Runs breadth first search starting at the given vertex.
* Only vertices reachable from the start vertex are included.
*
* @param v starting vertex label
* @param quiet true to suppress console output, false to print traversal
*/
public void runBFS(final String v, final boolean quiet)
{
final int startIndex;
final boolean[] visited;
final StringBuilder bfsOrder;
startIndex = findVertexIndex(v);
if (startIndex == -1)
{
return;
}
visited = new boolean[this.vertices.length];
bfsOrder = new StringBuilder();
if (!quiet)
{
System.out.println("BFS order traversal of graph:");
}
BFS(startIndex, visited, quiet, bfsOrder);
this.lastBFSOrder = bfsOrder.toString();
}
/**
* Returns the DFS visit order from the most recently run DFS.
*
* @return DFS order string, or a message if DFS has not been run
*/
public String getLastDFSOrder()
{
if (this.lastDFSOrder == null)
{
return "No DFS has been run yet.";
}
return this.lastDFSOrder;
}
/**
* Returns the DFS dead-end order from the most recently run DFS.
*
* @return DFS dead-end order string, or a message if DFS has not been run
*/
public String getLastDFSDeadEndOrder()
{
if (this.lastDFSDeadEndOrder == null)
{
return "No DFS has been run yet.";
}
return this.lastDFSDeadEndOrder;
}
/**
* Returns the BFS visit order from the most recently run BFS.
*
* @return BFS order string, or a message if BFS has not been run
*/
public String getLastBFSOrder()
{
if (this.lastBFSOrder == null)
{
return "No BFS has been run yet.";
}
return this.lastBFSOrder;
}
}
@@ -0,0 +1,29 @@
package ca.bcit.comp3760.lab04;
public class GraphDriver
{
public static void main(final String[] args)
{
final Graph G;
G = new Graph(new String[]{"a", "b", "c", "d", "e", "f", "g", "h"}, false);
G.addEdge("a", "b");
G.addEdge("a", "e");
G.addEdge("a", "f");
G.addEdge("b", "f");
G.addEdge("b", "g");
G.addEdge("c", "d");
G.addEdge("c", "g");
G.addEdge("d", "h");
G.addEdge("e", "f");
G.addEdge("g", "h");
System.out.printf("%s\n\n", G.toString());
G.runDFS(false);
System.out.println("\n");
G.runBFS(false);
}
}