几套迭代器

时间:2013-06-27 20:51:52

标签: java graph iterator

我正在写一个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;
    }
}

2 个答案:

答案 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;
}