一段给链表中数据排序的代码,bug调不出来了

一段给链表中数据排序的代码,bug调不出来了。在第16行if (p->data > q->data)这一句提示不合法的内存访问,但是p和q已经声明也初始化了。

 #include  <stdio.h>
 #include  <stdlib.h>
 #define    N    6
 typedef struct node {
   int  data;
   struct node  *next;
 } NODE;
 void fun(NODE  *h)
 { NODE  *p, *q;    int  t;
   p = h;
   while (p) {
 /**********found**********/
      q = h->next ;
 /**********found**********/
      while (p->next)
      {  if (p->data > q->data)
        {  t = p->data;  p->data = q->data;  q->data = t;  }
        q = q->next;
     }
 /**********found**********/
     p = q ;
   }
 }
 NODE *creatlist(int  a[])
{  NODE  *h,*p = NULL,*q;        int  i;
    h=NULL;
    for(i=0; i<N; i++)
    {  q=(NODE *)malloc(sizeof(NODE));
       q->data=a[i];
       q->next = NULL;
       if (h == NULL)  h = p = q;
       else    {  p->next = q;  p = q;   }
    }
    return  h;
 }
 void outlist(NODE  *h)
 {  NODE  *p;
    p=h;
    if (p==NULL)  printf("The list is NULL!\n");
    else
    {  printf("Head  ");
       do
       {  printf("->%d", p->data); p=p->next;  }
       while(p!=NULL);
       printf("->End\n");
   }
 }
 int main()
 {  NODE  *head;
    int  a[N]= {0, 10, 4, 2, 8, 6 };
    head=creatlist(a);
    printf("The original list:\n");
    outlist(head);
    fun(head);
    printf("\nThe list after sorting :\n");
    outlist(head);
 return 0;
 }

while (p->next) //一次循环找到1个最小值
{ if (p->data > q->data)
{ t = p->data; p->data = q->data; q->data = t; }
p=q; //p后移一个,不更新p导致死循环 段错误
q = q->next;//q后移一个
}
/**********found**********/
h= h->next; p=h; //下一次循环的初始位置

fun函数重写了,第一层循环,用来控制遍历次数。
第二层循环进行比较,找到大小关系。

void fun(NODE  *h)
{ 
    NODE  *p, *q;
    int  t;

    while(h != NULL)
    {   
        p = h;
        q = h->next;

        while(p != NULL && q != NULL)
        {
            if (p->data > q->data)
            {
                t = p->data;
                p->data = q->data;
                q->data = t;
            }
            p = q;
            q = q->next;
        }
        h = h->next;
    }
}