All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.umd.cs.findbugs.graph.AbstractGraph Maven / Gradle / Ivy

The newest version!
/*
 * Generic graph library
 * Copyright (C) 2000,2003,2004,2007 University of Maryland
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs.graph;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * A simple Graph implementation where the vertex objects store a list of
 * incoming and outgoing edges. The edge link fields are stored in the edge
 * objects, which means a fairly low space overhead.
 *
 * 

* The abstract allocateEdge() method must be implemented. * * @see Graph * @see AbstractEdge * @see AbstractVertex * @author David Hovemeyer */ public abstract class AbstractGraph, VertexType extends AbstractVertex> implements Graph { /* * ---------------------------------------------------------------------- * Helper classes * ---------------------------------------------------------------------- */ /** * Iterator over outgoing edges. */ private static class OutgoingEdgeIterator, VertexType extends AbstractVertex> implements Iterator { private EdgeType edge; public OutgoingEdgeIterator(VertexType source) { this.edge = source.getFirstOutgoingEdge(); } @Override public boolean hasNext() { return edge != null; } @Override public EdgeType next() { if (!hasNext()) { throw new NoSuchElementException(); } EdgeType result = edge; edge = edge.getNextOutgoingEdge(); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } } /** * Iterator over incoming edges. */ private static class IncomingEdgeIterator, VertexType extends AbstractVertex> implements Iterator { private EdgeType edge; public IncomingEdgeIterator(VertexType target) { this.edge = target.getFirstIncomingEdge(); } @Override public boolean hasNext() { return edge != null; } @Override public EdgeType next() { if (!hasNext()) { throw new NoSuchElementException(); } EdgeType result = edge; edge = edge.getNextIncomingEdge(); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } } /* * ---------------------------------------------------------------------- * Fields * ---------------------------------------------------------------------- */ private final ArrayList vertexList; private final ArrayList edgeList; private int maxVertexLabel; // private int nextVertexId; private int maxEdgeLabel; /* * ---------------------------------------------------------------------- * Public methods * ---------------------------------------------------------------------- */ public AbstractGraph() { this.vertexList = new ArrayList<>(); this.edgeList = new ArrayList<>(); this.maxVertexLabel = 0; this.maxEdgeLabel = 0; } @Override public int getNumEdges() { return edgeList.size(); } @Override public int getNumVertices() { return vertexList.size(); } @Override public Iterator edgeIterator() { return edgeList.iterator(); } @Override public Iterator vertexIterator() { return vertexList.iterator(); } public Iterable vertices() { return vertexList; } @Override public void addVertex(VertexType v) { vertexList.add(v); v.setLabel(maxVertexLabel++); } @Override public boolean containsVertex(VertexType v) { for (VertexType existingVertex : vertexList) { if (v == existingVertex) { return true; } } return false; } @Override public EdgeType createEdge(VertexType source, VertexType target) { EdgeType edge = allocateEdge(source, target); edgeList.add(edge); source.addOutgoingEdge(edge); target.addIncomingEdge(edge); edge.setLabel(maxEdgeLabel++); return edge; } @Override public EdgeType lookupEdge(VertexType source, VertexType target) { Iterator i = outgoingEdgeIterator(source); while (i.hasNext()) { EdgeType edge = i.next(); if (edge.getTarget() == target) { return edge; } } return null; } @Override public int getNumVertexLabels() { return maxVertexLabel; } @Override public void setNumVertexLabels(int numLabels) { this.maxVertexLabel = numLabels; } @Override public int getNumEdgeLabels() { return maxEdgeLabel; } @Override public void setNumEdgeLabels(int numLabels) { maxEdgeLabel = numLabels; } @Override public void removeEdge(EdgeType edge) { if (!edgeList.remove(edge)) { throw new IllegalArgumentException("removing nonexistent edge!"); } edge.getSource().removeOutgoingEdge(edge); edge.getTarget().removeIncomingEdge(edge); } @Override public void removeVertex(VertexType v) { if (!vertexList.remove(v)) { throw new IllegalArgumentException("removing nonexistent vertex!"); } for (Iterator i = incomingEdgeIterator(v); i.hasNext();) { removeEdge(i.next()); } for (Iterator i = outgoingEdgeIterator(v); i.hasNext();) { removeEdge(i.next()); } } @Override public Iterator outgoingEdgeIterator(VertexType source) { return new OutgoingEdgeIterator<>(source); } @Override public Iterator incomingEdgeIterator(VertexType target) { return new IncomingEdgeIterator<>(target); } @Override public int getNumIncomingEdges(VertexType vertex) { int count = 0; EdgeType e = vertex.firstIncomingEdge; while (e != null) { ++count; e = e.getNextIncomingEdge(); } return count; } @Override public int getNumOutgoingEdges(VertexType vertex) { int count = 0; EdgeType e = vertex.firstOutgoingEdge; while (e != null) { ++count; e = e.getNextOutgoingEdge(); } return count; } @Override public Iterator successorIterator(final VertexType source) { return new Iterator() { private final Iterator iter = outgoingEdgeIterator(source); @Override public boolean hasNext() { return iter.hasNext(); } @Override public VertexType next() { return iter.next().getTarget(); } @Override public void remove() { iter.remove(); } }; } @Override public Iterator predecessorIterator(final VertexType target) { return new Iterator() { private final Iterator iter = incomingEdgeIterator(target); @Override public boolean hasNext() { return iter.hasNext(); } @Override public VertexType next() { return iter.next().getSource(); } @Override public void remove() { iter.remove(); } }; } /* * ---------------------------------------------------------------------- * Downcall methods * ---------------------------------------------------------------------- */ protected abstract EdgeType allocateEdge(VertexType source, VertexType target); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy