Java 二叉树搜索算法错误

Java 二叉树搜索算法错误,java,search,recursion,binary-tree,Java,Search,Recursion,Binary Tree,我有一个二叉树需要搜索。我不是在搜索树的一个特定节点,而是在树的每个节点上搜索,以获得关于它们的信息。我现在有一个简单的递归搜索,但每次运行时都会出现堆栈溢出错误。这是一个深度为7的完整二叉树 if(curDepth

我有一个二叉树需要搜索。我不是在搜索树的一个特定节点,而是在树的每个节点上搜索,以获得关于它们的信息。我现在有一个简单的递归搜索,但每次运行时都会出现堆栈溢出错误。这是一个深度为7的完整二叉树

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 );
}