嵌套链表创建求助:类与学生链表的插入逻辑实现问题
问题分析与修正方案
你的代码存在多个逻辑错误,导致嵌套链表的插入逻辑完全失效,下面是核心问题点和修正后的完整实现:
核心问题清单
- 内存分配错误:
malloc(sizeof(struct nodeClass*))分配的是指针大小,而非结构体本身的大小,会导致内存溢出。 - 条件判断错误:用赋值运算符
=代替比较运算符==,导致班级判断完全错误。 - 班级节点重复创建:每个学生都新建一个班级节点,而非复用已存在的班级节点。
- 学生链表未维护有序性:没有实现按成绩降序、同分学号升序的插入逻辑。
- 空指针访问风险:当班级链表为空时,直接访问
head->next会触发崩溃。 - 未定义变量与语法错误:
temp->classID=i;中的i未定义,函数参数、循环语法不完整。
修正后的完整代码
头文件(function.h)
#include <stdio.h> #include <stdlib.h> // 学生节点结构体 struct nodeStudent { int studentID; int midterm; struct nodeStudent *next; }; // 班级节点结构体 struct nodeClass { int classID; double classMidtermAverage; struct nodeClass *next; struct nodeStudent *studentPtr; }; // 插入学生到对应班级的有序链表 void insert(struct nodeClass **head, int id, int midterm); // 计算各班平均分 void computeClassAverage(struct nodeClass *head); // 打印所有班级和学生信息 void printAll(struct nodeClass *head);
函数实现文件(function.c)
#include "function.h" // 辅助函数:根据学生ID获取班级ID(66开头=1,77=2,88=3,99=4) int getClassID(int studentID) { long classCode = studentID; // 提取前两位数字 while (classCode >= 100) { classCode /= 10; } switch ((int)classCode) { case 66: return 1; case 77: return 2; case 88: return 3; case 99: return 4; default: return -1; // 无效班级 } } // 辅助函数:将新学生插入到班级的有序学生链表(降序,同分学号小的在前) struct nodeStudent* insertStudent(struct nodeStudent *studentHead, int id, int midterm) { struct nodeStudent *newNode = (struct nodeStudent*)malloc(sizeof(struct nodeStudent)); newNode->studentID = id; newNode->midterm = midterm; newNode->next = NULL; // 空链表直接插入 if (studentHead == NULL) { return newNode; } struct nodeStudent *prev = NULL; struct nodeStudent *curr = studentHead; // 找到插入位置:成绩更高,或成绩相同但学号更小 while (curr != NULL && (curr->midterm > midterm || (curr->midterm == midterm && curr->studentID < id))) { prev = curr; curr = curr->next; } // 插入到链表头部 if (prev == NULL) { newNode->next = studentHead; return newNode; } // 插入到中间或尾部 prev->next = newNode; newNode->next = curr; return studentHead; } // 主插入函数:找到或创建班级节点,插入学生 void insert(struct nodeClass **head, int id, int midterm) { int classID = getClassID(id); if (classID == -1) { printf("无效学生ID:%d\n", id); return; } struct nodeClass *classNode = NULL; struct nodeClass *currClass = *head; // 查找已存在的班级节点 while (currClass != NULL) { if (currClass->classID == classID) { classNode = currClass; break; } currClass = currClass->next; } // 班级不存在则创建新节点 if (classNode == NULL) { classNode = (struct nodeClass*)malloc(sizeof(struct nodeClass)); classNode->classID = classID; classNode->classMidtermAverage = 0.0; classNode->studentPtr = NULL; classNode->next = NULL; // 将新班级节点加入班级链表(头部插入) if (*head == NULL) { *head = classNode; } else { classNode->next = *head; *head = classNode; } } // 将学生插入到班级的有序学生链表 classNode->studentPtr = insertStudent(classNode->studentPtr, id, midterm); } // 计算各班平均分 void computeClassAverage(struct nodeClass *head) { struct nodeClass *currClass = head; while (currClass != NULL) { int totalScore = 0; int studentCount = 0; struct nodeStudent *currStudent = currClass->studentPtr; while (currStudent != NULL) { totalScore += currStudent->midterm; studentCount++; currStudent = currStudent->next; } if (studentCount > 0) { currClass->classMidtermAverage = (double)totalScore / studentCount; } else { currClass->classMidtermAverage = 0.0; } currClass = currClass->next; } } // 打印所有信息 void printAll(struct nodeClass *head) { struct nodeClass *currClass = head; while (currClass != NULL) { printf("班级ID:%d,期中平均分:%.2f\n", currClass->classID, currClass->classMidtermAverage); printf("学生列表(按成绩降序):\n"); struct nodeStudent *currStudent = currClass->studentPtr; while (currStudent != NULL) { printf("学号:%d,成绩:%d\n", currStudent->studentID, currStudent->midterm); currStudent = currStudent->next; } printf("-------------------------\n"); currClass = currClass->next; } }
主函数文件(main.c)
#include "function.h" int main() { struct nodeClass *head = NULL; int id, midterm; printf("请输入学生ID和期中成绩(输入-1结束):\n"); scanf("%d", &id); while(id != -1) { scanf("%d", &midterm); insert(&head, id, midterm); scanf("%d", &id); } computeClassAverage(head); printAll(head); // 注意:实际使用时需要添加内存释放逻辑,避免内存泄漏 return 0; }
关键逻辑说明
- 班级节点管理:每次插入学生时先查找对应班级,不存在则创建并加入班级链表,避免重复创建。
- 学生链表有序插入:通过遍历找到符合「成绩降序、同分学号升序」的插入位置,保证链表始终有序。
- 平均分计算:遍历每个班级的学生链表,累加总分和人数后计算平均值。
- 错误处理:对无效学生ID进行提示,避免程序崩溃。
内容的提问来源于stack exchange,提问作者userozz
相关产品推荐
相关产品推荐

