not understanding why passing double pointer is required to pass a struct node by reference. isnt single pointer enough

this program is written to insert the nodes in binary search tree and also display the built tree. what i dont understand is why does the first argument of insert has to be a double pointer to pass it by reference. i tried removing the double pointer and instead using a single pointer as the first argument of insert() and tried to get the program working but it doesnt work. the inorder pre and post order displays come as a blank. pls help. the first program is a working version(using double pointers)
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<malloc.h>

struct node
{
    int data;
    struct node* lc;
    struct node* rc;
};
void insert(struct node** root,int num);
void inorder(struct node* root);
void preorder(struct node* root);
void postorder(struct node* root);
int main(void)
{
    int i=1,req,num;
    struct node* root=NULL;
    printf("enter no. of elements to be inserted\n");
    scanf("%d",&req);

    printf("enter the elements\n");
    while(i++<=req)
    {
        scanf("%d",&num);
        insert(&root,num);

    }
    printf("inorder traversal\n");
    inorder(root);
    printf("\npreorder traversal\n");
    preorder(root);
    printf("\npostorder traversal\n");
    postorder(root);
    return 0;
}
void insert(struct node** root,int num)
{
    struct node* tmp=NULL;
    if(*root==NULL)
    {
        tmp=(struct node*)malloc(sizeof(struct node));
        tmp->data=num;
        tmp->rc=NULL;
        tmp->lc=NULL;
        *root=tmp;
    }
    else if(num<((*root)->data))
    {
        insert(&((*root)->lc),num);
    }
    else
    {
        insert(&((*root)->rc),num);
    }
}
void inorder(struct node* root)
{
    if(root!=NULL)
    {
        inorder(root->lc);
        printf("%d ",root->data);
        inorder(root->rc);
    }
}
void preorder(struct node* root)
{
  if(root!=NULL)
    {

        printf("%d ",root->data);
        preorder(root->lc);
        preorder(root->rc);
    }
}
void postorder(struct node* root)
{
    if(root!=NULL)
    {
        postorder(root->lc);
        postorder(root->rc);
        printf("%d ",root->data);
    }
}

the next code is the one that doesn’t work(using single pointers)

#include<stdio.h>

#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<malloc.h>

struct node
{
int data;
struct node* lc;
struct node* rc;
};
void insert(struct node* root,int num);
void inorder(struct node* root);
void preorder(struct node* root);
void postorder(struct node* root);
int main(void)
{
int i=1,req,num;
struct node* root=NULL;
printf(“enter no. of elements to be inserted\n”);
scanf("%d",&req);

printf("enter the elements\n");
while(i++<=req)
{
    scanf("%d",&num);
    insert(root,num);

}
printf("inorder traversal\n");
inorder(root);
printf("\npreorder traversal\n");
preorder(root);
printf("\npostorder traversal\n");
postorder(root);
return 0;

}
void insert(struct node* root,int num)
{
struct node* tmp=NULL;
if(root==NULL)
{
tmp=(struct node*)malloc(sizeof(struct node));
tmp->data=num;
tmp->rc=NULL;
tmp->lc=NULL;
root=tmp;
}
else if(num<((root)->data))
{
insert(root->lc,num);
}
else
{
insert(root->rc,num);
}
}
void inorder(struct node* root)
{
if(root!=NULL)
{
inorder(root->lc);
printf("%d ",root->data);
inorder(root->rc);
}
}
void preorder(struct node* root)
{
if(root!=NULL)
{

    printf("%d ",root->data);
    preorder(root->lc);
    preorder(root->rc);
}

}
void postorder(struct node* root)
{
if(root!=NULL)
{
postorder(root->lc);
postorder(root->rc);
printf("%d ",root->data);
}
}