数据结构实训——员工管理系统
1 课题描述
每个员工的信息包括:编号、姓名、性别、出生年月、学历、职务、电话、住址等。系统能够完成员工信息的查询、更新、插入、删除、排序等功能。
2 问题分析和任务定义
要求:
每个员工的信息包括:编号、姓名、性别、出生年月、学历、职务、电话、住址等。
(1) 排序:按不同关键字,对所有员工的信息进行排序。(这里仅按照工号排序)
(2) 查询:按特定条件(工号、姓名)查找员工。
(3) 更新:按编号对某个员工的某项信息进行修改。
(4) 插入:加入新员工的信息。
(5) 删除:按编号删除已离职的员工的信息。
3 逻辑设计
1)数据类型:
对员工的信息进行分析,因为要可以根据工号进行排序,因而将工号设置为整数型,而姓名、性别、出生年月、学历、职务、电话、住址这些内容设置为字符串类型。并且还要设置一个整数型遍历num来存储此时含有的记录数。
struct staff
{
int id;///编号
char name[20];///姓名
char sex[20];///性别
char age[20];///出生年月
char clas[20];///学历
char duty[20];///职务
char tel[20];///电话
char addr[20];///住址
} s[1000];
int num;
2)抽象数据类型:
ADT Staff {
数据对象D:D是具有相同特征的数据元素的集合。各数据元素均含有类型相同,可唯一标识数据元素的关键字。
数据关系R:数据元素同属一个集合。
staffinput()
操作结果:输入员工信息。
staffdisplay()
操作结果:浏览员工记录。
staffsearch()
操作结果:查找员工记录。
staffdel()
操作结果:删除员工记录函数
staffadd()
操作结果:添加员工记录
staffchange()
操作结果:修改员工记录
staffsort()
操作结果:对员工排序
}ADT Staff
3)模块功能:
功能上主要有录入记录,查找记录,增加记录,删除记录,更改记录,对记录排序,显示所有记录这七大模块。其中查找记录和删除记录这一模块既可以根据工号查找,也可以根据姓名查找,灵活方便。而更改记录这一模块则能够修改该员工记录的所有信息。同时对记录排序这一模块需要使用排序算法来实现。
4 详细设计
员工信息结构体:
struct staff
{
int id;///编号
char name[20];///姓名
char sex[20];///性别
char age[20];///出生年月
char clas[20];///学历
char duty[20];///职务
char tel[20];///电话
char addr[20];///住址
} s[1000];
int num;
<1>输入员工信息函数:void staffinput()
输入多组员工记录,包括工号、姓名、性别、出生年月、学历、职务、电话、住址。
<2>浏览员工记录函数:void staffdisplay()
打印所有员工的记录,工号、姓名、性别、出生年月、学历、职务、电话、住址
<3>查找员工函数:void staffsearch()
既可以按照员工的工号也可以按照员工的姓名来查找,然后打印该员工信息。
<4>删除员工记录函数:void staffdel()
既可以按照员工的工号也可以按照员工的姓名来删除该员工记录。删除该条记录后num要-1,同时要将该记录后面的记录向前挪一位。
<5>添加员工记录函数:void staffadd()
插入一条新员工的记录,这条记录会添加在顺序表的表尾,同时num要+1。
<6>修改员工记录函数:void staffchange()
先按照员工的姓名或者工号查找到该员工的记录,然后可以对该员工的所有信息都能够修改。
<7>对员工排序函数:void staffsort()
使用快速排序,对员工的编号进行排序。
5 程序编码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct staff { int id;///编号 char name[20];///姓名 char sex[20];///性别 char age[20];///出生年月 char clas[20];///学历 char duty[20];///职务 char tel[20];///电话 char addr[20];///住址 } s[1000]; int num; void staffinput()///输入员工信息 { int i,n; printf("请输入需要创建信息的职工人数n:\n"); scanf("%d",&n); num=n; for(i=0; i<n; i++) { printf("请输入员工编号: "); scanf("%d",&s[i].id); printf("请输入姓名: "); scanf(" %s",s[i].name); printf("请输入性别: "); scanf(" %s",&s[i].sex); printf("请输入出生年月: "); scanf(" %s",&s[i].age); printf("请输入学历: "); scanf(" %s",&s[i].clas); printf("请输入职务: "); scanf(" %s",&s[i].duty); printf("请输入电话: "); scanf(" %s",&s[i].tel); printf("请输入住址: "); scanf(" %s",s[i].addr); printf("\n"); } printf("创建完毕!\n"); } void staffdisplay()///展示员工信息 { int i; printf("\n员工编号\t姓名\t性别\t出生年月\t学历\t职务\t电话\t住址\n"); for(i=0; i<num; i++) { printf("\n%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",s[i].id,s[i].name,s[i].sex,s[i].age,s[i].clas,s[i].duty,s[i].tel,s[i].addr); } return ; } void s_change(int n)///更改员工信息 { int a,b; int id;///编号 char name[20];///姓名 char sex[20];///性别 char age[20];///出生年月 char clas[20];///学历 char duty[20];///职务 char tel[20];///电话 char addr[20];///住址 printf("确实需要修改此人的信息按1,否则按0\n"); scanf("%d",&a); if(a==1) { while(1) { printf("\n需要进行修改的选项\n 1.员工编号 2.姓名 3.性别 4.出生年月 5.学历 6.职务 7.电话 8.住址\n"); printf("请输入你想修改的那一项序号:\n"); scanf("%d",&b); if(b>8||b<1) { printf("\n选择错误,请重新选择!\n"); getchar(); continue; } else { switch(b) { case 1: printf("员工编号更改为:"); scanf("%d",&id); s[n].id=id; break; case 2: printf("姓名改为: "); scanf(" %s",name); strcpy(s[n].name,name); break; case 3: printf("性别改为: "); scanf(" %s",&sex); strcpy(s[n].sex,sex); break; case 4: printf("出生年月改为: "); scanf("%s",&age); strcpy(s[n].age,age); break; case 5: printf("学历改为: "); scanf("%s",&clas); strcpy(s[n].clas,clas); break; case 6: printf("职务改为: "); scanf("%s",&duty); strcpy(s[n].duty,duty); break; case 7: printf("电话改为: "); scanf("%s",&tel); strcpy(s[n].tel,tel); break; case 8: printf("住址改为: "); scanf("%s",addr); strcpy(s[n].addr,addr); break; } break; } } } } int my_cmp(staff a, staff b) { return a.id<b.id; } void staffsort()///按照编号给员工排序 { printf("这里按照员工编号排序:\n"); sort(s,s+num,my_cmp); printf("按照员工编号排序之后的记录:\n"); staffdisplay(); } void staffchange() { int a,b,c,i,j; char x[20]; printf("1.按照姓名查找需要修改员工的信息\n"); printf("2.按照工号查找需要修改员工的信息\n"); scanf("%d",&a); if(a==1) { getchar(); printf("请输入要修改信息的员工姓名\n"); scanf("%s",&x); for(i=0; i<num; i++) { if(strcmp(s[i].name,x)==0) { printf("找到此人,原始记录为:\n"); printf("\n员工编号\t姓名\t性别\t出生年月\t学历\t职务\t电话\t住址\n"); printf("\n%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",s[i].id,s[i].name,s[i].sex,s[i].age,s[i].clas,s[i].duty,s[i].tel,s[i].addr); s_change(i); break; } } if(i>=num) { printf("查无此人!!!\n"); } } if(a==2) { printf("请输入要修改信息的员工工号\n"); scanf("%d",&c); for(i=0; i<num; i++) { if(s[i].id==c) { printf("找到此人,原始记录为:\n"); printf("\n员工编号\t姓名\t性别\t出生年月\t学历\t职务\t电话\t住址\n"); printf("\n%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",s[i].id,s[i].name,s[i].sex,s[i].age,s[i].clas,s[i].duty,s[i].tel,s[i].addr); s_change(i); break; } } if(i>=num) { printf("查无此人!!!\n"); } } } void staffsearch() { int a,b,c; int i,j; char x[20]; printf("1.按照姓名查找员工信息\n"); printf("2.按照工号查找员工信息\n"); scanf("%d",&a); if(a==1) { getchar(); printf("请输入要查找员工的姓名\n"); scanf("%s",&x); for(i=0; i<num; i++) { if(strcmp(s[i].name,x)==0) { printf("找到此人,原始记录为:\n"); printf("\n员工编号\t姓名\t性别\t出生年月\t学历\t职务\t电话\t住址\n"); printf("\n%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",s[i].id,s[i].name,s[i].sex,s[i].age,s[i].clas,s[i].duty,s[i].tel,s[i].addr); break; } } if(i>=num) { printf("查无此人!!!\n"); } } if(a==2) { printf("请输入要查找员工的工号\n"); scanf("%d",&c); for(i=0; i<num; i++) { if(s[i].id==c) { printf("找到此人,原始记录为:\n"); printf("\n员工编号\t姓名\t性别\t出生年月\t学历\t职务\t电话\t住址\n"); printf("\n%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",s[i].id,s[i].name,s[i].sex,s[i].age,s[i].clas,s[i].duty,s[i].tel,s[i].addr); break; } } if(i>=num) { printf("查无此人!!!\n"); } } } void staffadd() { printf("请输入要插入的新员工的信息:\n"); int i; i=num; num++; printf("请输入员工编号: "); scanf("%d",&s[i].id); printf("请输入姓名: "); scanf(" %s",s[i].name); printf("请输入性别: "); scanf(" %s",&s[i].sex); printf("请输入出生年月: "); scanf(" %s",&s[i].age); printf("请输入学历: "); scanf(" %s",&s[i].clas); printf("请输入职务: "); scanf(" %s",&s[i].duty); printf("请输入电话: "); scanf(" %s",&s[i].tel); printf("请输入住址: "); scanf(" %s",s[i].addr); printf("\n"); } void staffdel()///删除员工记录 { int a,b,c; int i,j; char x[20]; printf("1.按照姓名删除员工信息\n"); printf("2.按照工号删除员工信息\n"); scanf("%d",&a); if(a==1) { getchar(); printf("请输入要删除员工的姓名\n"); scanf("%s",&x); for(i=0; i<num; i++) { if(strcmp(s[i].name,x)==0) { printf("找到此人,原始记录为:\n"); printf("\n员工编号\t姓名\t性别\t出生年月\t学历\t职务\t电话\t住址\n"); printf("\n%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",s[i].id,s[i].name,s[i].sex,s[i].age,s[i].clas,s[i].duty,s[i].tel,s[i].addr); printf("继续删除请按1,不再删除请按0\n"); scanf("%d",&b); if(b==1) { for(j=i; j<num-1; j++)///后面的内容移动到前面 { s[j].id=s[j+1].id; strcpy(s[j].name,s[j+1].name); strcpy(s[j].sex,s[j+1].sex); strcpy(s[j].age,s[j+1].age); strcpy(s[j].clas,s[j+1].clas); strcpy(s[j].duty,s[j+1].duty); strcpy(s[j].tel,s[j+1].tel); strcpy(s[j].addr,s[j+1].addr); } num--; } break; } } if(i>=num) { printf("查无此人!!!\n"); } } if(a==2) { printf("请输入要删除员工的工号\n"); scanf("%d",&c); for(i=0; i<num; i++) { if(s[i].id==c) { printf("找到此人,原始记录为:\n"); printf("\n员工编号\t姓名\t性别\t出生年月\t学历\t职务\t电话\t住址\n"); printf("\n%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",s[i].id,s[i].name,s[i].sex,s[i].age,s[i].clas,s[i].duty,s[i].tel,s[i].addr); printf("继续删除请按1,不再删除请按0\n"); scanf("%d",&b); if(b==1) { for(j=i; j<num-1; j++) { s[j].id=s[j+1].id; strcpy(s[j].name,s[j+1].name); strcpy(s[j].sex,s[j+1].sex); strcpy(s[j].age,s[j+1].age); strcpy(s[j].clas,s[j+1].clas); strcpy(s[j].duty,s[j+1].duty); strcpy(s[j].tel,s[j+1].tel); strcpy(s[j].addr,s[j+1].addr); } num--; } break; } } if(i>=num) { printf("查无此人!!!\n"); } } } void load() { printf("\n\n"); printf(" ******************欢迎进入职工信息管理系统****************\n"); printf(" 1.录入职工信息"); printf(" 2.浏览职工信息\n"); printf(" 3.查询职工信息"); printf(" 4.删除职工信息\n"); printf(" 5.添加职工信息"); printf(" 6.修改职工信息\n"); printf(" 7.排序职工信息\n"); printf(" 8.退出\n"); printf(" ********************谢谢使用******************\n"); printf("\n"); return ; } int main() { int n; int flag=1; char a; num=0; while(1) { load();/*调用菜单函数*/ printf("请选择你需要操作的步骤(1--8):\n"); scanf("%d",&n); if(n>=1&&n<=8) { flag=0; switch(n) { case 1: printf(" *****输入职工信息*****\n"); printf("\n"); staffinput(); break; case 2: printf(" *****浏览职工信息*****\n"); printf("\n"); staffdisplay(); break; case 3: printf(" *****按职工号或姓名查询职工信息*****\n"); printf("\n"); staffsearch(); break; case 4: printf(" *****删除职工信息*****\n"); printf("\n"); staffdel(); break; case 5: printf(" *****添加职工信息*****\n"); printf("\n"); staffadd(); break; case 6: printf(" *****修改职工信息*****\n"); printf("\n"); staffchange(); break; case 7: printf(" *****对职工信息排序*****\n"); printf("\n"); staffsort(); break; default : return 0; } } else { printf("您输入有误,请重新选择!\n"); getchar(); continue; } } return 0; }
6 程序调试与测试
1)菜单目录:
2)输入员工信息:
3)显示全部员工信息:
4)查询员工信息:
按姓名和工号查找
5)删除员工信息:
删除后的所有数据:
6)修改员工信息:
修改后的记录:
7)员工信息排序:
按照员工的编号排序:
7 结果分析
这里只有员工编号为整数型,其他的都是字符串类型,因而错误类型的输入会造成乱码和死循环的产生。该程序主要是基于结构体数组来实现排序和输出的,因而属于顺序表,遍历输出的时间复杂度是O(n),空间复杂度也是O(n)。同时在这里删除某一员工的记录后,需要将其后面的所有记录都要向前移动一位,会花费一些时间;而插入一条记录只需要早顺序表之后添加即可。排序所使用的快速排序时间复杂度是O(nlogn)~O(n^2),空间复杂度是O(logn)~O(n)。
8 总结
该程序能够完成员工信息的查询、更新、插入、删除、排序等功能。基本达到了题目要求的目标了。但仍然存在着一些问题,比如在实现排序功能的时候,该程序仅仅实现了按照员工编号排序的功能,这也与程序的要求有关。比如如果按照职务排序,计算机并不能去识别到底哪一个职务大,更何况不同的公司有不同的情况,这只能在编写程序的时候按照该公司的职务安排提前规定各个职务的优先级,学历也是如此。该程序在任务要求中并没有规定这些,就导致了漏洞很大。同时该程序使用的是顺序表类型的存储结构,虽然实现了随机存取,但在删除记录信息的过程中需要挪动被删记录之后的所有记录,耗时间。编写该程序并不是很难,但从这次程序中,我学到了以后工作时需要多与客户和产品经理交流沟通,明确客户的需求,减少程序中的漏洞,从实际出发,编写合适有效的程序。