Java 二叉树搜索算法错误
我有一个二叉树需要搜索。我不是在搜索树的一个特定节点,而是在树的每个节点上搜索,以获得关于它们的信息。我现在有一个简单的递归搜索,但每次运行时都会出现堆栈溢出错误。这是一个深度为7的完整二叉树Java 二叉树搜索算法错误,java,search,recursion,binary-tree,Java,Search,Recursion,Binary Tree,我有一个二叉树需要搜索。我不是在搜索树的一个特定节点,而是在树的每个节点上搜索,以获得关于它们的信息。我现在有一个简单的递归搜索,但每次运行时都会出现堆栈溢出错误。这是一个深度为7的完整二叉树 if(curDepth
if(curDepth<6&!searchedNodes[curID*2])
深度搜索(curNode.getRight());
if(curDepth<6&!searchedNodes[curID*2+1])
深度搜索(curNode.getLeft());
如果(curID!=1&&!searchedNodes[(int)(curID/2)])
深度搜索(curNode.getParent())代码>
curID==1对应于根节点,所以我需要检查它是否
不是父母。searchedNodes的任务是确保我不进行搜索
同一节点重复两次。有什么办法吗
编辑:这是整个搜索方法
public void depthSearch(AntTree curNode){
布尔[]searchedNodes=新布尔[128];
if(curNode==null)
返回;
int curID=curNode.getID();
searchedNodes[curID]=true;
如果(curNode.getFood()>0){
AntScript.foodLocs[curID]=1;
}否则{
Ant6Script.foodLocs[curID]=0;
}
Ant[]ants=curNode.getAnts();
布尔值containsWorker=false,containsSoldier=false;
if(ants!=null){
for(int i=0;i
viewedNodeLocs数组的用途是因为我在一块板上有许多蚂蚁从不同的节点执行搜索,因此搜索之前未搜索过的节点比搜索过的节点更好。我不能只做一次大的搜索,然后就完成了,因为我对下一个节点的请求应该在一只蚂蚁发出13次请求后返回null(这整件事都是从我为游戏编写的蚂蚁AI中得到的)你可以使用树遍历技术来获取所有节点的信息。检查这里
.您需要遍历,而不是搜索
例如,一些psuedo代码
void PrintTree( TreeNode node ){
if( node == null ) return;
if( node.Left != null ) PrintTree( node.Left );
if( node.Right != null ) PrintTree( node.Right );
Console.Printline( node.Value );
}
如果您想为多个ant启动此代码的多个副本,并且只让一个ant接触任何单个节点,那么您将需要多个线程和一个带有锁定等功能的共享数据结构
现在最好只共享一个“映射”数据结构,每个数据结构都通过执行一次遍历来获取对所构建数据结构的引用。毕竟,深度为7的树无论如何只会有128个节点,所以遍历它的内存和时间都不多。如果需要,您随时可以在以后对其进行改进,但至少要先让它工作。您的数据结构非常独特。看起来您已将树展平为一组节点。这使得你的算法很难理解,而且几乎可以肯定这是个坏主意
话虽如此,我怀疑问题与以下事实有关:对depthSearch的每个递归调用都会分配一个新的searchedNodes数组。就像我说的,你的算法是。。。很难理解
我建议您用传统的方式表示二叉树,每个节点都有一个“左”和“右”指针。然后按照wikipedia文章中描述的方式实现遍历。更好的是,看看Java集合框架,看看现有的List/Set/Map实现中是否有一个实现了您想要做的事情。信息不够。发布整个递归搜索例程。如果没有对您实际尝试执行的操作的描述,则很难评估您所编写的内容。对于一个相对简单的问题来说,这看起来非常复杂,并且有一些明显的错误。最重要的一点是,每个递归调用将创建自己的searchedNodes副本,并只设置一个元素。下面的测试只查看当前调用
public void depthSearch(AntTree curNode) {
boolean[] searchedNodes = new boolean[128];
if (curNode == null)
return;
int curID = curNode.getID();
searchedNodes[curID] = true;
if (curNode.getFood() > 0) {
AntScript.foodLocs[curID] = 1;
} else {
Ant6Script.foodLocs[curID] = 0;
}
Ant[] ants = curNode.getAnts();
boolean containsWorker = false, containsSoldier = false;
if (ants != null) {
for (int i = 0; i < ants.length; i++) {
if (ants[i].type().equals("Worker")
&& ants[i].teamID() != AntScript.myTeamID) {
containsWorker = true;
} else if (ants[i].type().equals("Soldier")
&& ants[i].teamID() != AntScript.myTeamID) {
containsSoldier = true;
} else if (ants[i].type().equals("Queen")
&& ants[i].teamID() != AntScript.myTeamID) {
AntScript.enemyQueenLoc = curID;
}
}
}
if (containsWorker)
AntScript.enemyWorkerLocs[curID] = 1;
else
AntScript.enemyWorkerLocs[curID] = 0;
if (containsSoldier)
AntScript.enemySoldierLocs[curID] = 1;
else
AntScript.enemySoldierLocs[curID] = 0;
AntScript.viewedNodeLocs[curID] = 1;
int curDepth = (int) (Math.log(curID) / Math.log(2));
if (AntScript.viewedNodeLocs[(int) (curID / 2)] == 0
|| (curDepth < 6 && AntScript.viewedNodeLocs[curID * 2 + 1] == 0)
|| (curDepth < 6 && AntScript.viewedNodeLocs[curID * 2] == 0)) {
if (curDepth < 6
&& AntScript.viewedNodeLocs[curID * 2] == 0
&& !searchedNodes[curID * 2]) {
depthSearch(curNode.getLeft());
}
if (curDepth < 6
&& AntScript.viewedNodeLocs[curID * 2 + 1] == 0
&& !searchedNodes[curID * 2 + 1]) {
depthSearch(curNode.getRight());
}
if (curID != 1
&& AntScript.viewedNodeLocs[(int) (curID / 2)] == 0
&& !searchedNodes[(int) (curID / 2)]) {
depthSearch(curNode.getParent());
}
} else {
if (curDepth < 6 && !searchedNodes[curID * 2]) {
depthSearch(curNode.getRight());
}
if (curDepth < 6 && !searchedNodes[curID * 2 + 1]) {
depthSearch(curNode.getLeft());
}
if (curID != 1 && !searchedNodes[(int) (curID / 2)]) {
depthSearch(curNode.getParent());
}
}
}
void PrintTree( TreeNode node ){
if( node == null ) return;
if( node.Left != null ) PrintTree( node.Left );
if( node.Right != null ) PrintTree( node.Right );
Console.Printline( node.Value );
}