您的位置:首页 > 编程语言 > C语言/C++

链表基本操作的C语言简单实现

2018-02-09 15:51 761 查看
        实现动态单向链表的基本操作,包括新建、输出、删除、插入。
        浅显易懂,方便初学者模仿。//构建存放学生信息的单向动态链表
#include<stdio.h>
#include<malloc.h>
#define NULL 0
#define LEN sizeof(struct student) //用来计算结构体所占空间的大小
struct student
{
long num;
float score;
struct student * next;
};
int n; //全局变量n用来统计链表中的节点个数,初值为0.

struct student * creat(void) //定义一个函数,功能是创建动态链表,返回值是一个指向student类型的结构体的指针
{
struct student * head; //定义头指针
struct student * p1,* p2;
head = NULL; //头结点的初始化
n = 0; //开始的时候链表为空
p1 = ( struct student * )malloc(LEN); //malloc函数用来开辟第一个大小为student结构体的大小的内存空间,其返回值是(不指向任何类型数据的指针),所以要进行强制类型转换,变成和p1,p2一样的类型
p2 = p1; //这里必须要给p2也赋值,不然不能实现空链表的正常创建
scanf("%ld %f",&p1->num,&p1->score); //先接收第一个节点的数据
while(p1->num != 0) //必须合法的num才需要新建节点
{
n = n + 1;
if(n == 1) //这里判断是不是第一个节点
head = p1;
p2 = p1; //保留p1的指向,head之后会固定不变,所以用p2来跟随p1
p1 = ( struct student * )malloc(LEN); //新开辟内存单元
p2->next = p1;
scanf("%ld %f",&p1->num,&p1->score); //输入下一个节点的信息
}
p2->next = NULL;
return(head);
}

void print(struct student *head) //输出链表的函数
{
struct student * p;
if(head != NULL)
{
p = head;
do
{
printf("%ld %.2f\n",p->num,p->score);
p = p->next;
}while(p != NULL);
}
else
printf("Nothing.\n");
}

struct student * del(struct student * head,long num) //用来删除对应学校的学生
{
struct student *p1,*p2;
if(head == NULL) //空链表时
{
printf("This is an empty list.\n");
return(head);
}
else //链表非空的时候
{
p1 = head;
while(p1->num != num && p1->next != NULL) //寻找num对应的结点,直至找到或者遍历完整个链表
{
p2 = p1; //p2一直指向的是之后的p1的前一个结点
p1 = p1->next;
}
if(p1->num == num) //找到了,即使是最后一个结点才找到
{
if(head->num == num) //找到的是头结点
head = p1->next;
else
{
p2->next = p1->next;
}
printf("\ndelete:%ld\n",num);
n = n-1;
}
else //找遍了,却找不到的时候
printf("not found.\n");
}
return(head);
}

struct student * in(struct student * head,struct student * stud) //用来按照学号的由小到大的顺序插入对应学生
{
struct student *p0,*p1,*p2;
p1 = head;
p0 = stud;
if(head == NULL) //链表为空,插入到队首
{
head = p0;
p0->next = NULL;
}
else
{
while((p0->num > p1->num) && (p1->next != NULL)) //在队中寻找适当的位置,找到或者适当的位置在表尾,之后退出
{
p2 = p1; //保留上一个位置
p1 = p1->next;
}
if(p0->num <= p1->num) //找到了这个元素的适当位置
{
if(head == p1) //如果这个适当的位置在表首
{
head = p0;
p0->next = p1;
}
else //在表中的时候
{
p2->next = p0;
p0->next = p1;
}
}
else //需要放到表尾的时候
{
p1->next = p0;
p0->next = NULL;
}
}
n = n + 1;
return(head);
}

void main()
{
struct student * p,*p1;
long num;
int over,ok;
struct student stud; //用来存放刚刚插入的结点的信息,不能是指针,因为定义指针没有开辟内存空间

//新建
p = creat();

//输出
printf("数据如下:\n");
print(p);
printf("结点个数是%d\n",n);

//删除
printf("If you want to delete a point,Please input 1:\nIf not,input 0:\n");
scanf("%d",&over);
do
{
printf("Please input the number of the student you want to delete:\n");
scanf("%ld",&num);
p = del(p,num);
printf("\nAfter deleting:\n");
print(p);
printf("此时结点个数是%d\n",n);
printf("If you want to delete a point,Please input 1:\nIf not,input 0:\n");
scanf("%d",&over);
}while(over == 1);

//插入
printf("If you want to insert a point,Please input 1:\nIf not,input 0:\n");
scanf("%d",&ok);
do
{
printf("Please input the number of the student you want to insert:\n");
scanf("%ld %f",&stud.num,&stud.score);
p1 = &stud; //取一个结构体的初始地址
p = in(p,p1);
printf("\nAfter inserting:\n");
print(p);
printf("此时结点个数是%d\n",n);
printf("If you want to insert a point,Please input 1:\nIf not,input 0:\n");
scanf("%d",&ok);
}while(ok == 1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: