import java.util.*; public class myGraph { protected String[] names; // 1-d array to store the vertices protected boolean[][] Edges; // 2-d array to store adjacencies between vertices, 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) { names = new String[capacity]; Edges = new boolean[capacity][]; // We use only the portion of the matrix below the main diagonal to store the edges for(int i = 0; i < Edges.length; i++) { Edges[i] = new boolean[i+1]; for(int j = 0; j < i; 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 public int getIndex(String vertex) { for(int i = 0; i < numVertices; i++) if(vertex.equals(names[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][]; int smallerSize = newSize; if(array.length < smallerSize) smallerSize = array.length; for(int i = 0; i < newSize; i++) { temp[i] = new boolean[i+1]; for(int j = 0; j < i+1; j++) { if (i < 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(" failed -- vertex already exists."); return; } // if array of vertices is full, we need to expand it and // also expand Edges if (names.length == numVertices) { names = resize(names, 2*numVertices+1); Edges = resize(Edges, 2*numVertices+1); } names[numVertices++] = newVertex; } // 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(" failed -- it does not exist."); return; } // Move the last vertex up to fill the hole made by vertex i names[i] = names[numVertices-1]; names[numVertices-1] = null; for(int j = 0; j < i; j++) { // For every edge incident on vertex i, decrement numEdges if(Edges[i][j]) numEdges--; // Move the first i elements of the last row in the adj. matrix into the ith row Edges[i][j] = Edges[numVertices-1][j]; } for(int j = i+1; j < numVertices-1; j++) { // For every edge incident on vertex i, decrement numEdges if(Edges[j][i]) numEdges--; // Move the remaining elements of the last row in the adj. matrix into the ith collumn Edges[j][i] = Edges[numVertices-1][j]; } // Delete the last row in the matrix for(int k = 0; k=j) Edges[i][j] = true; else Edges[j][i] = true; numEdges++; } // deletes a given edge public void deleteEdge(String vertex1, String vertex2) { int i = getIndex(vertex1); if(i == -1) { System.out.print("deleteEdge failed: "); System.out.print(vertex1); System.out.println(" does not exist."); return; } int j = getIndex(vertex2); if(j == -1) { System.out.print("deleteEdge failed: "); System.out.print(vertex2); System.out.println(" does not exist."); return; } if (i>=j) { if (Edges[i][j]) { Edges[i][j] = false; numEdges--; } } else { if (Edges[j][i]) { 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 failed: Vertex "); System.out.print(vertex); System.out.println(" does not exist."); return new String[0]; } for(int j = 0; j < numVertices; j++) { boolean edge = false; if (j <= source) edge = Edges[source][j]; else edge = Edges[j][source]; if(edge) neighbors[numNeighbors++] = new String(names[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 public int degree(int index) { int numNeighbors = 0; // Scan the row corresponding to vertex in the adjacency // matrix, counting the number of neighbors for (int j = 0; j <= index; j++) if(Edges[index][j]) numNeighbors++; for (int j = index+1; j < numVertices; j++) if(Edges[j][index]) numNeighbors++; return numNeighbors; } // returns the indices of all the neighbors of a given vertex with index public int[] getNeighbors(int index) { int numNeighbors = degree(index); int[] neighbors = new int[numNeighbors]; // Scan the row corresponding to vertex in the adjacency matrix numNeighbors = 0; for(int j = 0; j < numVertices; j++) { boolean edge = false; if (j <= index) edge = Edges[index][j]; else edge = Edges[j][index]; if(edge) neighbors[numNeighbors++] = j; } return neighbors; } public String[][] listTriangles() { // From a set of n elements, n(n-1)(n-2)/6 triples can be chosen. // So this is an upper bound on the number of triangles in the // graph. For large graphs this upper bound may be too large // and the Java Virtual Machine may run out of memory in trying // to allocate memory for the 2-d String array defined below. int upperBound = numVertices * (numVertices - 1) * (numVertices - 2)/6; String[][] triangles = new String[upperBound][3]; int counter = 0; // will be used as we generate triangles // Scan all vertices. Pick the first vertex of the triangle for(int i = 0; i < numVertices; i++) { int[] neighbors = getNeighbors(i); // Scan the list of neighbors of i to find pairs of // adjacent vertices j and k // We only care about triangles of the form i < j < k for(int ii = 0; ii < neighbors.length; ii++) for(int iii = 0; iii < neighbors.length; iii++) { int j = neighbors[ii]; int k = neighbors[iii]; if((i < j) && (j < k) && Edges[k][j]) { triangles[counter][0] = names[i]; triangles[counter][1] = names[j]; triangles[counter][2] = names[k]; counter++; } // end-if } // end-for-iii } // end-for-i // Resizing the triangles array to be of just the right size String[][] temp = new String[counter][3]; for(int i = 0; i < counter; i++) { temp[i][0] = triangles[i][0]; temp[i][1] = triangles[i][1]; temp[i][2] = triangles[i][2]; } triangles = temp; return triangles; } } // end of class