0

我编写了以下代码,它正确打印了根值,但不是 ret 值。这里可能会打印一个内存地址(1707388)。我相信现在可以修改 ret,结果将在 main.js 中看到。任何帮助表示赞赏。

#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(&current->left, &ret, size);
        traverse(&current->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;
}
4

4 回答 4

4

这个:

void createTree(node_t *p, int order)

应该

void createTree(node_t **p, int order)

否则,您将修改本地 node_t指针,而不是函数外部的指针。你的树也没有正确建造。

于 2013-03-24T15:38:02.210 回答
3

ret按价值传递给

void traverse(node_t *current, node_t *ret, int size){

当函数更改ret时,更改不会传播回调用者。

这意味着retinmain()保持未初始化,并且代码的行为未定义。

要解决此问题,请进行traversereturnret或将其作为node_t**.

于 2013-03-24T15:38:47.810 回答
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);
于 2013-03-24T15:51:23.253 回答
1

traverse(node_t *current, node_t *ret, int size)ret是一个堆栈变量。换句话说,您通过 value传递指针,而不是通过 reference传递它。

你目前所做的基本上是一样的:

int f(int i) {
   ...
   i = <any value>;
   ...
}

在这种情况下,您只修改了值的副本。

在您的程序中,您还修改了指针的副本。在函数之外,指针保持不变。

如果你想修改它,你需要传递一个指向它的指针:

void traverse(node_t *current, node_t **ret, int size){
    ...
    *ret = current;
    ...
    return;
}

对于createTree().

于 2013-03-24T16:03:31.130 回答