/*******************************************************************************
* Copyright (c) 2013 Philip Collin.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Philip Collin - initial API and implementation
******************************************************************************/
package PaulChew;
/*
* Copyright (c) 2007 by L. Paul Chew.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Straightforward undirected graph implementation.
* Nodes are generic type N.
*
* @author Paul Chew
*
* Created November, December 2007. For use in Delaunay/Voronoi code.
*
*/
public class Graph<N> {
private Map<N, Set<N>> theNeighbors = // Node -> adjacent nodes
new HashMap<N, Set<N>>();
private Set<N> theNodeSet = // Set view of all nodes
Collections.unmodifiableSet(theNeighbors.keySet());
/**
* Add a node. If node is already in graph then no change.
* @param node the node to add
*/
public void add (N node) {
if (theNeighbors.containsKey(node)) return;
theNeighbors.put(node, new ArraySet<N>());
}
/**
* Add a link. If the link is already in graph then no change.
* @param nodeA one end of the link
* @param nodeB the other end of the link
* @throws NullPointerException if either endpoint is not in graph
*/
public void add (N nodeA, N nodeB) throws NullPointerException {
theNeighbors.get(nodeA).add(nodeB);
theNeighbors.get(nodeB).add(nodeA);
}
/**
* Remove node and any links that use node. If node not in graph, nothing
* happens.
* @param node the node to remove.
*/
public void remove (N node) {
if (!theNeighbors.containsKey(node)) return;
for (N neighbor: theNeighbors.get(node))
theNeighbors.get(neighbor).remove(node); // Remove "to" links
theNeighbors.get(node).clear(); // Remove "from" links
theNeighbors.remove(node); // Remove the node
}
/**
* Remove the specified link. If link not in graph, nothing happens.
* @param nodeA one end of the link
* @param nodeB the other end of the link
* @throws NullPointerException if either endpoint is not in graph
*/
public void remove (N nodeA, N nodeB) throws NullPointerException {
theNeighbors.get(nodeA).remove(nodeB);
theNeighbors.get(nodeB).remove(nodeA);
}
/**
* Report all the neighbors of node.
* @param node the node
* @return the neighbors of node
* @throws NullPointerException if node does not appear in graph
*/
public Set<N> neighbors (N node) throws NullPointerException {
return Collections.unmodifiableSet(theNeighbors.get(node));
}
/**
* Returns an unmodifiable Set view of the nodes contained in this graph.
* The set is backed by the graph, so changes to the graph are reflected in
* the set.
* @return a Set view of the graph's node set
*/
public Set<N> nodeSet () {
return theNodeSet;
}
}