C语言数据结构链表大作业


一、什么是数组、顺序表与链表

首先一定要分清楚什么是数组、顺序表与链表,学习C语言的小伙伴一般都是先进入数组的学习再进行结构体,C语言大作业多采用了结构体数组来构建学生信息数据库,在数据结构中则采用了顺序表或链表的形式,对于很多学习过数据结构的同学仍然无法分清楚这三者的关系,今天我们以三段代码来讲解。

1、数组

如下图所示代码,构建了一个学生结构体,包含学号、姓名、数学、语文、英语,定义出三个学生结构体,后续只要对三个数组进行调用修改即可,使用较为简便,缺点:因为不知道实际的学生数量,如果多定义则占用内存空间,少定义则很难再去添加。

typedef struct student
{
	char num[10];
	char name[10];
	int math;
	int chinese;
	int english;
}STU;

STU a[3];

2、顺序表

先来看一个普通的顺序表,如下图,可以发现如果不对datatype予以结构体定义,其可存储的数据类型非常有限,因此加上单个学生的结构体定义后,可使用的灵活性增加,但是本人以为顺序表和结构体数组似乎并无很大的区别,不过是对学生的数量及所有个体进行封装在一个结构体内,其大小也无法改变,虽然书中有对顺序表的插入与删除,可深追后发现,其实并没有增加或删除内存而仅仅进行赋值与删值,因此如果你追求数据结构有个更好的成绩,我推荐你使用链表。

#define max 100
typedef struct
{
	char name[10];
	char num[10];
	int english;
	int math;
}datatype;
typedef struct
{
	datatype a[max];
	int size;
}STU;

3. 链表

直接看代码,构建一个学生结构体,不同于之前,里面多了一个next指针,通过尾插、头插法可以构建一个链表,优点:可以动态增加或减少学生数量,占用内存为合理化,缺点:构建较为麻烦。

typedef struct student
{
	char name[10];
	char num[10];
	int english;
	int math;
	struct student* next;
}STU;

二、使用链表的大作业分析

1.下文所讲解的代码问题

对一个学生成绩表实现添加、修改、删除和排序和查找的功能
要求:
(1)分析需求,写出用到的数据结构;
(2)对排序(如冒泡法,其他快速算法)和查找(如顺序查找,二分查找)写出算法描述;
(3)排序按分数由高到低,查找按姓名;

2.需求分析与方法介绍及实现的代码

  1. 构建单链表存储学生各项信息:
    我采用的方法是带头结点的链表,初始化采用尾插法进行构建
    首先构建学生结构体与指向下一个学生的指针
typedef struct student
{
	char stuid[16];//学号
	char name[16];//学生姓名
	int score;//学生成绩
	struct student* next;//指向下一个学生的指针
}Stu;

接下来尾插法构建带头结点的学生链表

/*通过尾插法,建立一个带头结点的学生链表*/
Stu* init()
{
	Stu* head;                          //构建头结点
	head = (Stu*)malloc(sizeof(Stu));
	head->next = NULL;
	Stu* p;
	p = head;
	Stu* q;
	printf("请输入学生个数:");
	int i;
	scanf("%d", &i);
	printf("学号          姓名    成绩\n");
	while (i--)
	{
		q = (Stu*)malloc(sizeof(Stu));
		scanf("%s", &q->stuid);
		scanf("%s", &q->name);           //扫描很多的学生信息
		scanf("%d", &q->score);
		p->next = q;
		p = q;
	}
	p->next = NULL;
	return head;
}

运行所需的键盘输入如图所示
输入学生的信息


  1. 对学生成绩查找,从而添加删除与修改:
    添加采用:通过顺序查找查找要添加到位置,注:对头结点插入与其他结点不太相同;删除采用:free结点,构建链表使用动态内存分配,只需要链接新的结点后再删除原结点即可;修改时采用:顺序查找,先找到该结点,再进行修改学生信息。
/*对学生信息查找*/
Stu* find(Stu* head, char a[])
{
	Stu* p = head->next;
	while (p && (strcmp(p->name, a) != 0))
		p = p->next;
	if (p)
		return p;
	return NULL;
}
/*对学生信息进行插入操作*/
void* insert(Stu* head, char a[])
{
	Stu* q, * p;
	q = find(head, a);
	if (!q)
	{
		printf("未查找到该学生,无法进行插入操作\n");
	}
	else
	{
		p = (Stu*)malloc(sizeof(Stu));
		printf("请依次输入要插入的学生的学号、姓名、成绩:");
		scanf("%s %s %d", p->stuid, p->name, &(p->score));
		p->next = q->next;
		q->next = p;
		printf("插入成功,进行更新后,学生信息如下:\n");
		display(head);
	}
}//此函数只能实行对非头位置的插入操作

/*对学生信息进行插入操作*/
void* inser(Stu* head)
{
	Stu* p;
	p = (Stu*)malloc(sizeof(Stu));
	printf("请依次输入要插入的学生的学号、姓名、成绩:");
	scanf("%s %s %d", p->stuid, p->name, &(p->score));
	p->next = head->next;
	head->next = p;
}//此函数只能实行对头位置的插入操作

/*对学生信息进行修改操作*/
void* alter(Stu* head, char a[])
{
	Stu* q;
	q = find(head, a);
	if (q)
	{
		printf("请输入要修改的学生的新的信息,即顺序输入学号、姓名、成绩:");
		scanf("%s %s %d", q->stuid, q->name, &(q->score));
		printf("修改成功,进行更新后,学生信息如下:\n");
		display(head);
	}
	else
		printf("未查找到该学生,修改失败,");
}

/*对学生信息进行删除操作*/
Stu* delet(Stu* head, char a[])
{
	Stu* q;
	Stu* pre = head;
	q = head->next;
	while (q && (strcmp(q->name, a) != 0))
	{
		pre = q;
		q = q->next;
	}
	if (q)
	{
		pre->next = q->next;
		free(q);
		printf("删除成功,进行更新后,学生信息如下:\n");
		display(head);
	}
	else
		printf("未查找到该学生,删除失败,");
}

当然由于比较菜,我对插入学生的部分写了两个函数,分别为插入头结点与其他节点的,其实可以放一起的整合在一个函数,就教给大家拓展啦。


  1. 排序
    采用冒泡排序法,通过不断更新尾结点位置(每次最小值排到最后,即尾结点向前移动一位),每次从头位置(非头结点)进行排序到新的尾结点,即可完成排序。
/*对学生进行成绩排序*/
void C_sort(Stu* p)
{
	Stu* begin = p->next;
	Stu* end = NULL;
	char a[16];//中间变量用于交换
	int b;//中间变量用于交换
	while (p->next->next != end)
	{
		while (begin->next != end)              //冒泡排序法
		{
			if (begin->score < begin->next->score)
			{
				strcpy(a, begin->name);
				strcpy(begin->name, begin->next->name);
				strcpy(begin->next->name, a);/* 以上为对名字交换*/
				strcpy(a, begin->stuid);
				strcpy(begin->stuid, begin->next->stuid);
				strcpy(begin->next->stuid, a);/* 以上为对学号交换*/
				b = begin->score;
				begin->score = begin->next->score;
				begin->next->score = b;
			}
			begin = begin->next;
		}
		end = begin;
		begin = p->next;
	}
}


4.特殊说明:本程序含报错功能,即如果所输入的学生姓名不在学生系统存储,程序会进行报错,告诉“使用者”,未查找到该学生。在运行结果处,进行了测试。

三、总结

程序的主函数没有开放给大家,其实函数块都写好后,主函数不过是进行多级调用与循环,如果想显得逼格高一点,可以适当加一些配字与程序报错功能,例如下图。
在这里插入图片描述
如果想获取整个程序及使用方法的可以点击下方链接,我把报告进行了打包,含有代码与使用说明

C语言数据结构链表大作业实现

  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌夏微秋

希望各位多多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值