我读过很多类似的文章,如果这已经得到回答,我道歉,但我仍然被卡住了。
我正在编写一个函数来填充树,每个节点有四个分支,这将存储“八个拼图”状态的可能操作,即http://www.8puzzle.com/images/8_puzzle_start_state_a.png
问题是我已达到,我认为是堆栈溢出,因为手头的问题具有很强的递归性质。
尾递归似乎是解决方案,但我不确定它是否相关/可能或如何在此实例中实现它。代码如下:
void Tree::insert(string &initialState, const string &goalState, tree_node *&inNode){
cout<<"insert called"<<endl;
depth++;
cout<<depth<<endl;
string modState;
int zeroPos=0;
if(initialState==goalState){
cout<<"* * * GOAL * * *"<<endl;
getchar();
exit(0);
}
if(inNode==NULL){//is this the first node?
inNode = new tree_node(initialState);
root=inNode;
inNode->parent=NULL;
insert(initialState, goalState, inNode);
}else{
inNode->state = initialState;
for(zeroPos=0;zeroPos<initialState.size();zeroPos++){//where is the empty tile?
if(initialState[zeroPos]=='0'){
break;
}
}
//left
if(zeroPos!=0 && zeroPos!=3 && zeroPos!=6){//can the empty tile move left?
modState=initialState;
modState[zeroPos]=modState[zeroPos-1];
modState[zeroPos-1]='0';
if(isOriginal(modState, inNode) ){//does this state already exist?
cout <<"left " << modState[0]<<modState[1]<<modState[2]<<endl;
cout <<"left " << modState[3]<<modState[4]<<modState[5]<<endl;
cout <<"left " << modState[6]<<modState[7]<<modState[8]<<endl;
inNode->l = new tree_node(modState);
inNode->l->parent= inNode;
if(inNode->l != NULL){
insert(modState, goalState, inNode->l);
}
}
}
}
}
}
答案 0 :(得分:2)
这是一个非常通用的答案,但您是否尝试通过堆分配队列或堆栈等方式显式管理堆栈?基本上不要使用实际的函数调用,只需从你自己的堆栈/队列中推送和拉出东西。它们涵盖了非递归图遍历算法here(深度优先和广度优先搜索)。
答案 1 :(得分:0)
优化代码,意味着只保留您需要的节点。例如,只保留叶子节点(我的意思是那些你尚未透露的节点)。 是的,您可以在构建树时搜索树,编写一个函数来测量当前状态和目标状态之间的距离,称为启发式。还有一个更好的算法解决了8puzzle,它被称为A *,我建议你谷歌吧。