动态链表的创建:
#include <stdio.h>
#include <malloc.h>
#define NULL 0
#define LEN sizeof(struct student)
struct student
{
int num;
float score;
struct student *next;
};
int n; //n位结点总个数,被定义为全局变量,可被其他函数使用
struct student *creat(void) //函数无形参
{
struct student *head,*p1,*p2;
head=NULL; //头指针置空
n=0; //计数器清零
p1=p2=(struct student *)malloc(LEN); //p1,p2同时指向第一个结点
scanf("\t%d,%f",&p1->num,&p1->score); //输入第一个结点的数据
while(p1->num!=0) //以学生学号为例,学号为0时结束循环
{
n=n+1;
if(n==1)
head=p1; //若p1所指结点为第一个结点,头指针指向他,及链接到表头
else
p2->next=p1; //否则令表尾指针指向它,及链接到表尾
p2=p1; //p2指向新表尾
p1=(struct student *)malloc(LEN);//申请一个新结点空间,p1指向它
scanf("%d,%f",&p1->num,&p1->score);//输入新结点数据
}
p2->next=NULL; //最终表尾结点的指针域置空
free(p1); //释放p1指向的内存空间
return(head); //返回头指针
}
上述为动态链表的创建,申请空间,传入数据,继续开辟空间直到满足条件,释放空间,返回头指针的过程。
动态链表的输出:
#include <stdio.h>
void print(struct student *head) //函数的形参head值为实参传来的链表的头指针,及上个创建链表函数的返回值;
{
struct student *p;
printf("共有%d条学生记录,包括:\n",n); //n为全局变量
p=head;
while(p!=NULL)
{
printf("\t%d\t%1.f\n",p->num,p->score);
p=p->next;
}
}
说明:head的值是由实参传过来的,也就是将已有链表的头指针传给print函数,在函数中从head所指的第一个结点出发顺序输出各个结点。
删除链表的结点:
#include <stdio.h>
struct student *del(struct student *head,int num)
{
struct student *p1,*p2;
if(head==NULL)
{
printf("\nThe List is NULL!\n");
return(head);
}
p1-head; //p1指向第一个结点
while(p1->num!=num && p1->next!=NULL) //p1所指向的结点不是要删除的结点,也不是尾结点
{
p2=p1; //p2移到p1位置即p2后移一个结点
p1=p1->next; //p1后移一个结点
}
if(p1->num==num) //找到要删除的结点
{
if(p1==head)
head=p1->next; //若p1指向第一个结点,则令head指向第二个结点
else
p2->next=p1->next; //否则令其前一个结点的next指针指向其后一个结点
free(p1); //释放p1所指结点空间
printf("Delete:%d\n",num); //输出删除的数据
n=n-1; //结点数减1
}
else
printf("%d is not been found!\n",num); //找不到该结点,输出提示信息
return(head);
}
插入链表结点:
#include <stdio.h>
struct student *insert(struct student *head,struct student *stud);
{
struct student *p0,*p1,*p2;
p1=head; //p1指向第一个结点
p0=stud; //p0指向新结点
if(head==NULL) //原链表为空
{
head=p0; //新结点作为第一个结点
p0->next=NULL;
}
else
{
while((p0->num>p1->num) && (p1->next!=NULL)) //新结点数据大于当前结点数据并且当前结点不是尾结点
{
p2=p1; //p2后移一个结点
p1=p1->next; //p1后移一个结点
}
if(p0->num<=p1->num) //新结点数据小于等于当前结点数据
{
if(head==p1)
head=p0; //新结点插到原来的一个结点之前
else
p2->next=p0; //新结点插到p2所指结点之后
p0->next=p1; //新结点next指针指向当前结点
}
else
{
p1->next=p0; //新结点插到表尾结点之后
p0->next=NULL;
}
}
n=n+1; //结点数加1
return(head);
}
链表的综合操作
void main()
{
struct stuent *head,*stu;
int del_num;
printf("请输入记录:\n");
head=creat(); //调用函数建立链表
printf(head); //调用函数输出链表
printf("请输入删除的记录编号:");
scanf("%d",&del_num);
while(del_num!=0)
{
head=del(head,del_num); //调用函数删除链表中指定字节
print(head);
printf("请输入删除的记录编号:");
scanf("%d",&del_num);
}
printf("请输入要插入的记录:\n");
stu=(struct student *)malloc(LED);
scanf("%d,%f",&stu->num,&stu->score);
while(stu->num!=0)
{
head=insert(head,stu);
print(head);
printf("请输入要插入的记录:");
stu=(struct student *)malloc(LEN);
scanf("%d,%f",&stu->num,&stu->score);
}
}