链表删除(初学者)

链表删除(菜鸟求救)
struct student * del(struct student *head,long n)
{
  struct student *p1,*p2;
  p1=(struct student*)malloc(sizeof(struct student)); //开辟第一个结点,使p1指向它
  //head=p1;
  scanf("%d",&n);
  if (head!=NULL) //判断链表是否为空
  {
head=p1=p2;
if (p1->num==n) //判断是否是第一个结点
{
  head=p1->next; //删除第一个结点,head 指向第二个结点
}
else
{
  while(p1->next!=NULL)  

  if (p1->num==n)
  p2->next=p1->next; //将后一个结点地址给前一个结点
else
  p1=p1->next; //p1后移一个结点  
}
}
  }
  else
printf("无此链表");
  return head;
}
刚接触链表这一块 自己写的链表删除代码 着实看的别扭 太烂了 能帮忙看看可有什么该进之处。
思路:
判断输入的数据是否是第一个结点,若是则将p1->next給head 反之就将删除结点的将后一个结点地址给前一个结点
即p2->next=p1->next

------解决方案--------------------
C/C++ code

struct student
{
    int num;
    struct student* next;
};

struct student * del(struct student *head,long n)
{
    struct student *p1,*p2;
    p1=(struct student*)malloc(sizeof(struct student)); //开辟第一个结点,使p1指向它,不知道申请结点干什么,你的链表有头结点吗?
    //head=p1;
    scanf("%d",&n);
    if (head!=NULL) //判断链表是否为空
    {
        head=p1=p2;                     //这里错了
        if (p1->num==n) //判断是否是第一个结点
        {
            head=p1->next; //删除第一个结点,head 指向第二个结点
        }
        else
        {
            while(p1->next!=NULL)   
            {  
                if (p1->num==n)          //你这里删除了所有num为n的结点,且没有释放内存
                    p2->next=p1->next; //将后一个结点地址给前一个结点
                else
                    p1=p1->next; //p1后移一个结点       
            }
        }
    }
    else
        printf("无此链表");
    return head;
}