C语言:链表之学生管理系统

#include<iostream>
#include<string>
#include<iomanip>
#include<fstream>
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。


typedef struct {
    char no[8];   //8位学号
    char name[20]; //姓名
    int grade;     //成绩
}Student;

typedef Student ElemType; //ElemType 为可定义的数据类型 
typedef struct LNode {
	ElemType data; //结点的数据域
	struct LNode *next; //结点的指针域
} LNode, *LinkList; //LinkList为指向结构体LNode的指针类型	


Status InitList_L(LinkList &L) { //算法2.6 单链表的初始化
	//构造一个空的单链表L
	L = new LNode; //生成新结点作为头结点,用头指针L指向头结点
	L->next = NULL; //头结点的指针域置空
	return OK;
}

Status GetElem_L(LinkList L, int i, ElemType &e) { //算法2.7 单链表的取值
	//在带头结点的单链表L中查找第i个元素
	//用e返回L中第i个数据元素的值
	int j;
	LinkList p;
	p = L->next;
	j = 1; //初始化,p指向第一个结点,j为计数器
	while (j < i && p) { //顺链域向后扫描,直到p指向第i个元素或p为空
		p = p->next; //p指向下一个结点
		++j; //计数器j相应加1
	}
	if (!p || j > i)
		return ERROR; //i值不合法i>n或i<=0
	e = p->data; //取第i个结点的数据域
	return OK;
} //GetElem_L

LNode *LocateElem_L(LinkList L, string e) { //算法2.8 按值查找 //因为结果体中定义name为字符,所以不能与整数e比较 //必须定义string《字符串》char不行; 
	//在带头结点的单链表L中查找值为e的元素
	LinkList p;
	p = L->next;
	while (p && p->data.name != e)//顺链域向后扫描,直到p为空或p所指结点的数据域等于e    //修改  //禁止指针和整数比较 
		p = p->next; //p指向下一个结点
//	return p; //查找成功返回值为e的结点地址p,查找失败p为NULL
    return p;
} //LocateElem_L

Status ListInsert_L(LinkList &L, int i, ElemType &e) { //算法2.9 单链表的插入
	//在带头结点的单链表L中第i个位置插入值为e的新结点
	int j;
	LinkList p, s;
	p = L;
	j = 0;
	while (p && j < i - 1) {
		p = p->next;
		++j;
	}//查找第i-1个结点,p指向该结点
	if (!p || j > i - 1)
		return ERROR; //i>n+1或者i<1
	s = new LNode; //生成新结点*s
	s->data = e; //将结点*s的数据域置为e
	s->next = p->next; //将结点*s的指针域指向结点ai
	p->next = s; //将结点*p的指针域指向结点*s
	//++length;
	return OK;
} //ListInsert_L

Status ListDelete_L(LinkList &L, int i) { //算法2.10 单链表的删除
	//在带头结点的单链表L中,删除第i个位置
	LinkList p, q;
	int j;
	p = L;
	j = 0;
	while ((p->next) && (j < i - 1)) { //查找第i?1个结点,p指向该结点
		p = p->next;
		++j;
	}
	if (!(p->next) || (j > i - 1))
		return ERROR; //当i>n或i<1时,删除位置不合理
	q = p->next; //临时保存被删结点的地址以备释放
	p->next = q->next; //改变删除结点前驱结点的指针域
	delete q; //释放删除结点的空间
	//--length;
	return OK;
} //ListDelete_L

void CreateList_H(LinkList &L, int n) { //算法2.11 前插法创建单链表
	//逆位序输入n个元素的值,建立到头结点的单链表L
	LNode* p;
	string head_1, head_2, head_3;
	L = new LNode;
	L->next = NULL; //先建立一个带头结点的空链表
	//length = 0;
	fstream file;
	file.open("stu.txt");
	if (!file) {
		cout << "未找到相关文件,无法打开!" << endl;
		exit(ERROR);
	}
	file >> head_1 >> head_2 >> head_3;
	while (!file.eof()) {
		p = new LNode; //生成新结点*p
		file >> p->data.no >> p->data.name >> p->data.grade; //输入元素值赋给新结点*p的数据域
		p->next = L->next;
		L->next = p; //将新结点*p插入到头结点之后
		//length++;//同时对链表长度进行统计
	}
	file.close();
} //CreateList_F

void CreateList_R(LinkList &L, int n) { //算法2.12 后插法创建单链表
	//正位序输入n个元素的值,建立带表头结点的单链表L
	LinkList p, r;
	string head_1, head_2, head_3;
	L = new LNode;
	L->next = NULL; //先建立一个带头结点的空链表
	r = L; //尾指针r指向头结点

	//length = 0;
	fstream file; //打开文件进行读写操作
	file.open("stu.txt");
	if (!file) {
		cout << "未找到相关文件,无法打开!" << endl;
		exit(ERROR);
	}
	file >> head_1 >> head_2 >> head_3;
	while (!file.eof()) { //将文件中的信息运用后插法插入到链表中
		p = new LNode;//生成新结点
		file >> p->data.no >> p->data.name >> p->data.grade;//输入元素值赋给新结点*p的数据域
		p->next = NULL;
		r->next = p;//将新结点*p插入尾结点*r之后
		r = p;//r指向新的尾结点*p
		//length++; //同时对链表长度进行统计
	}
	file.close();
} //CreateList_L


//_______________________________________________________________________________________
int PrintAllElement(LinkList L) { //输出所有元素
	//
	LNode* p;
	int i;
	cout << "当前学生系统信息(链表)读出:\n";
	p = L->next;
	i=1;
	while (p) {
		cout <<i<<"\t"<< " "<< p->data.no << "\t\t" << p->data.name << "\t\t\t" << p->data.grade << endl;
		p = p->next;
		i++;
	}
	cout << endl;


}
int Menu() {
	int choice;
	choice=9;

	while (choice<0||choice>8) {
		cout << "1. 新建空表\n";
		cout << "2. 输入  从文件读入\n";
		cout << "3. 取值(按序号取值)\n";
		cout << "4. 查找(按  名字 查找)\n";
		cout << "5. 插入记录\n";
		cout << "6. 删除记录(按序号删除)\n";
		cout << "7. 输出(全部元素输出)\n";
		cout << "0. 退出\n\n";



		cout << "请选择:";
		cin >> choice;

	}
	return choice; 


}



int main() {

	LinkList testList;
	int i,n,inputn,inputelem;
	int location;
	int choice;
	ElemType element;
	double price;
	string name;

	while(1) {
		choice=Menu();
		if(choice==0) break;

		switch (choice) {
			case 1://创建链表
				if (InitList_L(testList))
					cout << "成功建立链表!\n\n";
				PrintAllElement(testList);
				break;
			case 2:  //使用后插法创建单链表
				CreateList_R(testList, 0);
				cout << "输入 stu.txt 信息完毕\n\n";
				PrintAllElement(testList);

				break;
			case 3://单链表的按序号取值
				cout << "请输入一个位置用来取值:";
				cin >> location;
				if (GetElem_L(testList, location, element)) {
					cout << "查找成功\n";
					cout << "第" << location << "这个学生的信息是的信息是:\n";
					cout << left << setw(15) << element.no << "\t" << left << setw(50)
					     << element.name << "\t" << left << setw(5) << element.grade << endl
					     << endl;   //修改通过位置得到学生学号、姓名、成绩 
				} else
					cout << "查找失败\n\n";
				break;
			case 4: //单链表的按值查找
				cout << "请输入所要查找姓名:";
//				cin >> price;//改成名字
				cin >> name;
				if (LocateElem_L(testList, name) != NULL) {
					cout << "查找成功\n";
					cout << "该名字对应的学号和成绩为为:" << LocateElem_L(testList, name)->data.no <<'\t'<< LocateElem_L(testList, name)->data.grade << endl << endl; //修改成了通过姓名返回学号和成绩 
//					     << endl << endl;  //修改到上一行 
				} else
					cout << "查找失败! 定价" << price << " 没有找到\n\n";
				break;
			case 5: //链表的插入
				cout << "请输入插入的位置和书的信息,包括:学号 名字 成绩(用空格隔开):";
				cout<<endl<< "请输入插入的位置:";
				cin >> location;
				cout<<endl<< "请输入学号 名字 成绩(用空格隔开):";
				cin >> element.no >> element.name >> element.grade;
				if (ListInsert_L(testList, location, element))
					cout << "插入成功.\n\n";
				else
					cout << "插入失败!\n\n";
				PrintAllElement(testList);
				break;
			case 6: //链表的删除
				cout << "请输入所要删除的学生的位置:";
				cin >> location;
				if (ListDelete_L(testList, location))
					cout << "删除成功!\n\n";
				else
					cout << "删除失败!\n\n";
				PrintAllElement(testList);
				break;
			case 7: //顺序表的输出
				PrintAllElement(testList);
				cout << endl;
				break;
		}
	}


}








下面是一个简单的C语言学生管理系统链表实现的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 学生结构体 typedef struct Student { char name[20]; // 名字 int age; // 年龄 float score; // 分数 struct Student *next; // 指向下一个学生的指针 } student; // 添加学生 void add_student(student **head) { student *new_student = (student*)malloc(sizeof(student)); // 创建新学生节点 printf("请输入学生姓名:"); scanf("%s", new_student->name); printf("请输入学生年龄:"); scanf("%d", &new_student->age); printf("请输入学生成绩:"); scanf("%f", &new_student->score); new_student->next = NULL; if (*head == NULL) { *head = new_student; } else { student *temp = *head; while (temp->next != NULL) { temp = temp->next; } temp->next = new_student; } printf("添加成功!\n"); } // 删除学生 void delete_student(student **head) { if (*head == NULL) { printf("链表为空,无法删除!\n"); return; } char name[20]; printf("请输入要删除的学生姓名:"); scanf("%s", name); if (strcmp((*head)->name, name) == 0) { student *temp = *head; *head = (*head)->next; free(temp); printf("删除成功!\n"); return; } student *temp = *head; while (temp->next != NULL) { if (strcmp(temp->next->name, name) == 0) { student *del_student = temp->next; temp->next = del_student->next; free(del_student); printf("删除成功!\n"); return; } temp = temp->next; } printf("未找到该学生,删除失败!\n"); } // 修改学生信息 void modify_student(student **head) { if (*head == NULL) { printf("链表为空,无法修改!\n"); return; } char name[20]; printf("请输入要修改的学生姓名:"); scanf("%s", name); student *temp = *head; while (temp != NULL) { if (strcmp(temp->name, name) == 0) { printf("请输入修改后的学生姓名:"); scanf("%s", temp->name); printf("请输入修改后的学生年龄:"); scanf("%d", &temp->age); printf("请输入修改后的学生成绩:"); scanf("%f", &temp->score); printf("修改成功!\n"); return; } temp = temp->next; } printf("未找到该学生,修改失败!\n"); } // 查找学生 void search_student(student *head) { if (head == NULL) { printf("链表为空,无法查找!\n"); return; } char name[20]; printf("请输入要查找的学生姓名:"); scanf("%s", name); student *temp = head; while (temp != NULL) { if (strcmp(temp->name, name) == 0) { printf("姓名:%s,年龄:%d,成绩:%.2f\n", temp->name, temp->age, temp->score); return; } temp = temp->next; } printf("未找到该学生!\n"); } // 显示所有学生 void show_all_students(student *head) { if (head == NULL) { printf("链表为空,无法显示!\n"); return; } printf("姓名\t年龄\t成绩\n"); student *temp = head; while (temp != NULL) { printf("%s\t%d\t%.2f\n", temp->name, temp->age, temp->score); temp = temp->next; } } // 释放链表空间 void free_list(student **head) { student *temp = *head; while (temp != NULL) { *head = (*head)->next; free(temp); temp = *head; } } int main() { student *head = NULL; // 头节点指针初始化为NULL int choice; while (1) { printf("\n********** 学生管理系统 **********\n"); printf("1. 添加学生\n"); printf("2. 删除学生\n"); printf("3. 修改学生信息\n"); printf("4. 查找学生\n"); printf("5. 显示所有学生\n"); printf("6. 退出\n"); printf("请输入你的选择:"); scanf("%d", &choice); switch (choice) { case 1: add_student(&head); break; case 2: delete_student(&head); break; case 3: modify_student(&head); break; case 4: search_student(head); break; case 5: show_all_students(head); break; case 6: free_list(&head); return 0; default: printf("输入错误,请重新选择!\n"); } } return 0; } ``` 这个示例中,我们定义了一个`student`结构体,包含了学生的姓名、年龄、分数以及指向下一个学生节点的指针。然后,我们实现了添加学生、删除学生、修改学生信息、查找学生、显示所有学生以及释放链表空间等操作。在`main`函数中,我们使用一个无限循环不断显示菜单,根据用户的选择调用相应的函数。注意,在添加、删除和修改学生信息时,我们需要传入头节点的指针的指针,这是因为在这些操作中可能会改变头节点的指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值