链表在C语言中很重要,本文所设计的链表,以一个经典的存储学生学号和成绩的结构体作为例子,具
体的结构体如下:
struct student
{
int num;
float socre;
struct student *next;
};
首先建立一个链表,具体函数如下:
#define <malloc.h> //使用malloc函数需要包含的头文件
#define NULL 0
#define LEN sizeof(struct student)
typedef struct student stu
struct student
{
long num;
float socre;
struct student *next;
}; //
注意不要忘记定义结构体大括号最后要有一个“;”
int n; //n为全局变量,本文件模块中其他函数均可使用它
stu *creat(void)
{
stu *head;
stu *p1,*p2;
n=0;
p1=p2=(struct student *)malloc(LEN);
scanf("%ld,%ld",&p1->num,&p1->socre);
head=NULL;
while(p1->num!=0)
{
n+=1;
if(n==1)
head=p1; //输入第一个元素
else
p2->next=p1; //与下一个链接
p2=p1;
p1=(stu *)malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score);
}
p2->next=NULL;
return(head);
}
输出链表:
void print(stu *head)
{
stu *p;
printf("\nNow,These %d records are:\n",n);
p=head;
if(head!=NULL)
do
{
printf("%ld %5.1f\n",p->num,p->socre);
p=p->next;
}while(p!=NULL);
}
删除链表:
stu *del(stu *head,long num)
{
stu *p1,*p2;
if(head==NULL)
{printf("\nlist null! \n");goto end;}
p1=head;
while(num!=p1->num&&p1->next!=NULL) //*p1指向的不是所要找的节点,并且后面还有节点
{p2=p1;p1=p1->next;} //p1后移一个节点
if(num==p1->num) //找到了
{
if(p1==head)
head=p1->next; //若p1指向的是首节点,把第二个节点地址赋予head
else
p2->next=p1->next; //否则讲下一节点地址赋给前一节点地址
printf("delete:%ld\n",num);
}
else if(p1->num==num&&p1->next==NULL)
p2->next=NULL;
else printf("%ld not been found! \n",num); //找不到该节点
n-=1;
return (head);
}
增加一个节点:
stu *insert(stu *head,stu *shu)
{
stu *p0,*p1,*p2; //p0指向待插入的节点,即shu,p1指向待检测节点,p2指向待检测前一个节点
p0=shu;
p1=head;
while(p0->num>p1->num)
{
p2=p1;
p1=p1->next;
}
if(p0->num<=p1->num&&p1->next!=NULL) //找到待插入的节点,并且该节点不是最后一个节点
{
if(p1==head) //如果需要插入在首节点
{
p0->next=p1;
head=p0;
}
else
{
p2->next=p0;
p0->next=p1;
}
}
else (p0->num<=p1->num&&p1-next==NULL) //待插入的节点为尾节点
{
p1->next=p0;
p0->next=NULL;
}
n+=1;
return (head);
}
将一个链表逆序:
char *convet(char * head)
{
char *p,*q,*temp;
p=head;
if(p->next==NULL)
return head;
q=p->next;
while(q->next!=NULL)
{
temp=q->next;
q->next=p;
p=q; //这两条语句完成位置更换,为下一次逆序做准备
q=temp;
}
head=q;
retrun head;
}