单链表(一)——链表的建立

建立单链表有两种方法:头插法和尾插法。

1、头插法建立单链表

1.1、基本思想

1.生成一个结点,将读入的数据存放到新结点的数据域中;

2.把新结点作为第一个表结点插到当前链表头结点之后,重复上述过程,直至输入结束标志为止。

1.2、头插法建立单链表的过程(示意图如下图所示)

1.建立链表的头结点head;

2.建立新的结点p;

3.给新节点的数据域赋值,将新结点的指针域指向head所指的结点;

4.将链表头结点head的指针域修改为新结点p;

5.重复2~4,直至输入结束标志为止。


1.3、算法实现

/*********************************************************************
* 函数名称:linklist *CreateLinklistHead()
* 函数功能:利用头插法创建链表
* 参    数:无
* 返 回 值:创建完链表后的链表头结点
* 说    明:无
*********************************************************************/
linklist *CreateLinklistHead()
{
	int x, i, nodeNum;
	linklist *head, *temp;  // 头结点与临时结点
	head = (linklist *)malloc(sizeof(linklist));  // 生成表头结点
	head->next = NULL;   // 给表头结点的指针域赋值
	printf("请输入链表中结点的个数:");
	scanf("%d", &nodeNum);
	for(i=1; i<=nodeNum; i++)
	{
		printf("请输入第 %d 个结点的数据:", i);
		scanf("%d", &x);
		temp = (linklist *)malloc(sizeof(linklist));  // 生成新的结点
		temp->data = x;    // 对新结点的数据域赋值
		// 将新结点插到头结点之后
		temp->next = head->next; 
		head->next = temp;
	}
	return head;  // 返回新建链表的头结点
}


2、尾插法建立单链表

2.1、基本思想

1.生成一个结点,将读入的数据存放到新结点的数据域中;

2.把新结点作为第一个表结点插到当前链表尾结点之后,重复上述过程,直至输入结束标志为止。

2.2、尾插法建立单链表的过程(示意图如下图所示)

1.建立链表的头结点head;

2.建立新的结点p;

3.给新节点的数据域赋值;

4.将新结点链接到链表的尾结点rear之后,修改为指针rear;

5.重复2~4,直至输入结束标志为止。


2.3、算法实现

/*********************************************************************
* 函数名称:linklist *CreateLinklistRear()
* 函数功能:利用尾插法创建链表
* 参    数:无
* 返 回 值:创建完链表后的链表头结点
* 说    明:无
*********************************************************************/
linklist *CreateLinklistRear()
{
	int x, i, nodeNum;
	linklist *head, *rear, *temp;  // 定义头结点、尾结点和临时结点
	head = (linklist *)malloc(sizeof(linklist));  // 生成表头结点,表头结点不存放数据
	head->next = NULL;  // 将表头结点的指针域赋值为NULL
	rear = head;  // 将表头结点赋值给表尾结点
	printf("请输入链表中结点的个数:");
	scanf("%d", &nodeNum);
	for(i=1; i<=nodeNum; i++)
	{
		printf("请输入第 %d 个结点的数据:", i);
		scanf("%d", &x);
		temp = (linklist *)malloc(sizeof(linklist));  // 生成新的结点
		temp->data = x;   // 新增结点的数据域
		temp->next = NULL; // 新增结点的指针域(由于是尾插法,所以插入的结点都在尾部,即指针域为NULL)
		rear->next = temp; // 使前一个结点指向新增结点(head->next=temp)
		rear = temp;  // 将新增结点赋值给尾结点(尾插法,插入的结点在尾部)(rear=head->next)
	}
	//rear->next = NULL;  // 将尾结点的指针域赋值为空(为了方便检验链表是否为空链表)
	return head;  // 返回头结点
}

学生成绩管理系统可以使用链表法来进行设计,链表是一种常用的数据结构,可以方便地实现插入、删除、查找等操作。下面是使用链表法实现学生成绩管理系统的思路: 1. 定义链表节点结构体,包括学生信息和成绩等数据成员,同时定义指向下一个节点的指针。 ``` struct Node { char no[10]; // 学号 char name[20]; // 姓名 char sex[10]; // 性别 char class[20]; // 班级 float chinese; // 语文成绩 float math; // 数学成绩 float english; // 英语成绩 float physics; // 物理成绩 float chemistry; // 化学成绩 float biology; // 生物成绩 float total; // 总分 float average; // 平均分 int rank; // 排名 struct Node *next; // 指向下一个节点的指针 }; ``` 2. 创建链表,包括初始化链表头节点、添加节点等操作。 ``` struct Node *head = NULL; // 链表头节点 // 初始化链表头节点 head = (struct Node*)malloc(sizeof(struct Node)); strcpy(head->no, ""); strcpy(head->name, ""); strcpy(head->sex, ""); strcpy(head->class, ""); head->chinese = 0; head->math = 0; head->english = 0; head->physics = 0; head->chemistry = 0; head->biology = 0; head->total = 0; head->average = 0; head->rank = 0; head->next = NULL; // 添加节点 struct Node *p = NULL; // 新节点 p = (struct Node*)malloc(sizeof(struct Node)); strcpy(p->no, "20210101"); strcpy(p->name, "张三"); strcpy(p->sex, "男"); strcpy(p->class, "2021"); p->chinese = 90; p->math = 80; p->english = 85; p->physics = 75; p->chemistry = 80; p->biology = 70; p->total = p->chinese + p->math + p->english + p->physics + p->chemistry + p->biology; p->average = p->total / 6.0; p->rank = 1; p->next = head->next; head->next = p; ``` 3. 实现学生成绩管理系统的各个功能模块,包括录入学生信息和成绩、计算学生成绩、查询学生成绩、修改学生成绩、删除学生成绩、统计学生成绩等。 ``` // 录入学生信息和成绩 void add_student() { struct Node *p = NULL; // 新节点 p = (struct Node*)malloc(sizeof(struct Node)); printf("请输入学号:"); scanf("%s", p->no); printf("请输入姓名:"); scanf("%s", p->name); printf("请输入性别:"); scanf("%s", p->sex); printf("请输入班级:"); scanf("%s", p->class); printf("请输入语文成绩:"); scanf("%f", &p->chinese); printf("请输入数学成绩:"); scanf("%f", &p->math); printf("请输入英语成绩:"); scanf("%f", &p->english); printf("请输入物理成绩:"); scanf("%f", &p->physics); printf("请输入化学成绩:"); scanf("%f", &p->chemistry); printf("请输入生物成绩:"); scanf("%f", &p->biology); p->total = p->chinese + p->math + p->english + p->physics + p->chemistry + p->biology; p->average = p->total / 6.0; p->rank = 1; p->next = head->next; head->next = p; } // 计算学生成绩 void calculate_score() { struct Node *p = head->next; while(p != NULL) { p->total = p->chinese + p->math + p->english + p->physics + p->chemistry + p->biology; p->average = p->total / 6.0; p = p->next; } } // 查询学生成绩 void search_score() { char no[10]; printf("请输入要查询的学生学号:"); scanf("%s", no); struct Node *p = head->next; while(p != NULL) { if(strcmp(p->no, no) == 0) { printf("学号:%s\t姓名:%s\t性别:%s\t班级:%s\n", p->no, p->name, p->sex, p->class); printf("语文:%5.1f\t数学:%5.1f\t英语:%5.1f\t物理:%5.1f\t化学:%5.1f\t生物:%5.1f\n", p->chinese, p->math, p->english, p->physics, p->chemistry, p->biology); printf("总分:%5.1f\t平均分:%5.1f\t排名:%d\n", p->total, p->average, p->rank); return; } p = p->next; } printf("未找到该学生!\n"); } // 修改学生成绩 void modify_score() { char no[10]; printf("请输入要修改的学生学号:"); scanf("%s", no); struct Node *p = head->next; while(p != NULL) { if(strcmp(p->no, no) == 0) { printf("请输入修改后的语文成绩:"); scanf("%f", &p->chinese); printf("请输入修改后的数学成绩:"); scanf("%f", &p->math); printf("请输入修改后的英语成绩:"); scanf("%f", &p->english); printf("请输入修改后的物理成绩:"); scanf("%f", &p->physics); printf("请输入修改后的化学成绩:"); scanf("%f", &p->chemistry); printf("请输入修改后的生物成绩:"); scanf("%f", &p->biology); p->total = p->chinese + p->math + p->english + p->physics + p->chemistry + p->biology; p->average = p->total / 6.0; return; } p = p->next; } printf("未找到该学生!\n"); } // 删除学生成绩 void delete_score() { char no[10]; printf("请输入要删除的学生学号:"); scanf("%s", no); struct Node *p1 = head->next; struct Node *p2 = head; while(p1 != NULL) { if(strcmp(p1->no, no) == 0) { p2->next = p1->next; free(p1); printf("删除成功!\n"); return; } p2 = p1; p1 = p1->next; } printf("未找到该学生!\n"); } // 统计学生成绩 void statistics_score() { float chinese_sum = 0, math_sum = 0, english_sum = 0, physics_sum = 0, chemistry_sum = 0, biology_sum = 0; int count = 0, pass_count = 0, excellent_count = 0; struct Node *p = head->next; while(p != NULL) { chinese_sum += p->chinese; math_sum += p->math; english_sum += p->english; physics_sum += p->physics; chemistry_sum += p->chemistry; biology_sum += p->biology; count++; if(p->total >= 60) { pass_count++; } if(p->total >= 90) { excellent_count++; } p = p->next; } printf("班级语文平均分:%5.1f\t数学平均分:%5.1f\t英语平均分:%5.1f\t物理平均分:%5.1f\t化学平均分:%5.1f\t生物平均分:%5.1f\n", chinese_sum/count, math_sum/count, english_sum/count, physics_sum/count, chemistry_sum/count, biology_sum/count); printf("班级及格率:%5.1f%%\t班级优秀率:%5.1f%%\n", pass_count*100.0/count, excellent_count*100.0/count); } ``` 以上是使用链表法实现学生成绩管理系统的思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值