最近,在准备找工作,看到了单链表这里,就自己试着用单链表编写了一个学生信息管理系统。自己水平不高,很简单的一个小系统,贴出来请大家帮我指出错误,请大家指教!谢谢!
// 学生信息系统.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
using namespace std;
#define LEN sizeof(struct student_list)//结构体的长度
struct student_list
{
int num;//学号
double score;//分数
struct student_list* next;//指向下一节点的指针
};
/********************************************学生信息系统***********************************************************
***名称:学生信息系统
***功能:1.录入学生信息
2.增添学生信息
3.删除学生信息
4.查找学生信息
5.排列学生信息
6.修改学生信息
7.安全退出系统
***所使用的函数及作用:
int GetKey():读取按键的值,判断选择了哪一项功能
void ShowMenu():介绍学生信息系统的功能及对应的按键
int print_list(struct student_list* list_head):打印学生的信息
struct student_list* create_list():录入学生信息
struct student_list* insert_list_node(struct student_list* list_head, struct student_list* list_student):增添学生的信息
struct student_list* delete_list_node(struct student_list* list_head, int position):删除学生的信息
struct student_list* sort_list(struct student_list* list_head):冒泡法排列学生信息(按照学号从小到大排列)
struct student_list* find_node(student_list* list_head, int stu_num):查找节点信息根据学号
int find_stu_node(student_list* list_head, int stu_num):查找修改的学生是否在链表中已经存在
struct student_list* modify_node(student_list* list_head, int num_old, int num_new, int socre_new):修改学生信息
************************************************************************************************************************/
/************************************
***功能:读取按键,判断选择了哪一项功能
***返回:void
************************************/
int GetKey()
{
int press_key;
press_key = getch();//功能键需要读两次值
return press_key;
}
/*********************************
***函数名称:ShowMenu
***函数说明:介绍学生信息系统的功能及对应的按键
***函数返回:void
*********************************/
void ShowMenu()
{
cout<<" 学 生 成 绩 管 理 系 统 "<> list_temp0->num;
if (list_temp0->num <= 0)
{
cout << "输入信息完毕!" << endl;
break;
}
cout << "输入分数:";
cin >> list_temp0->score;
/*************插表头******************/
//list_temp0->next = list_head;
//list_head = list_temp0;
/**************链表尾****************/
++n;
if (1 == n)
{
list_head = list_temp0;
list_temp0->next = NULL;
}
else
{
list_temp1->next = list_temp0;
list_temp0->next = NULL;
}
list_temp1 = list_temp0;//保存,产生新节点时候会用
}while (list_temp0->num != 0);
free(list_temp0);
list_temp0 = NULL;
return list_head;//退出的时候要返回一个值,否则不能打印,返回值的位置要写对
}
/*********************************
***功能:打印链表
***返回:成功返回0,失败返回1
*********************************/
void print_list(struct student_list* list_head)
{
struct student_list* p;
p = list_head;
if (p == NULL)
cout << "这是一个空链表!请创建或打印一个非空列表!" << endl;
else
{
do
{
cout << "节点的地址:0x" << p << "->学号:" << p->num << "->分数:" << p->score << endl;
p = p->next;
} while (p != NULL);
}
}
/*****************************************************
***功能:将一个节点插入到大于链表中学号的后面,链表中的学号
要求从小到大排列
***返回:指向链表表头的指针
****************************************************/
struct student_list* insert_list_node(struct student_list* list_head, struct student_list* list_student)
{
struct student_list* p0;//p0用来指向头结点
struct student_list* p1;//p1用来指向要插入的节点
struct student_list* p2;
p0 = list_head;
p1 = list_student;
if (list_head == NULL)//若链表为空
{
list_head = p1;
p1->next = NULL;
}
else//若链表不为空
{
//从头节点开始比较,直到插入学号大于于当前节点,或当前节点指向链表尾
while (p1->num > p0->num && p0->next != NULL)
{
p2 = p0;//备份
p0 = p0->next;//向后移一位
}
//若当前节点指向链表尾还没有找到插入位置
if (p0->next == NULL)
{
if (list_head == p0)//若当前节点只有一个并且是头节点
{
if (p0->num < p1->num)
{
p1->next = p0->next;
p0->next = p1;
}
else
{
list_head = p1;
p1->next = p0;
}
}
else//若当前节点不是头节点
{
if (p1->num < p0->num)//若插入的学号小于最后一个节点的学号
{
p1->next = p2->next;
p2->next = p1;
}
else//若插入的学号大于最后一个节点的学号
{
p1->next = p0->next;
p0->next = p1;
}
}
}
//或者若是插入节点的学号比当前节点的学号小
else if (p1->num < p0->num)
{
if (list_head == p0)//若当前节点是头节点
{
list_head = p1;
p1->next = p0;
}
else//若当前节点不是头节点
{
if (p0->next != NULL)//若当前节点不指向链表结尾
{
p1->next = p2->next;
p2->next = p1;
}
else//若当前节点指向链表结尾
{
p1->next = p0->next;
p0->next = p1;
}
}
}
}
return list_head;
}
/***************************
***功能:删除指定位置的节点
***返回:指向链表表头的指针
***************************/
struct student_list* delete_list_node(struct student_list* list_head, int position)
{
struct student_list* p0;
struct student_list* p1;
p0 = list_head;//p0是移动节点,p0初始指向头节点
if (list_head == NULL)//如果是空链表
{
cout << "这是一个空链表!" << endl;
}
else
{
while (p0->num != position && p0->next != NULL)//若当前节点的学号不是指定删除的学号,并且没指向链表的结尾
{
p1 = p0;
p0 = p0->next;
}
if (p0->num == position)
{
if (list_head == p0)//若当前节点是头节点
{
p0 = p0->next;//p0指向下一节点
list_head = p0;//下一节点作为头节点
}
else
p1->next = p0->next;//把当前节点指向的下一节点地址给前一节点
}
else if (p0->next == NULL)
{
if (p0->num == position)//在最后找到删除的节点
p1->next = p0->next;
else//若是没有找到要删除的节点
cout << "该节点在链表中不存在,请另外选择节点!" << endl;
}
}
return list_head;
}
/***************************
***功能:按照学生的学号排列节点
***返回:指向链表表头的指针
***************************/
struct student_list* sort_list(struct student_list* list_head)
{
struct student_list* endpt;//每趟排序的末尾节点
struct student_list* p;//中间变量
struct student_list* p1;
struct student_list* p2;
if (list_head == NULL)
{
cout << "这是一个空链表!" << endl;
}
else
{
p1 = (struct student_list*)malloc(LEN);//开辟一个链表空间
p1->next = list_head;
list_head = p1;
for (endpt = NULL; endpt != list_head; endpt = p)
{
for (p = p1 = list_head; p1->next->next != NULL; p1 = p1->next)
{
if (p1->next->num > p1->next->next->num)//若前一节点的学号大于后一节点的学号
{
p2 = p1->next->next;//把后一节点给临时节点
p1->next->next = p2->next;//将前一节点指向后一节点所指向的节点
p2->next = p1->next;//让后一节点指向前一节点
p1->next = p2;//让p1指向后一节点
p = p1->next->next;//p往链表的头移动一位
}
}
}
p1 = list_head;//p1指向链表的头
list_head = list_head->next;//将p1的下一节点作为链表头
free(p1);
p1 = NULL;
}
return list_head;
}
/***************************
***功能:根据学生的学号查找学生
***返回:指向链表表头的指针
***************************/
struct student_list* find_node(student_list* list_head, int stu_num)
{
struct student_list* p;
p = list_head;
if (list_head == NULL)
cout << "这是一个空链表!" << endl;
else
{
while (p != NULL && p->num != stu_num)
p = p->next;
if (p != NULL && p->num == stu_num)
cout << "节点的地址:0x" << p << "->学号:" << p->num << "->分数:" << p->score << endl;
if (p == NULL)
{
cout << " " << endl;
cout << " 很抱歉,您要查找的学生信息不存在!" << endl;
}
}
return list_head;
}
/***************************
***功能:根据学生的学号查找学生
***返回:找到返回1,没找到返回0
***************************/
bool find_stu_node(student_list* list_head, int stu_num)
{
struct student_list* p;
p = list_head;
bool find_flag = false;
if (list_head == NULL)
cout << "这是一个空链表!" << endl;
else
{
while (p != NULL && p->num != stu_num)
p = p->next;
if (p != NULL && p->num == stu_num)
find_flag = true;
if (p == NULL)
find_flag = false;
}
return find_flag;
}
/**********************************
***功能:输入想修改学生的学号,并修改
***返回:指向链表表头的指针
**********************************/
struct student_list* stu_new;
struct student_list* modify_node(student_list* list_head, int num_old, int num_new, int socre_new)
{
struct student_list* p;
p = list_head;
if (list_head == NULL)
cout << "这是一个空链表!" << endl;
else
{
stu_new = (struct student_list*)malloc(LEN);//将需要修改的信息作为一个节点
stu_new->num = num_new;
stu_new->score = socre_new;
if (find_stu_node(list_head, num_old))
{
if (num_old == num_new)//若是不修改学号,只修改成绩
{
while (p != NULL && p->num != num_old)
p = p->next;
if (p->num == num_old)
p->score = socre_new;
}
else//修改学号,也修改成绩
{
delete_list_node(list_head, num_old);
insert_list_node(list_head, stu_new);
}
}
else
{
cout << " " << endl;
cout << " 您要修改的学生信息不存在! " << endl;
cout << " 您要添加该学生的信息请输入9,继续请输入任意数字! " << endl;
cout << "请输入:";
int key_9;
cin >> key_9;
if (9 == key_9)
insert_list_node(list_head, stu_new);
}
}
return list_head;
}
int main()
{
int key_value;
int stu_num;
int stu_num_new;
int stu_score;
static struct student_list *student = NULL;
struct student_list* stu = NULL;
ShowMenu();
while (1)
{
key_value = GetKey();
switch (key_value)
{
case '1':
cout << "1.录入学生信息" << endl;
cout << " " << endl;
student = creat_list();
print_list(student);
cout << " " << endl;
cout << " 继续操作请输入1-6,退出请输入7! " << endl;
break;
case '2':
cout << "2.增添学生信息" << endl;
cout << " " << endl;
stu = (struct student_list*)malloc(LEN);
cout << "学号:";
cin >> stu->num;
cout << "分数:";
cin >> stu->score;
student = insert_list_node(student, stu);
print_list(student);
cout << " " << endl;
cout << " 继续操作请输入1-6,退出请输入7! " << endl;
break;
case '3':
cout << "3.删除学生信息" << endl;
cout << " " << endl;
int student_num;
cout << "请输入要删除的学号:";
cin >> student_num;
student = delete_list_node(student, student_num);
cout << " " << endl;
cout << " 您是否想查看现在的学生信息? " << endl;
cout << " " << endl;
cout << " 查看学生信息请输入8,跳过请输入任意数字! " << endl;
cout << "请输入:";
int key_delete;
cin >> key_delete;
if (8 == key_delete)
print_list(student);
cout << " " << endl;
cout << " 继续操作请输入1-6,退出请输入7! " << endl;
break;
case '4':
cout << "4.查找学生信息" << endl;
cout << " " << endl;
cout << "请输入您想要找的学生的学号:";
cin >> stu_num;
student = find_node(student, stu_num);
cout << " " << endl;
cout << " 继续操作请输入1-6,退出请输入7! " << endl;
break;
case '5':
cout << "5.排列学生信息" << endl;
cout << " " << endl;
student = sort_list(student);
if (student != NULL)//若是空链表就不用再显示出来
print_list(student);
cout << " " << endl;
cout << " 继续操作请输入1-6,退出请输入7! " << endl;
break;
case '6':
cout << "6.修改学生信息" << endl;
cout << " " << endl;
cout << "请输入您要修改的学生的学号:";
cin >> stu_num;
cout << "请输入您修改后的学生的信息:";
cin >> stu_num_new >> stu_score;
student = modify_node(student, stu_num, stu_num_new, stu_score);
print_list(student);
cout << " " << endl;
cout << " 继续操作请输入1-6,退出请输入7! " << endl;
break;
case '7':
cout << "7.安全退出系统" << endl;
cout << " " << endl;
cout << " 感谢您使用本系统,欢迎再次使用! " << endl;
free(student);
free(stu_new);//find_stu_node函数开辟的空间,在子函数中不能释放,把它定义为全局变量,在退出系统的时候释放
student = NULL;
stu_new = NULL;
system("pause");
return 0;
default:
cout << "您输入的数字不在1-7的范围内!继续操作请输入1-6,退出请输入7!" << endl;
cout << " " << endl;
cout << "请选择:";
break;
}
}
}
该系统的运行界面如下图所示:
写这个小系统主要是为了学习单链表,我水平不高,做的不好,希望大家多多指教,谢谢!关于链表的知识,请您自己查找相关资料阅读。