Your problem is that you made "c" in the local variable and edited its contents, but you need to edit the non-local variable.
You might be fine if you do *n = c; before each return (or change the code so that there is only one return, and reassign before). So - untested code:
int insert(Node ** n, int data) { Node *c = *n; int rc = 0; // create new node if (c == NULL) { c = (Node*) malloc(sizeof(Node)); c->data = data; c->left = NULL; c->right = NULL; rc = 1; } else if (data > c->data) { rc = insert(&c->right, data); } else { rc = insert(&c->left, data); } *n = c; return rc; }
Verified code
With a test harness. Printing is not great - but at least it works. Note that you need to free the tree using postoperative traversal; printing can be done previously or in order (as here) or after ordering.
#include <assert.h> #include <stdlib.h> #include <stdio.h> typedef struct Node Node; struct Node { int data; Node *left; Node *right; }; static void insert(Node **n, int data) { Node *c = *n; if (c == NULL) { // create new node c = (Node*) malloc(sizeof(Node)); c->data = data; c->left = NULL; c->right = NULL; } else if (data > c->data) insert(&c->right, data); else insert(&c->left, data); *n = c; } static void dumptree(Node **tree, const char *tag) { assert(tree != 0); Node *node = *tree; if (node != 0) { dumptree(&node->left, "left"); printf("data: %d (%s)\n", node->data, tag); dumptree(&node->right, "right"); } } static void dump(Node **tree, const char *tag) { printf("In-Order Dump (%s)\n", tag); dumptree(tree, "root"); } static void freetree(Node **tree) { assert(tree != 0); Node *node = *tree; if (node != 0) { freetree(&node->left); freetree(&node->right); free(node); //*tree = 0; } } int main(void) { Node *base = 0; int array[] = { 3, 9, 1, 4, 8, 2, 5, 7, 0, 6 }; int i; for (i = 0; i < 10; i++) { char buffer[32]; sprintf(buffer, "Add node %d", array[i]); insert(&base, array[i]); dump(&base, buffer); } freetree(&base); return 0; }