我编写了以下用于创建二进制搜索树的代码,但是当调用创建函数并且它第一次尝试调用insertNode(...)时程序挂起。以下是代码:
XfaForm xfa = new XfaForm(reader);
Node node = xfa.getDatasetsNode();
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
if ("data".equals(list.item(i).getLocalName())) {
node = list.item(i);
break;
}
}
// strip <xfa:data>
node = node.getFirstChild();
// Transformer code here
任何人都可以指出我的错误。任何建议都是有帮助的。
答案 0 :(得分:2)
在这种树中插入的算法是(insert(node, value)
):
node
为NULL则分配节点,将左/右设置为NULL(它是叶子),将值设置为value
,返回分配的节点value < node->value
:node->left = insert(node->left, value)
node->right = insert(node->right, value)
return node
(以便我们有同类代码)插入,假设您的main
是相同的:root = insert(root, val)
。
您可以将指针传递给指针(&root
),而不是返回值,但是您必须在函数中处理取消引用它。你似乎不太熟悉指针,如果你打算玩这种结构,你真的应该阅读更多关于它的内容。
另请注意,printf
函数中的main
无用:在那种树中,根值始终是第一个插入的值(或者你会必须在树中执行移位以平衡分支,但这是另一个问题)。
打印btree也意味着递归功能,你必须选择如何打印它(深度优先,排序......)。示例:如果node为NULL返回;在左边打电话给自己;印刷价值;称自己为正确→将打印按小到大的顺序排列的内容。
答案 1 :(得分:2)
任何人都可以指出我的错误。
主要问题是createNode
修改了root
的本地副本。永远不会修改全局变量root
,并将其设置为NULL
。
任何建议都有帮助。
root
移动为main
中的本地变量。create
的签名和目的,以便它只创建一个节点,而不是其他任何内容。malloc
的结果。请参阅Specifically, what's dangerous about casting the result of malloc? insertNode
中使用create
代替main
。在create
的正确位置致电insertNode
。以下是我对该计划的建议:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct BstNode{
int value;
struct BstNode* left;
struct BstNode* right;
};
struct BstNode* create(int data){
printf("Creating a node with value: %d\n", data);
struct BstNode* node = malloc(sizeof(*node));
node->value = data;
node->left = NULL;
node->right = NULL;
return node;
}
struct BstNode* insertNode(struct BstNode* root, int data){
if ( root == NULL )
{
return create(data);
}
if(data <= root->value)
root->left = insertNode(root->left, data);
else
root->right = insertNode(root->right, data);
return root;
}
void print(struct BstNode* node, int indent, char const* nodeName)
{
if ( node == NULL )
{
return;
}
for (int i = 0; i < indent; ++i )
{
printf(" ");
}
printf("%s: %d\n", nodeName, node->value);
print(node->left, indent+1, "left");
print(node->right, indent+1, "right");
}
int main(int argc, char** argv){
struct BstNode *root = NULL;
int i;
int data;
int num = 5;
if ( argc > 1 )
num = atoi(argv[1]);
srand(time(NULL));
for(i=0;i<num;i++){
data = rand()%10000;
root = insertNode(root, data);
}
printf("\n");
print(root, 0, "root");
return 0;
}
答案 2 :(得分:0)
函数insertNode具有无限递归,导致程序崩溃。
更具体地说
struct BstNode* insertNode(struct BstNode* root, int data){
if(data <= root->value)
root->left = insertNode(root->left, data);
else
root->right = insertNode(root->right, data);
printf("%d ",root->value);
return root;
你进入功能并检查是否(data&lt; = root-&gt; value)。在这两种情况下(true和false),你再次调用insertNode函数,然后一次又一次地调用insertNode - 你永远不会得到return语句。递归函数需要有一个基本情况,它返回一些值而不再调用它自己。
thisFunction()
if (base case)
return value;
else
return thisFunction()
在二叉搜索树的情况下,基本情况是当你插入的密钥(数据)是A)插入的密钥大于当前节点并且当前节点的右边的子节点是叶子(null)或者B)插入的密钥是比当前节点更小(或等于你想要解决关系的方式)和当前节点的左子节点为空。(data > cur->data && cur->right == NIL)
或(data < cur->data && cur->left == NIL)
。如果您遇到其中一种情况,只需将新节点设为当前节点的右子节点或左子节点。