import java.util.*; public class myGraph { protected String[] Vertices; // 1-d array to store the vertices protected boolean[][] Edges; // 2-d boolean array to store adjacencies between vertices protected int[] dFTTree; // 1-d array to store parent info. in depth // first traversal tree protected int numVertices; protected int numEdges; // Default constructor. Sets aside enough capacity for one vertex public myGraph( ) { this(1); } // Constructor that sets aside as much capacity as specified by the user public myGraph(int capacity) { Vertices = new String[capacity]; Edges = new boolean[capacity][capacity]; for(int i = 0; i < capacity; i++) for(int j = 0; j < capacity; j++) Edges[i][j] = false; } public int numberOfVertices() { return numVertices; } public int numberOfEdges() { return numEdges; } // Finds the location at which a vertex is stored in Vertices. // Returns -1 if vertex not found protected int getIndex(String vertex) { for(int i = 0; i < numVertices; i++) if(vertex.equals(Vertices[i])) return i; return -1; } // Resizes the array of vertices. Can make it larger or smaller, depending // on what newSize is. protected String[] resize(String[] array, int newSize) { String[] temp = new String[newSize]; int smallerSize = newSize; if(array.length < smallerSize) smallerSize = array.length; for(int i = 0; i < smallerSize; i++) temp[i] = array[i]; return temp; } // Resizes the array of adjacencies. Can make it larger or smaller, depending // on what newSize is. protected boolean[][] resize(boolean[][] array, int newSize) { boolean[][] temp = new boolean[newSize][newSize]; int smallerSize = newSize; if(array.length < smallerSize) smallerSize = array.length; for(int i = 0; i < newSize; i++) for(int j = 0; j < newSize; j++) { if (i < smallerSize && j < smallerSize) temp[i][j] = array[i][j]; else temp[i][j] = false; } return temp; } // Adds a new vertex public void addVertex(String newVertex) { if(getIndex(newVertex) != -1) { System.out.print("addVertex: "); System.out.print(newVertex); System.out.println(" vertex already exists."); return; } // if array of vertices is full, we need to expand it and // also expand Edges if (Vertices.length == numVertices) { Vertices = resize(Vertices, 2*numVertices+1); Edges = resize(Edges, 2*numVertices+1); } Vertices[numVertices++] = newVertex; } // Adds a new edge public void addEdge(String vertex1, String vertex2) { int i = getIndex(vertex1); if(i == -1) { System.out.print("addEdge: "); System.out.print(vertex1); System.out.println(" does not exist."); return; } int j = getIndex(vertex2); if(j == -1) { System.out.print("addEdge: "); System.out.print(vertex2); System.out.println(" does not exist."); return; } Edges[i][j] = true; Edges[j][i] = true; numEdges++; } // delete the given vertex public void deleteVertex(String vertex) { int i = getIndex(vertex); if(i == -1) { System.out.print("deleteVertex: "); System.out.print(vertex); System.out.println(" does not exist."); return; } // Move the last vertex up to fill the hole made by vertex i Vertices[i] = Vertices[numVertices-1]; for(int j = 0; j < numVertices; j++) { // For every edge incident on vertex i, decrement numEdges if(Edges[i][j]) numEdges--; // Move the last row in the adj. matrix into the ith row Edges[i][j] = Edges[numVertices-1][j]; Edges[numVertices-1][j] = false; // Move the last column in the adj. matrix into the ith column Edges[j][i] = Edges[j][numVertices-1]; Edges[j][numVertices-1] = false; } numVertices--; } // deletes a given edge public void deleteEdge(String vertex1, String vertex2) { int i = getIndex(vertex1); if(i == -1) { System.out.print("deleteEdge: "); System.out.print(vertex1); System.out.println(" does not exist."); return; } int j = getIndex(vertex2); if(j == -1) { System.out.print("deleteEdge: "); System.out.print(vertex2); System.out.println(" does not exist."); return; } Edges[i][j] = false; Edges[j][i] = false; numEdges--; } // returns the names of all the neighbors of a given vertex in an array // of Strings public String[] getNeighbors(String vertex) { String[] neighbors = new String[numVertices]; int numNeighbors = 0; int source = getIndex(vertex); if(source == -1) { System.out.print("getNeighbors: "); System.out.print(vertex); System.out.println(" does not exist."); return new String[0]; } for(int j = 0; j < numVertices; j++) { if(Edges[source][j]) neighbors[numNeighbors++] = new String(Vertices[j]); } neighbors = resize(neighbors, numNeighbors); return neighbors; } // returns the degree of a vertex with given name public int degree(String vertex) { // Get the index of the vertex int i = getIndex(vertex); if(i == -1) { System.out.print("In degree: "); System.out.print(vertex); System.out.println(" does not exist."); return -1; } // Call the other degree function that returns the degree // of a vertex, given its index return degree(i); } // returns the degree of a vertex with given index protected int degree(int vertex) { int numNeighbors = 0; // Scan the row corresponding to vertex in the adjacency // matrix, counting the number of neighbors for(int j = 0; j < numVertices; j++) if(Edges[vertex][j]) numNeighbors++; return numNeighbors; } // returns the indices of all the neighbors of a given vertex public int[] getNeighbors(int vertex) { int numNeighbors = degree(vertex); int[] neighbors = new int[numNeighbors]; // Scan the row corresponding to vertex in the adjacency // matrix numNeighbors = 0; for(int j = 0; j < numVertices; j++) if(Edges[vertex][j]) neighbors[numNeighbors++] = j; return neighbors; } public void depthFirstTraversal(String source) { // Getting the index of the source vertex and // checking if the vertex really exists int sourceIndex = getIndex(source); if(sourceIndex == -1) { System.out.print("In depthFirstTraversal: vertex "); System.out.print(source); System.out.println(" is missing."); return; } // Defining and initializing the visited array boolean[] visited = new boolean[numVertices]; for(int j = 0; j < numVertices; j++) visited[j] = false; visited[sourceIndex] = true; // Defining and initializing the stack Stack s = new Stack(); s.push(new Integer(sourceIndex)); // Initializing the depth first traversal tree dFTTree = new int[numVertices]; for(int j = 0; j < numVertices; j++) dFTTree[j] = j; boolean more; do { // The traversal can go on while the stack // contains a vertex to process while(!s.empty()) { // Peek at the current vertex int currentVertex = (s.peek()).intValue(); System.out.println(Vertices[currentVertex]); // Get the indices of the neighbors of the current vertex int[] neighbors = getNeighbors(currentVertex); // Scan the neighbors of the current vertex, looking // for an unvisited neighbor int j = 0; boolean found = false; while (j < neighbors.length && !found) { // If an unvisited neighbor has been found, // then push it into the stack, mark it visited, // make the current vertex its parent, // and get out of the while-loop by setting found // to true if(!visited[neighbors[j]]) { s.push(new Integer(neighbors[j])); visited[neighbors[j]] = true; found = true; dFTTree[neighbors[j]] = currentVertex; } j++; // scan the next vertex } // If no unvisited vertices have been found, it is time // to backtrack if (!found) s.pop(); } // end of while-stack-not-empty loop // Determine if there are more unvisited vertices // by scanning the visited array and looking for the // first unvisited vertex more = false; int j = 0; while(j < numVertices && !more) { if(!visited[j]) more = true; j++; } } while(more); } // end of function } // end of class