我有一个需要搜索的二叉树。我不是在搜索树的一个特定节点,而是在树的每个节点上搜索有关它们的信息。我现在有一个简单的递归搜索,但每次运行时都会出现堆栈溢出错误。它是一个深度为7的完整二叉树...
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());
curID == 1对应于根节点,所以我需要检查它是不是 不是父母。 searchNodes的事情是确保我不搜索 同一个节点两次。关于如何做到这一点的任何想法?
编辑:这是整个搜索方法
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());
}
}
}
ViewedNodeLocs数组的目的是因为我在不同节点上执行搜索的板上有很多蚂蚁,最好搜索之前没有搜索过的节点,而不是搜索过的节点。我不能只做一个大搜索然后完成,因为我对下一个节点的请求应该在一个蚂蚁发出13个请求后返回null(这一切都来自我为游戏编程的蚂蚁AI)
答案 0 :(得分:2)
您的数据结构最为奇特。看起来你已经将树扁平化为一组节点。它使你的算法真的很难理解,几乎肯定是个坏主意。
话虽如此,我怀疑这个问题与每个对depthSearch的递归调用分配一个新的searchingNodes数组有关。就像我说的,你的算法很难理解。
我建议您以常规方式表示二叉树,每个节点都有一个“左”和“右”指针。然后以维基百科文章中描述的方式实现遍历。更好的是,看一下Java Collections框架,看看现有的List / Set / Map实现之一是否符合您的要求。
答案 1 :(得分:0)
您可以使用树遍历技术获取有关所有节点的信息。点击这里 http://en.wikipedia.org/wiki/Pre-order_traversal
答案 2 :(得分:0)
您需要遍历,而不是搜索。
例如,一些伪代码
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 );
}
如果要为多个蚂蚁触发此代码的多个副本,并且只让一个蚂蚁触摸任何一个节点,则需要多个线程和一个带锁定等的共享数据结构。
现在更好地分享一个“Map”数据结构,每个数据结构都通过执行遍历一次获得对您构建的数据结构的引用。毕竟,深度为7的树无论如何都只有128个节点,所以没有太多的内存或时间来遍历。如果需要,您可以随时改进它,但至少要让它先工作。