我正在写一个Graph类,
我保留一个HashMap
,其中节点(int值)的id被映射到关联的节点,并且我使用adjacency list
方法来保持边缘从节点开始(保持它们的形式一个HashSet
)
请注意:此图表是有向和未加权的,
我想实现一个方法,该方法在类Edge
的对象上返回迭代器:
当在这个迭代器上获得下一个时,会得到一个Edge类的对象,它在遍历时正好被创建,如果一个节点没有更多的邻居,它将进入下一个节点(顺序并不重要)并且如果没有更多的起始节点(遍历所有节点),它就会完成。
如何在边缘上实现此迭代器而不事先保留Edge类对象中的边缘?
class Graph{
HashMap<Integer , GraphNode> nodes;
public Graph(){
nodes = new HashMap<Integer ,GraphNode>();
}
public boolean addEdge(GraphNode n1 , GraphNode n2){
if (!nodes.containsKey(n1) || !nodes.containsKey(n2))
return false;
return n1.addNeighbor(n2);
}
public boolean addNode(int id){
if (nodes.containsKey(id))
return false;
nodes.put(id , new GraphNode(id));
return true;
}
public boolean removeNode(GraphNode n1){
if (!nodes.containsKey(n1.content))
return false;
for (GraphNode m : n1.neighbors)
m.removeNeighbor(n1);
nodes.remove(n1);
return false;
}
public boolean removeEdge(GraphNode n1 , GraphNode n2){
if (!nodes.containsKey(n1) || !nodes.containsKey(n2))
return false;
return n1.removeNeighbor(n2);
}
public Iterator<GraphNode> NodeIterator(){
return nodes.values().iterator();
}
public Iterator<Edge> EdgeIterator(){
Iterator<GraphNode> itr = this.NodeIterator();
while (itr.hasNext){
GraphNode n = itr.next();
//......
}
}
}
class GraphNode{
HashSet<GraphNode> neighbors;
int content;
public GraphNode(int content){
this.content = content;
neighbors = new HashSet<GraphNode>();
}
boolean addNeighbor(GraphNode n){
if (neighbors.contains(n))
return false;
neighbors.add(n);
return true;
}
boolean removeNeighbor(GraphNode n){
if (!neighbors.contains(n))
return false;
neighbors.remove(n);
return true;
}
}
class Edge{
Node start , end;
public Edge(Node start , Node end){
this.start = start;
this.end = end;
}
}
答案 0 :(得分:1)
我觉得这样的事情可能有用:
public Iterator<Edge> EdgeIterator(){
Iterator <Edge> edgeIter = new Iterator<Edge>() {
private Iterator<GraphNode> itr = this.NodeIterator();
private GraphNode currentNode;
... // additional private members as required
public void remove()
{
// you don't have to implement this method if you don't need to support
// this operation
}
public Edge next()
{
if (!hasNext())
throw new NoSuchElementException ();
return new Edge (x , y); // where you find x & y based on the current state
// of the iterator (kept in the private members of
// this instance)
}
public boolean hasNext()
{
return ?; // you return a boolean value based on the current state
// of the iterator (kept in the private members of
// this instance)
}
};
return edgeIter;
}
EdgeIterator
方法创建Iterator<Edge>
并定义Iterator
接口的方法(我将这些方法的实现留给您)。 Iterator
实例包含Iterator<GraphNode>
的实例,用于迭代节点。
您应该向迭代器添加一些其他私有成员来跟踪当前节点(节点迭代器返回的最后一个节点)以及您正在迭代的当前边缘。每当您完成对节点边缘的迭代时,您将使用itr.next()
获取下一个节点(在检查下一个节点可用之后)。边缘迭代器的next()
可以根据这些私有成员构造下一个Edge
。
答案 1 :(得分:0)
正如Eran所说,我完成了迭代器方法的代码, 你觉得这个有用吗?
public Iterator<Edge> EdgeIterator(){
Iterator<Edge> edgeIter = new Iterator<Edge>() {
private Iterator<GraphNode> node_itr = NodeIterator();
private Iterator<GraphNode> neighbor_itr;
private GraphNode current_node;
private GraphNode current_neighbor;
public void remove()
{
if (current_node == null || current_neighbor == null)
return;
current_node.removeNeighbor(current_neighbor);
}
public Edge next()
{
if (neighbor_itr == null || !neighbor_itr.hasNext())
if (node_itr.hasNext()){
current_node = node_itr.next();
neighbor_itr = current_node.neighbors.iterator();
}else
return null;
current_neighbor = neighbor_itr.next();
return new Edge(current_node , current_neighbor);
}
public boolean hasNext()
{
if (neighbor_itr == null || !neighbor_itr.hasNext())
if (node_itr.hasNext())
return node_itr.next().neighbors.iterator().hasNext();
else
return false;
return true;
}
};
return edgeIter;
}
更新:已修改/正在使用的版本:
public Iterator<Edge> EdgeIterator(){
Iterator<Edge> edgeIter = new Iterator<Edge>() {
private Iterator<GraphNode> node_itr = NodeIterator();
private Iterator<GraphNode> neighbor_itr;
private GraphNode current_node;
private GraphNode current_neighbor;
public void remove()
{
if (current_node == null || current_neighbor == null)
return;
current_node.removeNeighbor(current_neighbor);
}
private void moveNext(){
if (neighbor_itr == null || !neighbor_itr.hasNext()){
while (node_itr.hasNext()){
current_node = node_itr.next();
neighbor_itr = current_node.neighbors.iterator();
if (neighbor_itr.hasNext()){
break;
}
}
}
}
public Edge next()
{
moveNext();
current_neighbor = neighbor_itr.next();
return new Edge(current_node , current_neighbor);
}
public boolean hasNext()
{
moveNext();
return neighbor_itr.hasNext();
}
};
return edgeIter;
}