|
|
9 months ago | |
|---|---|---|
| README.md | 9 months ago | |
README.md
student
#include #include using namespace std;
#define OK 1 #define ERROR 0
// 定义学生信息结构体 typedef struct Student { int id; // 学号 string name; // 姓名 float score; // 成绩 string gender; // 性别 int age; // 年龄 string major; // 专业 } Student;
// 定义单链表节点结构体 typedef struct LNode { Student data; // 学生数据 struct LNode *next; // 指向下一个节点的指针 } LNode, *LinkList;
// 1. 初始化链表 int InitList(LinkList &L) { L = new LNode; // 创建头节点 L->next = NULL; // 初始化头节点的next指针为NULL return OK; }
// 2. 创建链表(尾插法) void CreateList_R(LinkList &L, int n) { if (n <= 0 || n > 100) { cout << "学生数量应在1-100之间!" << endl; return; }
LinkList r = L;
for (int i = 0; i < n; i++) {
LinkList p = new LNode;
cout << "\n请输入第" << i + 1 << "个学生的数据:" << endl;
cout << "学号: "; cin >> p->data.id;
cout << "姓名: "; cin >> p->data.name;
cout << "成绩: "; cin >> p->data.score;
cout << "性别: "; cin >> p->data.gender;
cout << "年龄: "; cin >> p->data.age;
cout << "专业: "; cin >> p->data.major;
p->next = NULL;
r->next = p;
r = p;
}
cout << "成功创建" << n << "个学生数据!" << endl;
}
// 3. 打印链表 void PrintList(LinkList &L) { if (L->next == NULL) { cout << "学生链表为空!" << endl; return; }
cout << "\n--- 打印学生数据 ---" << endl;
cout << "序号\t学号\t姓名\t成绩\t性别\t年龄\t专业" << endl;
cout << "-----------------------------------------------" << endl;
LinkList p = L->next;
int i = 1;
while (p != NULL) {
cout << i++ << "\t" << p->data.id << "\t"
<< p->data.name << "\t" << p->data.score << "\t"
<< p->data.gender << "\t" << p->data.age << "\t"
<< p->data.major << endl;
p = p->next;
}
}
// 4. 插入学生数据 int ListInsert(LinkList &L, int i, Student stu) { if (i < 1) return ERROR;
LinkList p = L;
int j = 0;
// 查找第i-1个节点
while (p && j < i - 1) {
p = p->next;
j++;
}
if (!p || j > i - 1) return ERROR;
LinkList s = new LNode;
s->data = stu;
s->next = p->next;
p->next = s;
return OK;
}
// 5. 删除学生数据 int ListDelete(LinkList &L, int i) { if (i < 1) return ERROR;
LinkList p = L;
int j = 0; // 位置计数器
// 查找第i-1个节点
while (p->next && j < i - 1) {
p = p->next;
j++;
}
if (!(p->next) || j > i - 1) return ERROR; // 检查是否找到第i-1个节点
LinkList q = p->next;
p->next = q->next; // 第i-1个节点的next指针指向第i+1个节点
delete q; // 释放第i个节点
return OK;
}
// 6. 统计学生数量 int CountStudents(LinkList &L) { int count = 0; LinkList p = L->next; while (p != NULL) { count++; // 每遍历一个节点,计数器加1 p = p->next; // 移动到下一个节点 } return count; }
// 7.1 按姓名直接插入排序 void SortByName(LinkList &L) { if (L->next == NULL || L->next->next == NULL) return;
LinkList sorted = L->next; // 已排序部分的第一个节点
LinkList current = sorted->next; // 当前待排序的节点
while (current != NULL) {
// 如果当前节点的姓名小于已排序部分的第一个节点的姓名
if (current->data.name < L->next->data.name) {
sorted->next = current->next; // 将当前节点从链表中移除
current->next = L->next; // 将当前节点插入到已排序部分的头部
L->next = current;
}
// 否则,将当前节点插入到已排序部分的合适位置
else {
LinkList p = L->next;
while (p != sorted && p->next->data.name < current->data.name) {
p = p->next;
}
if (p != sorted) {
sorted->next = current->next; // 将当前节点从链表中移除
current->next = p->next; // 将当前节点插入到已排序部分的合适位置
p->next = current;
} else {
sorted = current; // 更新已排序部分的尾指针
}
}
current = sorted->next; // 移动到下一个待排序的节点
}
cout << "按姓名排序完成!" << endl;
}
// 7.2 按学号冒泡排序 void SortById(LinkList &L) { if (L->next == NULL || L->next->next == NULL) return;
int swapped; // 用于标记是否发生了交换
LinkList end = NULL; // 冒泡排序的边界,初始化为NULL
do {
swapped = 0; // 每次循环前将交换标志置为0
LinkList prev = L; // 前驱节点指针
LinkList curr = L->next; // 当前节点指针
while (curr->next != end) { // 遍历链表,直到边界
if (curr->data.id > curr->next->data.id) { // 如果当前节点的学号大于下一个节点的学号
// 交换节点
LinkList next = curr->next;
curr->next = next->next;
next->next = curr;
prev->next = next;
swapped = 1; // 设置交换标志为1
prev = next; // 更新前驱节点指针
} else {
prev = curr; // 移动前驱节点指针
curr = curr->next; // 移动当前节点指针
}
}
end = curr; // 更新边界
} while (swapped); // 如果发生了交换,则继续下一轮冒泡排序
cout << "按学号排序完成!" << endl;
}
// 7.3 按成绩从高到低进行冒泡排序 void SortByScore(LinkList &L) { if (L->next == NULL || L->next->next == NULL) return; // 如果链表为空或只有一个节点,无需排序
int swapped; // 用于标记是否发生了交换
LinkList end = NULL; // 冒泡排序的边界,初始化为NULL
do {
swapped = 0; // 每次循环前将交换标志置为0
LinkList prev = L; // 前驱节点指针
LinkList curr = L->next; // 当前节点指针
while (curr->next != end) { // 遍历链表,直到边界
if (curr->data.score < curr->next->data.score) { // 如果当前节点的成绩小于下一个节点的成绩
// 交换节点
LinkList next = curr->next;
curr->next = next->next;
next->next = curr;
prev->next = next;
swapped = 1; // 设置交换标志为1
prev = next; // 更新前驱节点指针
} else {
prev = curr; // 移动前驱节点指针
curr = curr->next; // 移动当前节点指针
}
}
end = curr; // 更新边界
} while (swapped); // 如果发生了交换,则继续下一轮冒泡排序
cout << "按成绩从高到低排序完成!" << endl;
}
// 8. 按学号查找学生 LNode* FindById(LinkList &L, int id) { LinkList p = L->next; while (p != NULL) { if (p->data.id == id) { return p; } p = p->next; } return NULL; }
// 9. 销毁链表 int DestroyList(LinkList &L) { LinkList p = L; while (L) { p = L; L = L->next; delete p; } return OK; }
int main() { LinkList L; // 定义链表 int choice, n, pos, id; // 定义选择、学生数量、位置、学号 Student stu; // 定义学生数据
// 初始化链表
if (InitList(L) == OK) {
cout << "学生链表初始化成功!" << endl;
}
while (true) {
cout << "\n=== 学生链表操作菜单 ===" << endl;
cout << "1. 创建学生链表" << endl;
cout << "2. 打印学生链表" << endl;
cout << "3. 插入学生数据" << endl;
cout << "4. 删除学生数据" << endl;
cout << "5. 统计学生数量" << endl;
cout << "6. 按姓名排序" << endl;
cout << "7. 按学号排序" << endl;
cout << "8. 按成绩排序" << endl;
cout << "9. 按学号查找学生" << endl;
cout << "10. 退出程序" << endl;
cout << "请输入选择: ";
cin >> choice;
switch (choice) {
// 创建学生链表
case 1:
cout << "请输入学生数量: ";
cin >> n;
CreateList_R(L, n);
break;
// 打印学生链表
case 2:
PrintList(L);
break;
// 插入学生数据
case 3:
cout << "请输入插入位置: ";
cin >> pos;
cout << "请输入学生数据:" << endl;
cout << "学号: "; cin >> stu.id;
cout << "姓名: "; cin >> stu.name;
cout << "成绩: "; cin >> stu.score;
cout << "性别: "; cin >> stu.gender;
cout << "年龄: "; cin >> stu.age;
cout << "专业: "; cin >> stu.major;
if (ListInsert(L, pos, stu) == OK) {
cout << "插入成功!" << endl;
} else {
cout << "插入失败!" << endl;
}
break;
//删除学生数据
case 4:
cout << "请输入删除位置: ";
cin >> pos;
if (ListDelete(L, pos) == OK) {
cout << "删除成功!" << endl;
} else {
cout << "删除失败!" << endl;
}
break;
//统计学生数量
case 5:
cout << "学生数量为: " << CountStudents(L) << endl;
break;
// 按姓名排序
case 6:
SortByName(L);
break;
// 按学号排序
case 7:
SortById(L);
break;
// 按成绩排序
case 8:
SortByScore(L);
break;
// 按学号查找学生
case 9:
cout << "输入要查找的学号: ";
cin >> id;
LNode* result = FindById(L, id);
if (result != NULL) {
cout << "找到学生: " << endl;
cout << "学号: " << result->data.id << endl;
cout << "姓名: " << result->data.name << endl;
cout << "成绩: " << result->data.score << endl;
cout << "性别: " << result->data.gender << endl;
cout << "年龄: " << result->data.age << endl;
cout << "专业: " << result->data.major << endl;
} else {
cout << "未找到学号为 " << id << " 的学生!" << endl;
}
break;
}
}
}