我在树上应用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中,其中弹出元素将被推送。
答案 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();
}