C语言中将数组元素值赋给链表中各节点

NODE *creatlist(int a[])
{
    NODE *h,*p,*q;
    int i;
    h=(NODE *)malloc(sizeof(NODE));
    h->next=NULL;                                                   
    for(i=0;i<N;i++)
    {
        q=(NODE *)malloc(sizeof(NODE));
        q->data=a[i];                                          
        q->next=NULL;                                                
     if(h->next==NULL)                                           
        h->next=p=q;                                         
    else
    {
        p->next=q;                                                   
        p=q;
    }
    }
    return h;
}

if语句和else 语句那里看不懂,返回值为h 为什么我感觉是只有一次给h的一个节点赋值。该怎么理解,求解答。

这种最好还是画图理解,但是我懒得画图了。。。
注意:NODE 节点应该是链表, 每个节点应该是对应自己的data,和next

struct Node
{
int data;
struct Node* next;
};

假设 p只有一个node节点

刚开始:NODE(h)===》h->.next(NULL)
第一个节点插入: NODE(h)===》h->next(q)(同时把p指向这里)===>q->next(NULL)
也就是说,每次之后:NODE(h)===》h->next(XXX)==》。。。==>p(永远指向最后一个位置)===>p->next(NULL)

后面就是一直在上面链表结构上进行插入,给p->next指向新节点,同时把p换到新节点表示链表最后位置

NODE *creatlist(int a[])
{
    NODE *h,*p,*q;
    int i;

    h=(NODE *)malloc(sizeof(NODE)); //申请头节点 
    h->next=NULL; 

    for(i=0;i<N;i++) //这里是遍历数组 
    {
        //先定义一个节点,往链表中进行插入
        q=(NODE *)malloc(sizeof(NODE));
        q->data=a[i];                                          
        q->next=NULL;    

        //这是链表的最后进行插入的逻辑
        if(h->next==NULL) //h节点是头节点,最终链表头节点标志
        {
            h->next=q;    //这里不要按照你的写法写,单独对每个赋值
                         //如果只有一个节点, 已经创建的节点放在链表最后
            p = q;      //   把p节点指向链表的最后节点位置
        }                                                                              
        else
        {
            p->next=q;  //p指向的是链表最后,在他的next进行连接新节点就好                  
            p=q;       //重新把p指向链表的最后位置
        }
    }
    return h;
}