该系统具有以下主要功能:
- 添加人员信息:在有空间的前提下,用户输入人员的工号、姓名、性别、联系电话和 QQ 号等信息,系统会自动检查编号的唯一性,确保不重复。
- 查找人员信息:提供按工号和姓名两种查找方式,找到后会显示相应人员的详细信息。
- 修改人员信息:可以按工号或姓名进行修改,修改时编号不能更改。
- 删除人员信息:同样支持按工号和姓名删除,删除前会进行确认。
- 统计人员数量:能给出当前公司人员的总数。
- 显示人员信息:可以展示全体人员的信息或指定单个人员的信息。
- 保存和读取文件:能将人员信息保存到指定文件,也能从文件中读取人员信息。
- 排序人员信息:提供插入排序和冒泡排序两种方式,可对人员按工号进行排序。
#include<stdio.h>
#include<stdlib.h> //内存管理
#include<string.h> //串操作
//数据元素结构
typedef struct
{ int no; //编号
char name[20]; //姓名
int sex; //性别
char tel[14]; //联系电话
char qq[12]; //QQ号
}ElemType;
//链表表结构
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode;
void Edit(LNode *L); //修改子菜单
void Delete(LNode *L) ; //删除子菜单
void Search(LNode *head); //查找子菜单
void Sort(LNode *head); //排序子菜单
void DestroyList(LNode *head); //销毁链表
void Add(LNode *head); //添加人员
int Unique(LNode *head,int n) ; //判别工号n是否已经存在
void PrintList(LNode *head); ///显示功能
void Total(LNode *head) ; //统计人员数目
void Edit_num(LNode *head); //按编号修改
void Edit_name(LNode *head); //按姓名修改
void Delete_num(LNode *head); /按编号进行删除
void Delete_name(LNode *head); /按姓名进行删除
void Save(LNode *head); /存文件
void Read(LNode *head); /读文件
void Search_num(LNode *head); //按编号进行查找
void Search_name(LNode *head); //按姓名进行查找
void SelectSort(LNode *head); //选择排序
void BubbleSort(LNode *head); //冒泡排序
int main()
{
printf(" ### 欢迎进入人员管理系统 ###\n");
链表初始化
LNode *head; ///
head = (LNode *)malloc(sizeof(LNode)); //创建头结点
head->next =NULL;
int choice=1;
while(choice!=0)
{
printf("ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
printf("| |\n");
printf("|1.添加 2.查找 3.修改 4.统计 5.删除 6.显示 7.保存 8.读取 9.排序 0.返回|\n");
printf("| |\n");
printf("ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
printf("输入您操作的选项:");
scanf("%d",&choice);
switch(choice)
{
case 1:Add(head); //添加人员信息
break;
case 2:Search(head);//查找
break;
case 3:Edit(head);//调用修改二级菜单
break;
case 4:Total(head);//统计
break;
case 5:Delete(head);//调用删除菜单
break;
case 6:PrintList(head);//显示
break;
case 7:Save(head); /存文件
break;
case 8:Read(head); /读文件
break;
case 9:Sort(head); //排序三级子菜单//排序
break;
case 0:DestroyList(head); //销毁链表
printf("退出成功!\n");
break;
default:
printf("无此选项,请重试!\n");
break;
}
}
printf(" ooooo欢迎您使用本系统!ooooo\n");
return 0;
}
///销毁链表函数
void DestroyList(LNode *head)
{ LNode *q,*p=head;//让p指向头结点
while(p!=NULL)
{ q=p->next;//让q指向头结点的后续结点
free(p);//删除p
p=q;
}
head=NULL;
}
添加人员信息
void Add(LNode *head)
{
LNode *q,*p=head;
//找链表尾部地址p
q=p->next;
while(q!=NULL)
{
p=q;
q=q->next;
}
printf("正在添加人员......\n");
q= (LNode *)malloc(sizeof(LNode)); //创建新结点
q->next=NULL;
printf("请输入数据(工号 姓名 性别(0或1) 联系电话 QQ号):\n");
scanf("%d%s%d%s%s",&q->data.no,q->data.name , &q->data.sex , q->data.tel ,q->data.qq);
if(Unique(head,q->data.no))
{
printf("该编号已存在,添加失败!\n");
free(q);
return;
}
p->next=q;
printf("添加成功!!!\n\n");
}
/判别工号唯一性,1---不唯一;0---唯一
int Unique(LNode *head,int n)
{
LNode *p=head->next;
while(p!=NULL)
{ if(p->data.no==n) return 1;
p=p->next ;
}
return 0;
}
///显示功能
void PrintList(LNode *head)
{ if (!head->next) {printf("没有人员信息!\n");return;}
LNode *p;
p=head->next;
printf("学号 姓名 性别 电话 QQ号\n");
printf("-----------------------------------------------------\n");
while(p!=NULL)
{ printf("%d\t%s\t",p->data.no,p->data.name);
if(p->data.sex) printf("男 "); else printf("女 ");
printf("%s\t%6s\n",p->data .tel,p->data.qq);
printf("-----------------------------------------------------\n");
p=p->next ;
}
}
//统计人员数目
void Total(LNode *head)
{
LNode *p;
int count=0;
p=head->next;
while(p!=NULL)
{ count++;
p=p->next ;
}
printf("人员总人数为:%d人\n",count);
}
修改功能/
/
void Edit(LNode *head) //修改二级子菜单
{
if (!head->next) {printf("没有人员信息!\n");return;}
int choice=1;
do{
printf(" ooooo修改ooooo\n");
printf("|| ||\n");
printf("|| 1 : 按工号 2 : 按姓名 0 :退出 ||\n");
printf("|| ||\n");
printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
printf("请输入您的选择:");
scanf("%d",&choice);
switch(choice)
{
case 1:Edit_num(head);
break;
case 2:Edit_name(head);
break;
case 0:printf("您已安全退出!\n");
break;
default:printf("没有此选项,请重选!\n");
break;
}
}while(choice!=0);
}
void Edit_num(LNode *head) //按编号修改
{
int x;
printf("请输入要修改的人员的编号:");
scanf("%d",&x);
LNode *p=head->next;
while(p!=NULL)
{
if(p->data.no==x)
{
printf("请输入数据(工号 姓名 性别(0或1) 联系电话 QQ号):\n");
scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel ,p->data.qq);
while(p->data.no!=x)
{
printf("编号不能修改!");
printf("请输入数据(工号 姓名 性别(0或1) 联系电话 QQ号):\n");
scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel ,p->data.qq);
}
printf("修改成功!\n");
return;
}
p=p->next ;
}
printf("该人员不存在!\n");
}
void Edit_name(LNode *head) //按姓名修改----存在重名现象
{
char nam[20],c1;
printf("请输入要编辑的人员的姓名:");
scanf("%s",nam);
LNode *p=head->next;
while(p!=NULL)
{
if(strcmp(p->data.name,nam)==0)
{ int n=p->data.no;
printf("%d\t%s\t",p->data.no,p->data.name);
if(p->data.sex) printf("男 "); else printf("女 ");
printf("%s\t%6s\n",p->data .tel,p->data.qq);
printf("要修改这条记录吗?(是:y/Y,否:n/N):");
fflush(stdin);
scanf("%c",&c1);
if(c1=='y'||c1=='Y')
{ printf("请输入数据(工号 姓名 性别(0或1) 联系电话 QQ号):\n");
scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel ,p->data.qq);
while(p->data.no!=n)
{
printf("编号不能修改!");
printf("请输入数据(工号 姓名 性别(0或1) 联系电话 QQ号):\n");
scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel ,p->data.qq);
}
printf("修改成功!\n");
return;
}
}
p=p->next ;
}
printf("该人员不存在!\n");
}
删除功能/
/
void Delete(LNode *head) //删除子菜单
{
if (!head->next) {printf("没有技术人员信息!\n");return;}
int choice;
do{
printf(" ooooo删除ooooo\n");
printf("|| ||\n");
printf("|| 1 : 按工号 2 : 按姓名 0 :退出 ||\n");
printf("|| ||\n");
printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
printf("请输入您的选择:");
scanf("%d",&choice);
switch(choice)
{
case 1:Delete_num(head);
break;
case 2:Delete_name(head);
break;
case 0:printf("您已安全退出删除功能!\n");
break;
default:printf("没有此选项,请重选!\n");
break;
}
}while(choice!=0);
}
void Delete_num(LNode *head) /按工号进行删除
{
char c1;
int x;
printf("请输入要删除的人员的编号:");
scanf("%d",&x);
LNode *q=head,*p; //q前驱结点,p被删除结点
while(q->next!=NULL)
{ p=q->next;
if(p->data.no==x)
{
printf("%d\t%s\t",p->data.no,p->data.name);
if(p->data.sex) printf("男 "); else printf("女 ");
printf("%s\t%6s\n",p->data .tel,p->data.qq);
break;
}
q=q->next;
}
if(q->next==NULL)
{
printf("无此人员!");
return ;
}
printf("是否删除此项(是:y/Y,否:n/N):");
fflush(stdin);
scanf("%c",&c1);
if(c1=='y'||c1=='Y')
{
q->next=p->next; //删除p结点
free(p); //释放空间
printf("删除成功!\n");
return ;
}
else
printf("没有删除该人员!\n");
}
void Delete_name(LNode *head) /按姓名进行删除----姓名可能相同
{
char c1;
char nam[20];
printf("请输入要删除的人员的姓名:");
scanf("%s",nam);
LNode *q=head,*p; //q前驱结点,p被删除结点
while(q->next!=NULL)
{ p=q->next;
if(strcmp(p->data.name,nam)==0)
{
printf("%d\t%s\t",p->data.no,p->data.name);
if(p->data.sex) printf("男 "); else printf("女 ");
printf("%s\t%6s\n",p->data .tel,p->data.qq);
printf("要删除这条记录吗?(是:y/Y,否:n/N):");
fflush(stdin);
scanf("%c",&c1);
if(c1=='y'||c1=='Y') break;
}
q=q->next;
}
if(q->next==NULL)
{
printf("无此人员!");
return ;
}
printf("是否删除此项(是:y/Y,否:n/N):");
fflush(stdin);
scanf("%c",&c1);
if(c1=='y'||c1=='Y')
{
q->next=p->next; //删除p结点
free(p); //释放空间
printf("删除成功!\n");
return ;
}
else
printf("没有删除该人员!\n");
}
///
void Save(LNode *head) /存文件
{
FILE *fp = NULL;
fp = fopen("D:\\人员管理.txt", "w");
if(!fp)
{ printf("文件打开出错\n");
return;
}
LNode *p;
p=head->next;
while(p!=NULL)
{
fprintf(fp,"\n%d\t",p->data.no); //写进磁盘保存,以下同理
fprintf(fp,"%s\t",p->data.name);
fprintf(fp,"%d\t",p->data.sex);
fprintf(fp,"%s\t",p->data.tel);
fprintf(fp,"%s",p->data.qq);
p=p->next;
}
printf("保存成功!\n");
fclose(fp);
}
void Read(LNode *head) /读文件
{
//清空所有数据结点
LNode *q,*p=head->next;//让p指向一个数据结点
while(p!=NULL)
{ q=p->next;//让q指向头结点的后续结点
free(p);//删除p
p=q;
}
head->next=NULL;
/
//打开文件
FILE *fp = NULL;
fp = fopen("D:\\人员管理.txt", "r");
if(!fp)
{ printf("文件打开出错\n");
return;
}
//尾插入法构建链表
q=head;
while(!feof(fp))
{
p=(LNode *)malloc(sizeof(LNode)); //创建数据结点
fscanf(fp, "%d%s%d%s%s", &p->data.no,p->data.name,&p->data.sex,p->data.tel,p->data.qq);
q->next=p;
q=p;
}
p->next=NULL;
printf("读取成功!\n");
fclose(fp);
}
//
void Search(LNode *head) //查找子菜单
{
if (!head->next) {printf("没有人员信息!\n");return;}
int choice;
do{
printf(" ooooo查找ooooo\n");
printf("|| ||\n");
printf("|| 1 : 按工号 2 : 按姓名 0 :退出 ||\n");
printf("|| ||\n");
printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
printf("请输入您的选择:");
scanf("%d",&choice);
switch(choice)
{
case 1:Search_num(head);
break;
case 2:Search_name(head);
break;
case 0:printf("您已安全退出查找功能!\n");
break;
default:printf("没有此选项,请重选!");
break;
}
}while(choice!=0);
}
void Search_num(LNode *head) //按编号进行查找
{
int x;
printf("请输入要查找的人员的工号:");
scanf("%d",&x);
LNode *p=head->next;
while(p!=NULL)
{
if(p->data.no==x) //找到后,显示该记录信息
{
printf("%d\t%s\t",p->data.no,p->data.name);
if(p->data.sex) printf("男 "); else printf("女 ");
printf("%s\t%6s\n",p->data .tel,p->data.qq);
break;
}
p=p->next;
}
if(p==NULL)
{
printf("无此工号的人员!");
return ;
}
}
void Search_name(LNode *head) //按姓名进行查找--顺序查找--可能重名
{
char nam[20];
int flag=0;
printf("请输入要查找的人员的姓名:");
scanf("%s",nam);
LNode *p=head->next;
while(p!=NULL)
{
if(strcmp(p->data.name,nam)==0) //找到后,显示该记录信息
{ if(flag)
printf("oooooooooooo又找到了一个,其信息为:oooooooooooo\n");
else
printf("oooooooooooo 找到了,其信息为: oooooooooooo\n");
printf("%d\t%s\t",p->data.no,p->data.name);
if(p->data.sex) printf("男 "); else printf("女 ");
printf("%s\t%6s\n",p->data .tel,p->data.qq);
flag=1;
}
p=p->next;
}
if(!flag) printf("该人员不存在!\n");
}
//
void Sort(LNode *head) //排序子菜单
{
if (!head->next) {printf("没有人员信息!\n");return;}
int choice;
do{
printf(" ooooo查找ooooo\n");
printf("|| ||\n");
printf("|| 1 : 选择排序 2 : 冒泡排序 0 :退出 ||\n");
printf("|| ||\n");
printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
printf("请输入您的选择:");
scanf("%d",&choice);
switch(choice)
{
case 1:SelectSort(head);
break;
case 2:BubbleSort(head);
break;
case 0:printf("您已安全退出排序功能!\n");
break;
default:printf("没有此选项,请重选!");
break;
}
}while(choice!=0);
}
void SelectSort(LNode *head) //直接选择排序
{
LNode *p,*q,*min;
ElemType t;
p=head->next; //p指向第一个数据结点
while (p!=NULL)
{
min=p;
q=p->next;
while(q!=NULL) //找最小值结点地址min
{
if(q->data.no<min->data.no)
min=q;
q=q->next;
}
if(min!=p) //若不是最前面,则交换
{ t=p->data;
p->data=min->data;
min->data=t;
}
p=p->next;
}
printf("排序完毕!\n");
PrintList(head);
}
void BubbleSort(LNode *head) //冒泡排序
{ ElemType t;
LNode *tail,*p,*next;//tail代表链表每一次排序后的未排序链表的最后一个节点
if(head->next==NULL)
{ printf("无记录!\n");
return;
}
for(p=head;p->next!=NULL;p=p->next);//找尾结点地址p
tail=p;
while(tail!=head->next)
{
for(p = head->next ;p!=tail;p=p->next)
{
if(p->data.no>p->next->data.no)//比较p节点和p->next节点的data大小
{
t=p->data;p->data=p->next->data;p->next->data=t;
}
next=p;
}
tail = next;
}
printf("排序完毕!\n");
PrintList(head);
}