所以我正在通过数组实现二进制搜索树(如果父级索引是i,那么左子索引是(i * 2 + 1),右子索引是(i * 2 + 2)。
每当我试图遍历树(预先排序)时,我在第3个预订函数调用期间遇到堆栈溢出。
这是我的预订功能代码:
void traversePreOrder(Tree tree, int index)
{
printf("%d\n", index); //debug
if (tree.data[index].accNumber != 0) //all .accNumber values are initialized as 0
// at the start of the program to mark empty nodes.
{
printf("printing: %d\n", index); //debug
printNode(tree.data[index]);
if (tree.data[index * 2 + 1].accNumber != 0)
{
printf("will print: %d\n", index * 2 + 1); //debug
traversePreOrder(tree, index * 2 + 1);
}
if (tree.data[index * 2 + 2].accNumber != 0)
{
printf("will print: %d\n", index * 2 + 2); //debug
traversePreOrder(tree, index * 2 + 2);
}
}
else
return;
}
以下是预订遍历的输出:
0
printing: 0
User: Dumbledore
Account number: 53167
Account type: public
Account balance: 4597.54
Is account in debt? Yes
will print: 1
1
printing: 1
User: Stark
Account number: 13497
Account type: private
Account balance: 1549.50
Is account in debt? No
will print: 3
Process returned 255 (0xFF) execution time : 5.856 s
Press any key to continue.
树应该看起来像:
(only accNumber values)
53167
/ \
13457 74310
\ / \
43158 71401 79473
/ / \
14741 69690 99751
感谢您的帮助。
更新
将最大树容量从1000更改为50以某种方式解决了这个问题。如果有人可以解释原因,那就太好了。
答案 0 :(得分:1)
你声明:
所有.accNumber值在程序开始时初始化为0 标记空节点。
这不是一个足够强大的递归停止标准。
如果你想要明确,你应该在索引的上限,并确保你不超过它。例如:如果tree.size
iz是树中节点的数量,那么在递归的每个步骤之前也应该进行查询,如下所示:
int left_child_idx = index * 2 + 1;
if (tree.data[left_child_idx].accNumber != 0 && left_child_idx < tree.size)
{
printf("will print: %d\n", index * 2 + 1); //debug
traversePreOrder(tree, index * 2 + 1);
}
或者,如果你不想这样做,你应该确保有两个终止叶子,0 accNumber
所有你的最后一个节点。
在这个数据结构中,实际上意味着data
数组的后半部分应该只包含这样的终止叶子。
看起来很难看,但我希望你能看到它:
53167
/ \
13457 74310
/ \ / \
0 43158 71401 79473
/ \ / \ / \ / \
0 0 14741 0 69690 0 0 99751
/\ /\ /\ /\ /\ /\ /\ /\
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
作为一个阵列:
[53167, 13457, 74310, 0, 43158, 71401, 79473, 0, 0, 14741, 0, 69690, 0, 0, 99751,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
有31个元素,99751是第15个元素。下半场的任何一个都不会为零,你会得到溢出。