C 二叉树,内存分配

C 二叉树,内存分配,c,memory-management,struct,binary-search-tree,C,Memory Management,Struct,Binary Search Tree,所以我尝试用C语言用结构和jazz来构建一个二叉树。到目前为止,我得到了以下信息: #include <stdio.h> #include <string.h> #include <stdarg.h> #include <stdlib.h> #include <math.h> #include <assert.h> #include <signal.h> typedef struct treeNode {

所以我尝试用C语言用结构和jazz来构建一个二叉树。到目前为止,我得到了以下信息:

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <signal.h>

typedef struct treeNode {
    int value;
    struct treeNode *left;
    struct treeNode *right;
} node;

node *top = NULL;

static node *addNode(int e, node *n);
static void printTree(node *n);

static node *addNode(int e, node *n) {
    if(top == NULL) {
        top = malloc(sizeof(node));
        top->value = e;
        top->left = NULL;
        top->right = NULL;
        return top;
    } else if (n != NULL) {
        if(e <= n->value) {
            if(n->left == NULL) {
                n->left = addNode(e, n->left);
            } else {
                (void) addNode(e, n->left); 
            }
        } else {
            if(n->right == NULL) {
                n->right = addNode(e, n->right);
            } else {
                (void) addNode(e, n->right);
            }
        }
    } else if(n == NULL) {
        n = malloc(sizeof(node));
        n->value = e;
        n->left = NULL;
        n->right = NULL;
        return n;
    }
    return n;
}

static void printTree(node *n) {
    if(n != NULL) {
        fprintf(stdout, "%d, ", n->value);
        if(n->left != NULL) {
            printTree(n->left);
        }
        if(n->right != NULL) {
            printTree(n->right);
        }
    }
}

int main(int argc, char **argv) {
        addNode(1, top);
        addNode(2, top);
        addNode(0, top);
        addNode(3, top);
        printTree(top);
return 0;
}

这根本不起作用-因此没有创建新节点。现在的情况是,它正在按照它必须的方式工作——我真的不明白它为什么会这样做。当我第一次调用addNode函数时,不管怎样,我都会将顶部指针作为参数提供给它,因此它应该检查它是否为null(此时应该为null),并且应该为它分配一些内存。然而,这并没有发生。我不明白为什么。

您需要将第一个节点分配给
top

int main(int argc, char **argv) {
    top = addNode(1, top);
    addNode(2, top);
    addNode(0, top);
    addNode(3, top);
    printTree(top);
    return 0;
}

对于原始的
if
子句,
top
未得到更新。您刚才在这里返回了几点。首先让我们从细节开始:您的
printTree()
太复杂了。当您在输入函数时检查空值时,无需再次检查左/右:

void printTree(node *n) {
  if (n == NULL) { return; }  // just leave
  printTree(n->left);
  printf("%d\n", n->value);
  printTree(n->right);
}
请注意,打印值的顺序(左和右)将改变输出。在本例中,它将从低值打印到高值

现在,对于
addNode()
来说,不需要全局
top
值。将
top
赋给函数,并获取带有返回值的新函数(
top=addNode(val,top);
。在混合
n
top
访问时,使用此全局值只会导致错误代码。 而且功能可以更简单:

node *addNode(int val, node *n) {
  if (n == NULL) {  // just allocate a new one
    n = malloc(sizeof(node));  // add check for failure here, of course
    n->left = n->right = NULL; // it is a leaf, no child
    n->value = val;
    return(n);  // return the node for caller
  }
  // ok, we are on a node, check on which side we need to insert
  if (val < n->value) {
    // to the left: it may be replaced (if created)
    n->left = addNode(val, n->left);
  } else {
    // same, for right
    n->right = addNode(val, n->right);
  }
  // return the node so that top=addNode(val,top) always works
  return(n);
}

不,
top
是在
addNode
中设置的。看一下对
malloc
的调用
top
是全局的。所以这不会有任何区别。这段代码是为了让他最初的尝试在他将
if n==NULL
放在第一位的地方工作,而根本没有设置
top
。哦,好的,对不起,我误解了:
(*n)->左
(右和值相同)
node *addNode(int val, node *n) {
  if (n == NULL) {  // just allocate a new one
    n = malloc(sizeof(node));  // add check for failure here, of course
    n->left = n->right = NULL; // it is a leaf, no child
    n->value = val;
    return(n);  // return the node for caller
  }
  // ok, we are on a node, check on which side we need to insert
  if (val < n->value) {
    // to the left: it may be replaced (if created)
    n->left = addNode(val, n->left);
  } else {
    // same, for right
    n->right = addNode(val, n->right);
  }
  // return the node so that top=addNode(val,top) always works
  return(n);
}
void addNode(int val, node **n) {
  if (*n == NULL) {  // just allocate a new one
    *n = malloc(sizeof(node));  // add check for failure here, of course
    (*n)->left = (*n)->right = NULL; // it is a leaf, no child
    (*n)->value = val;
    return;  // return, the node 'n' is still modified
  }
  // ok, we are on a node, check on which side we need to insert
  if (val < (*n)->value) {
    // to the left: it may be replaced (if created)
    (*n)->left = addNode(val, (*n)->left);
  } else {
    // same, for right
    (*n)->right = addNode(val, (*n)->right);
  }
  // leave function (return not needed), node unchanged
  return;
}
int main(void) {
  node *top = NULL;  // must be initialized

  addNode(3, &top);
  addNode(1, &top);
  addNode(5, &top);
  printNode(top);
  (…)