在广度优先搜索中存储被访问节点的数据结构

时间:2017-08-03 19:40:34

标签: data-structures graph-theory graph-algorithm breadth-first-search

我在树上应用bfs,其中每个节点有四个堆栈,其中包含一个整数。我将它们存储在队列中。我正在使用HashSet来存储访问过的节点。所以在添加队列中的节点之前,我正在检查HashSet是否包含该节点。但该计划花费了太多时间来提供输出。我的方法是正确的还是有其他方法来跟踪被访问的节点?当我们无法表示数组中的节点时,Hashset是否良好? 我提供我的代码。以下是表示一个节点的状态类。

  static class State implements Serializable
  {
     int c=0;  
     Stack s[]=new Stack[4];
     State()
     {        
        for(int i=0;i<4;i++)
        {
           s[i]=new Stack();
        }
     }
  }

我的广度优先搜索算法在以下代码中

static int  Bfs(HashSet<state>hs,state st,int n)
{
    hs.add(st);
    LinkedList<state> queue = new LinkedList<>();
    queue.add(st);
    while(!queue.isEmpty())
    {
        state sn=queue.remove();            
        if(sn.s[0].size()==n)
        {                
            return sn.c;
        }
        for(int i=0;i<4;i++)
        {
            if(sn.s[i].size()>0)
            {
                int f=i;
                for(int id:IntStream.range(0, 4).filter(x->(x!=f)).toArray())
                {                   

                       state tm=(state)deepcopy(sn); 
                       if((tm.s[id].size()==0)||((int)tm.s[id].peek()>(int)tm.s[i].peek()))
                       {    
                            tm.s[id].push(tm.s[i].pop());
                            if(!hs.contains(tm))
                            {
                                tm.c+=1;
                                hs.add(tm);
                                queue.add(tm);
                            }
                           queue.add(tm);
                       }    
                } 
            }    
        }
    }
    return -1;
}

上面的代码是针对问题“dangerously-set-inner”,这就像4个堆叠的河内塔一样。我需要将所有磁盘放在第一个堆栈中。因此,在每个deque操作中,我从一个堆栈中弹出最后一个元素并逐个推送到其他堆栈上,并且我在所有堆栈上逐个执行此弹出操作。因此,对于每个状态,将有4x3个邻居。 For循环只是将所有其他堆栈的索引存储在变量id中,其中弹出元素将被推送。

1 个答案:

答案 0 :(得分:0)

是的,我认为这是存储访问节点的一种非常好的方法,特别是因为您无法在Hashset中存储任何重复项。这是另一种选择。我已编码。

    Class Main {
public void bfs()
{
    // BFS uses Queue data structure
    Queue queue = new LinkedList();
    queue.add(this.rootNode);
    printNode(this.rootNode);
    rootNode.visited = true;
    while(!queue.isEmpty()) {
        Node node = (Node)queue.remove();
        Node child=null;
        while((child=getUnvisitedChildNode(node))!=null) {
            child.visited=true;
            printNode(child);
            queue.add(child);
        }
    }
    // Clear visited property of nodes
    clearNodes();
}