数据结构C/C++ 职工信息管理系统
一、前言
二、系统结构设计
三、模块功能代码
3.1 菜单函数
3.2 初始化单链表
3.3 添加信息
3.4 信息输出
3.5 信息排序
3.6 信息删除
3.7 信息存储
四、系统完整代码
五、运行结果(部分展示)
六、实验总结
七、参考网址
一、前言
本文还是使用较老的 VC++6.0,这里推荐可以使用小熊猫C++ 用的还是比较舒服方便的。
系统还是较为简陋,欢迎各位大佬进行改进。
系统任务描述如下:
设有一组职工数据,每个职工记录包含职工编号(no)、姓名(name)、部门号(depno)和工资数(salary)。设计一个程序完成以下功能:
(1)建表。从键盘输入职工记录,并建立一个带头结点的单链表L。
(2)输入。添加一个职工信息。
(3)输出。输出全部职工信息。
(4)排序。按职工编号no所有职工记录进行递增排序,并输出所有职工记录。
(5)排序。按部门号no所有职工记录进行递增排序,并输出所有职工记录。
(6)排序。按工资数salary所有职工记录进行递增排序,并输出所有职工记录。
(7)删除。删除指定职工编号的职工记录。
(8)删除。删除职工链表L中的全部记录。
(9)存储后退出。将单链表中的全部结点数据存储到职工文件中,然后退出程序运行过程。
二、系统结构设计
1. 职工信息管理系统功能模块结构图和职工信息结构图:
2. 菜单功能
三、模块功能代码
3.1 菜单函数
void menu()
{
system("cls");//清屏
system("color 00b");//设置为蓝色
printf(" **********欢迎使用职工管理系统**************\n");
printf(" 请输入如下命令执行相应功能\n");
printf(" 【1】 添加一个职工信息\n");
printf(" 【2】 输出全部职工信息\n");
printf(" 【3】 按职工号排序\n");
printf(" 【4】 按部门号排序\n");
printf(" 【5】 按工资数排序\n");
printf(" 【6】 删除指定职工编号记录\n");
printf(" 【7】 删除全部职工记录 \n");
printf(" 【8】 清屏\n");
printf(" 【9】 储存信息并退出\n");
printf(" 【-1】 退出程序\n");
printf(" ********************************************\n");
}
3.2 初始化单链表
使用malloc函数为头节点分配内存,并强制转化为结点指针类型,并赋值给头指针。接下来看内存分配是否成功。如果头指针不为空,则令头结点next域指向空。否则,它会打印错误消息 "内存不足!" 并返回-1表示初始化失败。
int Initlist(LinkNode *&L)
{
L=(LinkNode *)malloc(sizeof(LinkNode));
if(L!=NULL)
{
L->next=NULL;
return 1;
}
else
{
printf("内存不足!\n");
return 0;
}
}
3.3 添加信息
利用头插法建表,重复读入数据,生成新结点,将读入数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头结点之后,直至读入结束标志为止。
若链表中存在与新结点中相同的职工号,打印“录入失败提示:此职工号已经存在!”的提示信息,表示插入失败,并释放新结点。反之,打印“录入成功!”的提示信息,表示插入成功。
int CreateListF(LinkNode *&L)
{
LinkNode *q=(LinkNode *)malloc(sizeof(LinkNode));
printf("请输入职工号(数字):");
scanf("%d",&q->w.no);
LinkNode *s=L->next;
while(s)
{
if(s->w.no==q->w.no)
{
free(q);
printf("录入失败提示:此职工号已经存在!\n");
return -1;
}
s=s->next;
}
printf("请输入职工姓名(文字):");
scanf("%s",&q->w.name);
printf("请输入职工部门号(数字):");
scanf("%d",&q->w.departno);
printf("请输入职工工资数(数字):");
scanf("%d",&q->w.salary);
q->next=L->next;
L->next=q;
printf("录入成功!\n");
return 1;
}
3.4 信息输出
使用while循环遍历链表,如果链表非空,则执行以下步骤。输出当前节点的职工信息,包括职工号、姓名、部门号、工资等。将节点的指针移动到链表的下一个节点。循环执行步骤2~3,直到链表为空为止。输出显示完毕的信息。
void show(LinkNode *L)
{
menu();
printf("浏览职工信息\n");
printf("职工号\t姓名\t部门号\t工资\t\n");
while(L->next!=NULL)
{
printf("%d\t%s\t%d\t%d\t\n",L->next->w.no,L->next->w.name,L->next->w.departno,L->next->w.salary);
L=L->next;
}
printf("显示完毕!\n");
}
3.5 信息排序
构建一个有序的结点序列,其相关数据域按递增排序,从头节点遍历有序序列,与无序序列头节点数据域一一比较,取出结点并将其放在有序序列中合适的位置上,直到无序序列中没有元素。
若要以部门号或薪资号进行递增排序,只需更改结点中结构体的成员即可。
职工号递增:
LinkNode nolist(LinkNode *&L)
{
LinkNode *p=L->next;
LinkNode *r=p->next;
LinkNode *q;
LinkNode *pre;
p->next=NULL;
p=r;
while(p!=NULL)
{
r=p->next;
q=L;
while(q->next!=NULL&&q->next->w.no<p->w.no)
{
q=q->next;
}
pre=q;
p->next=pre->next;
pre->next=p;
p=r;
}
return *L;
}
部门号递增:
LinkNode depnolist(LinkNode *&L)
{
LinkNode *p=L->next;
LinkNode *r=p->next;
LinkNode *q;
LinkNode *pre;
p->next=NULL;
p=r;
while(p!=NULL)
{
r=p->next;
q=L;
while(q->next!=NULL&&q->next->w.departno<p->w.departno)
{
q=q->next;
}
pre=q;
p->next=pre->next;
pre->next=p;
p=r;
}
return *L;
}
工资递增:
LinkNode salarylist(LinkNode *&L)
{
LinkNode *p=L->next;
LinkNode *r=p->next;
LinkNode *q;
LinkNode *pre;
p->next=NULL;
p=r;
while(p!=NULL)
{
r=p->next;
q=L;
while(q->next!=NULL&&q->next->w.salary<p->w.salary)
{
q=q->next;
}
pre=q;
p->next=pre->next;
pre->next=p;
p=r;
}
return *L;
}
3.6 信息删除
删除指定的员工
遍历链表,查找待删除职工号所在的节点。若找到,则保存该节点的指针q,并让节点k指向q的下一个节点。使用free函数释放q指向的节点空间,并输出删除成功的信息。若遍历完整个链表仍未找到待删除的职工号,则输出删除失败的信息。
int deleteone(LinkNode *&L,int no)
{
menu();
printf("正在按职工号删除职工信息\n");
LinkNode *k=L;
while(k->next!=NULL)
{
if(k->next->w.no==no)
{
LinkNode *q=k->next;
k->next=q->next;
free(q);
printf("删除职工号%d成功!\n",no);
return 1;
}
k=k->next;
}
printf("没有你输入的职工号!\n");
return -1;
}
删除全部员工
使用while循环遍历链表,如果链表非空,则执行以下步骤。保存链表头结点指向的节点q的指针,并让头结点指向q的下一个节点。释放q指向的节点空间。循环执行步骤2~3,直到链表为空为止。
void deleteall(LinkNode *&L)
{
while(L->next!=NULL)
{
LinkNode *q=L->next;
L->next=L->next->next;
free(q);
}
}
3.7 信息存储
定义文件指针fp,并使用fopen函数打开文件work.txt,如果打开失败,则输出提示信息,函数结束。使用while循环遍历链表,如果链表非空,则执行以下步骤。
将当前节点存储的职工信息写入文件,使用fwrite函数,并向其传递3个参数:待写入的数据地址、每个数据单元的字节数、待写入的数据单元数量,函数的返回值表示成功写入的数据单元数量。将节点的指针移动到链表的下一个节点,并统计写入的节点数量n。循环执行步骤3~4,直到链表为空为止。使用fclose函数关闭文件。
使用free函数释放链表头结点的内存空间。输出写入文件的职工信息数量,或者提示没有任何记录写入文件。
代码生成的work.txt文件与C++编译文件在相同路径
void SaveFile(LinkNode *L)
{
LinkNode *q=L->next;
int n=0;
FILE *fp;
if ((fp=fopen("work.txt","wb+"))==NULL)
{
printf(" 提示:不能创建文件work.txt\n");
return;
}
while (q!=NULL)
{
fwrite(&q->w,sizeof(Worker),1,fp);
q=q->next;
n++;
}
fclose(fp);
free(L);
if (n>0)
printf("%d个职工记录写入work.txt文件\n",n);
else
printf("没有任何职工记录写入work.txt文件\n");
}
四、系统完整代码
这里直接将代码放到vc++6.0的c++文件就行,同理 要是使用小熊猫C++也是直接放建立好的c++的文件即可。下头的文件保存就会保存到与建立的c++文件相同的路径。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
struct Worker
{
int no;
char name[8];
int departno; //部门
int salary;
};
typedef struct LNode
{
Worker w;
LNode *next;
}LinkNode;
//显示程序界面文字
void menu()
{
system("cls");//清屏
system("color 00b");
printf(" **********欢迎使用职工管理系统**************\n");
printf(" 请输入如下命令执行相应功能\n");
printf(" 【1】 添加一个职工信息\n");
printf(" 【2】 输出全部职工信息\n");
printf(" 【3】 按职工号排序\n");
printf(" 【4】 按部门号排序\n");
printf(" 【5】 按工资数排序\n");
printf(" 【6】 删除指定职工编号记录\n");
printf(" 【7】 删除全部职工记录 \n");
printf(" 【8】 清屏\n");
printf(" 【9】 储存信息并退出\n");
printf(" 【-1】 退出程序\n");
printf(" ********************************************\n");
}
//初始化单链表
int Initlist(LinkNode *&L)
{
L=(LinkNode *)malloc(sizeof(LinkNode));
if(L!=NULL)
{
L->next=NULL;
return 1;
}
else
{
printf("内存不足!\n");
return 0;
}
}
//存储
void SaveFile(LinkNode *L)
{
LinkNode *q=L->next;
int n=0;
FILE *fp;
if ((fp=fopen("work.txt","wb+"))==NULL)
{
printf(" 提示:不能创建文件work.txt\n");
return;
}
while (q!=NULL)
{
fwrite(&q->w,sizeof(Worker),1,fp);
q=q->next;
n++;
}
fclose(fp);
free(L);
if (n>0)
printf("%d个职工记录写入work.txt文件\n",n);
else
printf("没有任何职工记录写入work.txt文件\n");
}
/*录入职工信息*/ //采用头插法
int CreateListF(LinkNode *&L)
{
LinkNode *q=(LinkNode *)malloc(sizeof(LinkNode));
printf("请输入职工号(数字):");
scanf("%d",&q->w.no);
LinkNode *s=L->next;
while(s)
{
if(s->w.no==q->w.no)
{
free(q);
printf("录入失败提示:此职工号已经存在!\n");
return -1;
}
s=s->next;
}
printf("请输入职工姓名(文字):");
scanf("%s",&q->w.name);
printf("请输入职工部门号(数字):");
scanf("%d",&q->w.departno);
printf("请输入职工工资数(数字):");
scanf("%d",&q->w.salary);
q->next=L->next;
L->next=q;
printf("录入成功!\n");
return 1;
}
//职工号排序
LinkNode nolist(LinkNode *&L)
{
LinkNode *p=L->next;
LinkNode *r=p->next;
LinkNode *q;
LinkNode *pre;
p->next=NULL;
p=r;
while(p!=NULL)
{
r=p->next;
q=L;
while(q->next!=NULL&&q->next->w.no<p->w.no)
{
q=q->next;
}
pre=q;
p->next=pre->next;
pre->next=p;
p=r;
}
return *L;
}
//部门号排序
LinkNode depnolist(LinkNode *&L)
{
LinkNode *p=L->next;
LinkNode *r=p->next;
LinkNode *q;
LinkNode *pre;
p->next=NULL;
p=r;
while(p!=NULL)
{
r=p->next;
q=L;
while(q->next!=NULL&&q->next->w.departno<p->w.departno)
{
q=q->next;
}
pre=q;
p->next=pre->next;
pre->next=p;
p=r;
}
return *L;
}
//工资排序
LinkNode salarylist(LinkNode *&L)
{
LinkNode *p=L->next;
LinkNode *r=p->next;
LinkNode *q;
LinkNode *pre;
p->next=NULL;
p=r;
while(p!=NULL)
{
r=p->next;
q=L;
while(q->next!=NULL&&q->next->w.salary<p->w.salary)
{
q=q->next;
}
pre=q;
p->next=pre->next;
pre->next=p;
p=r;
}
return *L;
}
//按职工号删除职工信息(已修改)
int deleteone(LinkNode *&L,int no)
{
menu();
printf("正在按职工号删除职工信息\n");
LinkNode *k=L;
while(k->next!=NULL)
{
if(k->next->w.no==no)
{
LinkNode *q=k->next;
k->next=q->next;
free(q);
printf("删除职工号%d成功!\n",no);
return 1;
}
k=k->next;
}
printf("没有你输入的职工号!\n");
return -1;
}
//删除全部员工记录(修改已正常)
void deleteall(LinkNode *&L)
{
while(L->next!=NULL)
{
LinkNode *q=L->next;
L->next=L->next->next;
free(q);
}
}
//浏览职工信息
void show(LinkNode *L)
{
menu();
printf("浏览职工信息\n");
printf("职工号\t姓名\t部门号\t工资\t\n");
while(L->next!=NULL)
{
printf("%d\t%s\t%d\t%d\t\n",L->next->w.no,L->next->w.name,L->next->w.departno,L->next->w.salary);
L=L->next;
}
printf("显示完毕!\n");
}
void main()
{
int ord=0;
int no;
LinkNode *L;
if(!(Initlist(L)))
exit(0);
while(ord!=-1)
{
switch(ord)
{
case 0:
menu();
break;
case 1:
CreateListF(L);
break;
case 2:
show(L);
break;
case 3:
nolist(L);
show(L);
printf("按职工号排列成功!\n");
break;
case 4:
depnolist(L);
show(L);
printf("按部门号排列成功!\n");
break;
case 5:
salarylist(L);
show(L);
printf("按工资排列成功!\n");
break;
case 6:
printf("请输入要删除的职工号:");
scanf("%d",&no);
deleteone(L,no);
printf("删除成功!\n");
show(L);
break;
case 7:
deleteall(L);
show(L);
printf("记录为空\n");
printf("已经删除全部记录!\n");
break;
case 8:
default:
menu();
break;
case 9:
SaveFile(L);
exit(0);
}
printf("请输入操作命令数字:\n");
scanf("%d",&ord);
}
free(L);
}
五、运行结果(部分展示)
初始界面:
进行插入功能:
进行输出功能:
进行删除功能:删除指定员工和删除全部员工
进行排序功能:以职工号,职工部门号,职工工资信息排序
进行存储功能:
六、实验总结
通过设计职工信息管理系统,我对单链表这个数据结构更加熟悉。单链表可以通过指针进行节点的连接,从而形成一个链式结构,每个节点存储一个员工的信息,如工号、姓名、部门、工资等。首先是节点的定义,每个节点存储一个员工的信息,通过指针连接下一个节点。接着是链表的插入、删除和查找操作,可以通过指针来实现节点之间的连接和数据的读取。最后是利用文件操作实现了职工信息的存储。也知道了链表的头节点需要单独处理,通常不存储数据信息。对链表的操作也需要考虑边界条件,如链表为空、插入位置超出范围等。
通过前面的实验学习我了解到单链表,双链表,栈,队列,的逻辑结构都是一对一的线性结构,学习并掌握了数据结构相关的基本概念、分类、实现方法和应用场景,并通过实验实际操作加深了对数据结构的理解。例如,栈和队列常用于程序调试和嵌套结构的处理;链表通常用于动态内存分配和实现复杂的数据结构;此外,也学习到了各种各样的排序算法,但还是没有十全十美的算法
数据结构是基础的一门课,最初接触是对一些思想可能只是生硬的记忆,随着学习的深入逐渐领悟了很多。数据结构广泛应用于程序设计、数据库、网络等领域。总之,学习数据结构是计算机科学中的重要部分,是提高编程技能和实现复杂程序的必备基础之一。
感谢老师在学习中给予的帮助与指导,让我深入地了解数据结构的原理和实现。
七、参考网址
C语言程序设计 利用文件保存数据_save函数在c语言中有关文件的用法-CSDN博客
https://blog.csdn.net/qq_31790997/article/details/90114169
数据结构《职工管理系统》_提供排序功能,可按照多种关键字对职工进行排序。要求按照“部门号”(“部门号”相-CSDN博客
https://www.bilibili.com/video/BV1et4y197Ud/?spm_id_from=333.999.0.0文章来源:https://www.toymoban.com/news/detail-795464.html
希望能对你有所帮助文章来源地址https://www.toymoban.com/news/detail-795464.html
到了这里,关于数据结构C/C++ 职工信息管理系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!