我编写了以下代码,它正确打印了根值,但没有写入ret值。这里可能会打印一个内存地址(1707388)。我相信ret现在可以修改,结果将在main中看到。任何帮助表示赞赏。
#include <stdlib.h>
struct node{
int value;
int order;
struct node *left;
struct node *right;
};
typedef struct node node_t;
node_t array[10];
void createTree(node_t *p, int order){
p->value = rand()%10;
p->order = order;
printf("%i", p->value);
printf(" ");
printf("%i\n", p->order);
if (!order){
p->left = NULL;
p->right = NULL;
return;
}
order--;
createTree(&p->left, order);
createTree(&p->right, order);
}
void traverse(node_t *current, node_t *ret, int size){
printf("%i\n", current->value);
if (current->value > size){
ret = current;
traverse(¤t->left, &ret, size);
traverse(¤t->right, &ret, size);
}
return;
}
int main(void){
node_t *root = &array[0];
node_t *ret;
srand(time(NULL));
createTree(root, 4);
int i = 3;
printf("%s", "root-value: ");
printf("%i\n", root->value);
traverse(root, ret, i);
printf("%s", "root-value: ");
printf("%i\n", root->value);
printf("%i\n", ret->value);
return 1;
}
答案 0 :(得分:4)
此:
void createTree(node_t *p, int order)
应该是
void createTree(node_t **p, int order)
否则,您正在修改本地 node_t
指针,而不是函数外部的指针。您的树也没有正确构建。
答案 1 :(得分:3)
您将ret
按值传递给
void traverse(node_t *current, node_t *ret, int size){
当函数更改ret
时,更改不会传播回调用者。
这意味着ret
中的main()
仍然未初始化,并且代码的行为未定义。
要解决此问题,请traverse
返回ret
,或将其作为node_t**
。
答案 2 :(得分:2)
代码存在一些问题。
首先,您没有为节点正确分配内存。在你的代码中,你传递错误的指针类型,而且指向未初始化区域。
在这里,如何以不同的方式使用它:
node_t *createTree(int order)
{
node_t *result = malloc(sizeof(*result));
result->value = rand() % 10;
result->order = order;
if (order)
{
result->left = createTree(order - 1);
result->right = createTree(order - 1);
}
else
{
result->left = result->right = 0;
}
return result;
}
然后,你的遍历函数需要一些块来限制再次失败的搜索:
node_t *traverse(node_t *current, int size)
{
node_t *ret = NULL;
if (current->value > size)
{
// assuming current node fit - stops the search
ret = current;
}
if (!ret && current->left)
{
// try left node
ret = traverse(current->left, size);
}
if (!ret && current->right)
{
// try right node
ret = traverse(current->right, size);
}
return ret;
}
如果您需要(通常是),这里是destroyTree
:
void destroyTree(node_t *node)
{
if (!node) return; // we treat NULL as a valid pointer for simplicity
destroyTree(node->left);
destroyTree(node->right);
free(node);
}
这是一个用法示例:
node_t *root, *found;
root = createTree(4);
found = traverse(root, 3);
if (found)
{
printf("Found!");
}
destroyTree(root);
答案 3 :(得分:1)
在traverse(node_t *current, node_t *ret, int size)
中,ret
是一个堆栈变量。换句话说,您将指针按值传递,而不是通过引用传递 。
目前你做了什么与基本相同:
int f(int i) {
...
i = <any value>;
...
}
在这种情况下,您只修改值的副本。
在您的程序中,您还要修改指针的副本。在函数外部,指针不会被修改。
如果要修改它,则需要传递指针:
void traverse(node_t *current, node_t **ret, int size){
...
*ret = current;
...
return;
}
createTree()
也一样。