员工工资管理系统
实现功能
- 程序中的数据存储到文件中。
- 可以录入员工工资信息,格式如下:
(工号(8位) 姓名、部门、年份、月份、应发工资,实发工资)
其中,实发工资=应发工资-税费,税费扣除方法请自行调查。实发工资由系统自动计算。- 输出所有员工工资信息。
- 先按年份升序输出,同一年的工资信息按月份升序输出,同一月的工资信息按工号升序输出。
- 先按部门降序输出,同一部门的工资信息按实发工资升序输出
- 可以删除某个员工的工资信息。(删除时按工号删除)。
- 工资查询
- 根据姓名查找该员工的工资信息,若有同名,则输出所有同名员工的工资信息。
- 根据部门查找该部门的所有工资信息,并按实发工资降序 输出。
- 根据所给的年份和月份,查询该月份所有员工的工资信息,按部门降序显示。
- 统计
- 统计每个员工入职以来的平均工资,并按升序输出统计信息。
- 统计某年中,每个部门总工资最高的前三名和总工资最低的后三名,并输出统计信息。
- 统计某年月每个部门所有员工的纳税总额,按部门升序显。
头文件
//员工工资管理系统头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <wchar.h>
#include <io.h> //判断文件是否存在
#define filename "staff.txt" //保存的文件名称
/*
* 存储方案
* 顺序依次为:年份,月份,部门,员工编号
*/
typedef struct
{
int id; //工号
char name[20]; //姓名
char department[20];//部门
int year; //年份
int month; //月份
float salary; //应发工资
float realsalary; //实发工资
}Employee;
//链表结构体
typedef struct Node
{
Employee data; //员工信息
struct Node* next; //下一个节点指针
}Node,*NodeList;
//员工信息链表结构体
typedef struct
{
struct Node* head; //头结点
int size; //链表长度
}EmployeeList,*LinkList;
typedef struct average
{
int id;
char* name;
float a_salary;
struct average* next;
}average;
typedef struct salary
{
int id;
char* name;
float all_salary;
char* department;//部门
struct salary* next;
}salary;
//纳税表 计算税率的时候可以初始化此表
//typedef
// 初始化链表
//存储所有用户数据
LinkList list;
void InsertList(Node* );
//计算税费 参数:工资
float tax(float salary);
//主菜单框架
void menu_frame();
//菜单底部框架
void menu_bottom_frame();
//对用输入进入子菜单进行分配
void menu();
//主菜单无参数输入,返回用户输入的子菜单系统
int main_menu();
//信息录入菜单
void information_menu();
//员工工资查询菜单
void staff_search_menu();
//删除员工信息菜单
void delete_staff_menu();
//工资查询菜单
void staff_salary_search();
//进入统计功能菜单
void staff_statistics();
//文件保存功能 将结构体文件保存到本地
void save_staff(LinkList);
void open_staff_file();
//输出链表
// 输出链表
void printList(LinkList list);
//按年月份升序(同一月工号升序)
void sort_month(LinkList list);
//按照部门降序,实发工资升序
void sort_department(LinkList list);
//根据员工工号删除员工的信息
void delete_id(LinkList list,int id);
//根据姓名搜索所有员工工资信息
void search_name_salary(LinkList list, char name[20]);
//查找部门所有员工信息,按实发工资降序
//传入参数 部门
void dept_staff(LinkList list, char department[20]);
//根据年月,按部门降序输出所有员工工资
//参数链表,年份,月份
void year_month_salary(LinkList list, int year, int month);
//统计部分
//入职以来每个员工的平均工资,升序
void sort_id(LinkList list);
//TODO
void every_staff_average_salary(LinkList list);
//根据年份,总工资前三名,和最后三名
//根据部门输出员工信息,工资降序 得出前三名最高工资,最后三名最低
void dept_max_min(LinkList list,int year);
//参数 :年月
//输出 :部门 纳税总额
//部门升序输出
//计算出每个人的纳税总额
void year_month_tax_all(LinkList list, int year, int month);
实现函数
//员工工资管理系统算法实现函数
#include "head.h"
void menu()
{
//根据主菜单用户输入,分配子系统
switch (main_menu())
{
case 1:
system("cls"); //对cmd页面信息进行清空
//printf("进入信息录入");
information_menu();
break;
case 2:
system("cls");
//printf("进入员工信息查询");
staff_search_menu();
break;
case 3:
system("cls");
//printf("删除员工信息");
delete_staff_menu();
break;
case 4:
system("cls");
//printf("工资查询");
staff_salary_search();
break;
case 5:
system("cls");
//printf("进入统计功能");
staff_statistics();
break;
case 0:
system("cls");
printf("\t\t\t\t正在退出员工工资系统.....");
exit(0);
break;
default:
system("cls");
printf("\t\t\t\t请重新输入!");
menu();
break;
}
}
float tax(float salary)
{
//强制取整数
//int t_salary = (int)salary;
float tax_need; //需要交的税额
//使用switch根据不同工资计算出其所需要的交的money
//参数必须为整形
//除以5000根据其得出的结果,判断其税率区间
//税率计算使用超额累进税率
if (salary <= 5000)
{
tax_need = 0;
}
else if (salary > 5000 && salary <= 8000)
{
tax_need = (salary - 5000) * 0.03;
}
else if (salary > 8000 && salary <= 17000)
{
//工资大于8000小于17000
//5000~8000按照3%税率,超过8000的部分按照10%
tax_need = (8000 - 5000) * 0.03 + (salary - 8000) * 0.1;
}
else if (salary > 17000 && salary <= 30000)
{
//工资在17000到30000之间
tax_need = (8000-5000) * 0.03 + (17000 - 8000) * 0.1 + (salary - 17000)*0.2;
}
else if (salary > 30000 && salary <= 40000)
{
//工资在30000到40000之间
tax_need = (8000 - 5000) * 0.03 + (17000 - 8000) * 0.1 + (30000 - 17000) * 0.2
+ (salary - 30000) * 0.25;
}
else if (salary > 40000 && salary <= 60000)
{
//工资在4万 到6万之间
tax_need = (8000 - 5000) * 0.03 + (17000 - 8000) * 0.1 + (30000 - 17000) * 0.24
+ (40000 - 30000) * 0.25 + (salary - 40000) * 0.3;
}
else if (salary > 60000 && salary <= 85000)
{
//工资在6万 到8.5万之间
tax_need = (8000 - 5000) * 0.03 + (17000 - 8000) * 0.1 + (30000 - 17000) * 0.2
+ (40000 - 30000) * 0.25 + (60000 - 40000) * 0.3 + (salary - 60000) * 0.35;
}
else if (salary > 85000)
{
//工资大于8.5万的部分45%
tax_need = (8000 - 5000) * 0.03 + (17000 - 8000) * 0.1 + (30000 - 17000) * 0.2
+ (40000 - 30000) * 0.25 + (60000 - 40000) * 0.3 + (85000 - 60000) * 0.35
+ (salary - 85000) * 0.45;
}
return tax_need;
}
//将节点数据插入到list表中
void InsertList(Node* n)
{
Node *n_list = (Node*)malloc(sizeof(Node));
n_list = n;
n_list->next = NULL;
LinkList listIsert = list;
//list中的总长度+1
if (listIsert->head == NULL)
{
listIsert->size++;
listIsert->head = n_list;
return;
}
Node* N_list = (NodeList)malloc(sizeof(NodeList));;
N_list = NULL;
N_list = listIsert->head;
//根据n的信息判断插入位置
for (int i = 0; i < listIsert->size; i++)
{
if (n_list->data.id <= N_list->data.id )
{
n_list->next = N_list;
//N_list = &n;
listIsert->head = n_list;
listIsert->size++;
return;
}
//TODO
//else if (n.data.id > N_list->data.id && N_list->next != NULL)
else if (n_list->data.id > N_list->data.id )
{
n_list->next = N_list->next;
N_list->next = n_list;
listIsert->size++;
return;
}
else
{
N_list = N_list->next; //往后循环
}
}
//li->head->next = N_list;
}
void save_staff(LinkList list_file)
{
int ch;
//TODO保存文件
FILE* fp = NULL;
fp = fopen(filename, "w"); //文件以只读的形式
if (fp == NULL)
{
printf("%s\n", strerror(errno));
}
//根据ID进行排序保存
sort_id(list);
//将头文件存入
int length = list_file->size;
NodeList staff = list_file->head;
//写入数据
for(int i=0;i<length;i++)
{
fprintf(fp, "%d %s %s %d %d %.2f %.2f\n",
staff->data.id,staff->data.name,staff->data.department,staff->data.year,staff->data.month,staff->data.salary,staff->data.realsalary );
staff = staff->next;
}
fclose(fp);
fp = NULL;
}
void open_staff_file()
{
int ch; //用int类型的变量存储EOF
FILE* fp = NULL;
fp = fopen(filename, "r");
while (!feof(fp))
{
struct Node *staff = (Node*)malloc(sizeof(Node));;
staff->data.id = NULL;
staff->next = NULL;
if (fscanf(fp, "%d %s %s %d %d %f %f\n",
&staff->data.id, staff->data.name, staff->data.department,
&staff->data.year, &staff->data.month, &staff->data.salary, &staff->data.realsalary) != 7)
{
break;
}
if (staff->data.id != NULL)
{
InsertList(staff);
}
}
fclose(fp);
fp = NULL;
}
void menu_frame()
{
system("cls");
printf("\n");
printf("\t\t\t\t 欢迎进入员工工资管理系统!您可以进行以下操作!\n");
printf("\t\t\t\t********************************************\n");
printf("\t\t\t\t 员工工资管理系统 \n");
printf("\t\t\t\t********************************************\n");
printf("\t\t\t\t\tNo.0—————[0]退 出 | 返回 主 系 统 \n");
}
void menu_bottom_frame()
{
printf("\t\t\t\t\tNo.2*****[其它]返回上一层 \n");
printf("\n\n");
printf("\t\t\t\t====>请输入相对应的信息:");
}
int main_menu()
{
int choose;
menu_frame();
printf("\t\t\t\t\tNo.1—————[1]信息录入 \n");
printf("\t\t\t\t\tNo.2—————[2]查看员工信息 \n");
printf("\t\t\t\t\tNo.3—————[3]删除员工信息 \n");
printf("\t\t\t\t\tNo.4—————[4]工资查询 \n");
printf("\t\t\t\t\tNo.5—————[5]统计功能 \n");
menu_bottom_frame();
scanf("%d", &choose);
return choose;
}
//插入员工信息
void information_menu()
{
//定义员工节点
struct Node *staff =(Node*)malloc(sizeof(Node)); ;
staff->next = NULL;
menu_frame();
printf("\t\t\t\t\tNo.0*****员工信息目录: \n");
printf("\n\n\t\t\t\t====>请输入对应的用户信息(空格分割):\n");
printf("\n\t\t\t\t\tNo.1*****[1]年份:");
scanf("%d",&staff->data.year);
printf("\n\t\t\t\t\tNo.2*****[2]月份:");
scanf("%d", &staff->data.month);
printf("\n\t\t\t\t\tNo.2*****[3]部门(营销部,开发部,人事部):");
scanf("%s", &staff->data.department);
printf("\n\t\t\t\t\tNo.3*****[3]工号(8位):");
scanf("%d", &staff->data.id);
printf("\n\t\t\t\t\tNo.2*****[2]姓名:");
scanf("%s", &staff->data.name);
printf("\n\t\t\t\t\tNo.2*****[2]应发工资:");
scanf("%f", &staff->data.salary);
staff->data.realsalary = staff->data.salary - tax(staff->data.salary);
printf("\t\t\t\t\tNo.1*****工号:%d\n \t\t\t\t\tNo.4*****姓名:%s\n\t\t\t\t\tNo.4*****部门: %s\n \t\t\t\t\tNo.4*****年份:%d\n \t\t\t\t\tNo.4*****月份:%d\n \t\t\t\t\tNo.4*****应发工资:%.2f\n \t\t\t\t\tNo.4*****实发工资:%.2f\n",
staff->data.id, staff->data.name, staff->data.department, staff->data.year, staff->data.month, staff->data.salary,staff->data.realsalary);
int choose;
printf("\n\n");
printf("\t\t\t\t\tNo.1*****[1]保存继续添加信息\n");
printf("\t\t\t\t\tNo.2*****[2]删除不保存,重新添加信息\n");
printf("\t\t\t\t\tNo.3*****[3]退出不保存信息\n");
printf("\t\t\t\t\tNo.4*****[其它]退出保存信息\n");
printf("\n\n\t\t\t\t====>请输入对应的用户信息(空格分割):");
scanf("%d", &choose);
switch (choose)
{
case 1:
//插入输入函数,传入Node节点
InsertList(staff);
save_staff(list);
//继续添加数据
information_menu();
break;
case 2:
//不保存继续添加数据
information_menu();
break;
case 3:
//不保存退回到主菜单
main_menu();
break;
default:
//插入输入函数,传入Node节点
InsertList( staff);
save_staff(list);
main_menu();
break;
}
}
//员工信息搜索菜单
void staff_search_menu()
{
int choose;
menu_frame();
printf("\t\t\t\t\tNo.0*****请选择输出方式: \n");
printf("\t\t\t\t\tNo.1*****[1]按年月份升序(同一月工号升序) \n");
printf("\t\t\t\t\tNo.2*****[2]按照部门降序(实发工资升序) \n");
menu_bottom_frame();
scanf("%d", &choose);
switch (choose)
{
case 1:
//TODO按年月份升序(同一月工号升序)
system("cls");
sort_month(list);
printf("\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回员工信息输出 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
int i;
scanf("%d", &i);
switch (i)
{
case 0:
exit(0);
break;
case 1:
staff_search_menu();
break;
default:
main_menu();
}
case 2:
//TODO按照部门降序(实发工资升序)
//按照部门降序(实发工资升序)
system("cls");
sort_department(list);
printf("\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回员工信息输出 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
int m;
scanf("%d", &m);
switch (m)
{
case 0:
exit(0);
break;
case 1:
staff_search_menu();
break;
default:
main_menu();
}
default:
//返回上一层
main_menu();
}
}
//删除员工信息菜单
void delete_staff_menu()
{
int id; //员工if
menu_frame();
printf("\t\t\t\t\tNo.2*****[0]返回上一层 \n");
printf("\t\t\t\t\tNo.2*****[工号]要删除的员工工号: \n ");
printf("\n\n");
menu_bottom_frame();
scanf("%d", &id);
switch (id)
{
case 0:
//返回主菜单
menu();
break;
default:
//根据工号删除相应的员工信息
printf("删除员工信息");
//进入删除员工处理,传入参数id
delete_id(list, id);
break;
};
}
//员工工资查询菜单
void staff_salary_search()
{
int choose;
int m;
menu_frame();
printf("\t\t\t\t\tNo.0*****请选择输出方式: \n");
printf("\t\t\t\t\tNo.1*****[1]根据姓名查询(同名全部输出) \n");
printf("\t\t\t\t\tNo.2*****[2]根据部门查询(实发工资降序) \n");
printf("\t\t\t\t\tNo.2*****[3]根据年月查询(月份部门降序) \n");
menu_bottom_frame();
char name[20];
char department[20];
int year;
int month;
scanf("%d", &choose);
switch (choose)
{
case 1:
//根据姓名查询(同名全部输出)
printf("\n\n\t\t\t\t====>请输入您要查询的员工姓名:");
scanf("%s", &name);
search_name_salary(list,name);
printf("\n\n\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回上一级 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
scanf("%d", &m);
switch (m)
{
case 0:
exit(0);
break;
case 1:
staff_salary_search();
break;
default:
main_menu();
}
break;
case 2:
//根据部门查询(实发工资降序)
printf("\n\n\t\t\t\t====>请输入您要查询的部门:");
scanf("%s", &department);
dept_staff(list, department);
printf("\n\n\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回上一级 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
scanf("%d", &m);
switch (m)
{
case 0:
exit(0);
break;
case 1:
staff_salary_search();
break;
default:
main_menu();
}
break;
break;
case 3:
//根据年月查询(月份部门降序)
printf("\n\n\t\t\t\t====>请输入您要查询的年份:");
scanf("%s", &year);
printf("\n\t\t\t\t====>请输入您要查询的月份:");
scanf("%s", &month);
year_month_salary(list,year,month);
printf("\n\n\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回上一级 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
scanf("%d", &m);
switch (m)
{
case 0:
exit(0);
break;
case 1:
staff_salary_search();
break;
default:
main_menu();
}
break;
break;
default:
//返回主菜单
menu();
break;
};
}
//员工工资统计
void staff_statistics()
{
int choose;
int year =0;
int month =0;
int m;
menu_frame();
printf("\t\t\t\t\tNo.0*****请选择输出方式: \n");
printf("\t\t\t\t\tNo.1*****[1]每个员工平均工资(升序) \n");
printf("\t\t\t\t\tNo.2*****[2]年份工资前三名和后三名 \n");
printf("\t\t\t\t\tNo.2*****[3]某年月每个部门纳税总额(按部门升序显示) \n");
menu_bottom_frame();
scanf("%d", &choose);
switch (choose)
{
case 1:
//每个员工平均工资(升序)
//sort_id(list);
every_staff_average_salary(list);
printf("\n\n\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回上一级 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
scanf("%d", &m);
switch (m)
{
case 0:
exit(0);
break;
case 1:
staff_statistics();
break;
default:
main_menu();
}
break;
case 2:
//年份工资前三名和后三名
printf("\n\n\t\t\t\t====>请输入您要查询的年份:");
scanf("%d",&year);
dept_max_min(list,year);
printf("\n\n\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回上一级 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
scanf("%d", &m);
switch (m)
{
case 0:
exit(0);
break;
case 1:
staff_statistics();
break;
default:
main_menu();
}
break;
case 3:
//TODO某年月每个部门纳税总额(按部门升序显示)
printf("\n\n\t\t\t\t====>请输入您要查询的年份:");
scanf("%d", &year);
printf("\n\t\t\t\t====>请输入您要查询的月份:");
scanf("%d", &month);
year_month_tax_all(list,year, month);
printf("\n\n\t\t\t\t\tNo.1*****[0]退出系统 \n");
printf("\t\t\t\t\tNo.2*****[1]返回上一级 \n");
printf("\t\t\t\t\tNo.2*****[3]返回主菜单 \n");
printf("\t\t\t\t====>请输入相对应功能的编号(:");
scanf("%d", &m);
switch (m)
{
case 0:
exit(0);
break;
case 1:
staff_statistics();
break;
default:
main_menu();
}
break;
default:
//返回主菜单
menu(list);
break;
}
}
//对链表输出
void printList(LinkList list)
{
Node* p;
p = list->head;
while (p != NULL)
{
printf("\t\t\t\t\t%d %s %s %d %d %.2f %.2f\n", p->data.id, p->data.name, p->data.department, p->data.year, p->data.month, p->data.salary, p->data.realsalary);
p = p->next;
}
}
//根据年份月份工号排序
void sort_month(LinkList list)
{
//对list数据从首位开始,另一个依次向后,根据年份,月份,工号的顺序,若比首位小,两者交换顺序,依次类推到最后实现排序
Node* p, * q, * temp; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
temp = (Node*)malloc(sizeof(Node));
p = list->head; //p的地址将使用list的地址
for(int i = list->size;i>0;i--)
//while(p !=NULL)
{
q = p->next; //q指向下一个节点
//q负责一直向后循环寻找最小值与q所在位置替换
while (q != NULL)
{
//如果条件满足,则替换,否则
//q的年份小于p
//或者q p年份相等,但是月份q小月p
//年月相等但是q的id小于p 调换位置
if (q->data.year < p->data.year || (q->data.year == p->data.year && q->data.month < p->data.month) || (q->data.year == p->data.year && q->data.month == p->data.month && q->data.id < p->data.id))
{
//q p 通过temp调换位置
//节点交换
//temp = q;
//q = q->next;
p->next = temp->next; //切记,该变了list的文件
//p->next = q;
//temp->next = p;
//p = temp;
temp->data = p->data;
p->data = q->data;
q->data = temp->data;
//核心代码
}
else
{
q = q->next;
p = p->next;
}
}
p = list->head;
p = p->next; //首节点最小,往后走继续判断
}
printList(list);
}
//按照部分降序,同部门工资升序排序
void sort_department(LinkList list)
{
//思路:比较部门以及工资数
Node* p, * q, * temp; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
p = list->head;
temp = (Node*)malloc(sizeof(Node));
for (int i = list->size; i > 0; i--)
{
q = p->next; //q指向下一个节点
//q负责一直向后循环寻找最小值与q所在位置替换
while (q != NULL)
{
if (wcscmp(p->data.department, q->data.department) < 0
|| (wcscmp(p->data.department, q->data.department) == 0 && q->data.realsalary < p->data.realsalary))
{
temp->data = p->data;
p->data = q->data;
q->data = temp->data;
}
else
{
q = q->next;
p = p->next;
}
}
p = list->head;
p = p->next; //首节点最小,往后走继续判断
}
printList(list);
}
//根据工号删除员工的所有信息
void delete_id(LinkList list,int id)
{
//先删除
Node*d,*pre; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
//Employee *temp;
//H = list->head;
d = list->head;
pre = list->head;
int lenght = list->size;
while(d!=NULL)
{
if (d->data.id == id)
{
pre->next = d->next;
list->size--;
}
pre = d;
d = d->next;
}
//保存本地
save_staff(list);
}
//根据员工姓名输出选定的员工工资信息
void search_name_salary(LinkList list, char name[20])
{
Node* s;
s = list->head;
while (s!=NULL)
{
if (strcmp(s->data.name, name) == 0)
{
printf("\n\t\t\t\t====> %s在%d年%d月在%s的实发工资为%.2f",s->data.name,s->data.year,s->data.month,s->data.department,s->data.realsalary);
}
s = s->next;
}
}
//查找部门所有员工信息,按实发工资降序
void dept_staff(LinkList list, char department[20])
{
Node* d,*s;
d = list->head;
struct Node* emp = (Node*)malloc(sizeof(Node));
int length = 0;
emp->next = NULL;
s = emp;
while (d != NULL)
{
if (strcmp(d->data.department, department) == 0)
{
//将对应的部门加入链表
Node *temp = (Node*)malloc(sizeof(Node));
temp->next = NULL;
temp->data = d->data;
s->next = temp;
s = s->next;
length++;
}
d = d->next;
}
//将emp按照实际工资降序
Node* p, * q, * temp; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
temp = (Node*)malloc(sizeof(Node));
p = emp->next;
printf("%d\n", length);
for(int i=length;i>=0;i--)
{
q = p->next; //q指向下一个节点
//q负责一直向后循环寻找最小值与q所在位置替换
while (q != NULL)
{
if (p->data.realsalary < q->data.realsalary)
{
temp->data = p->data;
p->data = q->data;
q->data = temp->data;
//核心代码
}
else
{
q = q->next;
p = p->next;
}
}
p = emp;
p = p->next; //首节点最小,往后走继续判断
}
//输出emp
emp = emp->next;
while (emp != NULL)
{
printf("\n\t\t\t\t====> %s在%d年%d月在%s的实发工资为%.2f", emp->data.name, emp->data.year, emp->data.month, emp->data.department, emp->data.realsalary);
emp = emp->next;
}
}
void year_month_salary(LinkList list, int year, int month)
{
Node* d, * s;
d = list->head;
struct Node* emp = (Node*)malloc(sizeof(Node));
int length = 0;
emp->next = NULL;
s = emp;
while (d != NULL)
{
if (d->data.year==year && d->data.month == month)
{
//将对应的部门加入链表
Node* temp = (Node*)malloc(sizeof(Node));
temp->next = NULL;
temp->data = d->data;
s->next = temp;
s = s->next;
length++;
}
d = d->next;
}
//将emp按照实际工资降序
Node* p, * q, * temp; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
temp = (Node*)malloc(sizeof(Node));
p = emp->next;
printf("%d\n", length);
for (int i = length; i >= 0; i--)
{
q = p->next; //q指向下一个节点
//q负责一直向后循环寻找最小值与q所在位置替换
while (q != NULL)
{
if (strcmp(p->data.department, q->data.department) < 0)
{
temp->data = p->data;
p->data = q->data;
q->data = temp->data;
//核心代码
}
else
{
q = q->next;
p = p->next;
}
}
p = emp;
p = p->next; //首节点最小,往后走继续判断
}
//输出emp
emp = emp->next;
while (emp != NULL)
{
printf("\n\t\t\t\t====> %s在%d年%d月在%s的实发工资为%.2f", emp->data.name, emp->data.year, emp->data.month, emp->data.department, emp->data.realsalary);
emp = emp->next;
}
}
//根据id进行排序
void sort_id(LinkList list)
{
Node* p, * q, * temp; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
p = list->head;
temp = (Node*)malloc(sizeof(Node));
for (int i = list->size; i >= 0; i--)
{
q = p->next; //q指向下一个节点
//q负责一直向后循环寻找最小值与q所在位置替换
while (q != NULL)
{
if (p->data.id > q->data.id)
{
temp->data = p->data;
p->data = q->data;
q->data = temp->data;
}
else
{
q = q->next;
p = p->next;
}
}
p = list->head;
//p = p->next; //首节点最小,往后走继续判断
}
//printList(list);
}
//每个员工的平均工资
void every_staff_average_salary(LinkList list)
{
struct average* s = (average*)malloc(sizeof(average));
s->next = NULL;
Node* d;
average* a = (average*)malloc(sizeof(average));
a->next = NULL;
d = list->head;
a = s;
//根据id进行排序
//
sort_id(list);
float total_salary ;
int total_month;
float average_salary;
int p_id;
char *name;
int id_count;
id_count = 0;
//根据顺序和规则计算出所有Id入职依赖的总收入/月数
while ( d != NULL)
//for(int i=0;i<list->size;i++)
{
total_salary = 0;
total_month = 0;
p_id = d->data.id;
name = d->data.name;
while (d->data.id == p_id)
{
total_month++; //计算月份
total_salary = total_salary + d->data.salary; //计算总工资
d = d->next;
if (d == NULL)
break;
}
//计算出平均工资
average_salary = total_salary / total_month;
struct average* lin_a = (average*)malloc(sizeof(average));
lin_a->next = NULL;
lin_a->id = p_id;
lin_a->name = name;
lin_a->a_salary = average_salary;
a->next = lin_a;
a = a->next;
id_count++;
}
free(a);
//对生成的平均工资结构体进行升序派别
average* p, * q, * temp; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
p = s->next;
temp = (average*)malloc(sizeof(average));
//while (p != NULL)
for(int i=0;i<id_count;i++)
{
q = p->next;
for (int j = id_count -i; j >0; j--)
{
if (p->a_salary > q->a_salary)
{
temp->id = p->id;
temp->name = p->name;
temp->a_salary = p->a_salary;
p->id = q->id;
p->name = q->name;
p->a_salary = q->a_salary;
q->id = temp->id;
q->name = temp->name;
q->a_salary = temp->a_salary;
q = q->next;
if (q->id < 0 || q->a_salary < 0)
break;
p = p->next;
}
else
{
q = q->next;
if ( q==NULL || q->id < 0 || q->a_salary < 0)
break;
p = p->next;
}
}
p = s->next;
}
//对排序号的链表进行输出
for (int i = 0; i < id_count; i++)
{
s = s->next;
if (s->id < 0 || s->a_salary < 0)
break;
printf("\t\t\t\t ID: %d,Name: %s,平均工资: %.2f\n", s->id, s->name, s->a_salary);
}
}
void dept_max_min(LinkList list,int year)
{
struct salary* s = (salary*)malloc(sizeof(salary));
s->next = NULL;
Node* d;
salary* a = (salary*)malloc(sizeof(salary));
a->next = NULL;
d = list->head;
a = s;
//根据id进行排序
sort_id(list);
float total_salary;
int total_month;
char *department;//部门
int p_id;
char *name;
int id_count;
id_count = 0;
//计算部门,每个人的总工资,建立新的链表
//根据顺序和规则计算出所有Id入职依赖的总收入/月数
//for(int i=0;i<list->size;i++)
while (d != NULL)
{
total_salary = 0;
total_month = 0;
p_id = d->data.id;
name = d->data.name;
department = d->data.department;
while (d->data.id == p_id && d->data.year == year) //加上年份,计算年份每个人的总工资
{
total_month++; //计算月份
total_salary = total_salary + d->data.salary; //计算总工资
d = d->next;
if (d == NULL)
break;
}
if (total_month != 0)
{
//计算出平均工资
struct salary* lin_a = (salary*)malloc(sizeof(salary));
lin_a->next = NULL;
lin_a->id = p_id;
lin_a->name = name;
lin_a->department = department;
lin_a->all_salary = total_salary;
a->next = lin_a;
a = a->next;
id_count++;
}
else
{
d = d->next;
if (d == NULL)
break;
}
}
salary* p, * q, * temp; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
p = s->next;
temp = (salary*)malloc(sizeof(salary));
for (int i = list->size; i > 0 && p!=NULL; i--)
{
q = p->next; //q指向下一个节点
//q负责一直向后循环寻找最小值与q所在位置替换
while (q != NULL)
{
if (wcscmp(p->department, q->department) < 0
|| (wcscmp(p->department, q->department) == 0 && q->all_salary > p->all_salary))
{
temp->id = p->id;
temp->name = p->name;
temp->department = p->department;
temp->all_salary = p->all_salary;
p->id = q->id;
p->name = q->name;
p->department = q->department;
p->all_salary = q->all_salary;
q->id = temp->id;
q->name = temp->name;
q->department = temp->department;
q->all_salary = temp->all_salary;
}
else
{
q = q->next;
p = p->next;
}
}
p = s->next;
}
//得出部门下,按照员工总工资得到的排序
for (int i = 0; i < id_count; i++)
{
s = s->next;
if (s == NULL || s->id < 0 || s->all_salary < 0)
break;
printf("\n\t\t\tID: %d,Name: %s,部门: %s , 在%d年内总工资工资: %.2f\n", s->id, s->name, s->department, year, s->all_salary);
}
}
void year_month_tax_all(LinkList list, int year, int month)
{
//找到此数据建立新的链表加入纳税总额 ,计算即可,
char dept[3][20] = { "人事部","营销部","开发部" };
int Tax[3] = { 0,0,0 };
int Person_tax = 0;//人事部
int Sales_tax = 0;//销售部
int Develop_tax = 0;//开发部
//计算出每个部门的纳税总额,部门升序,直接根据部门输出即可
for (int j = 0; j < 3; j++)
{
//遍历List求出对应部门的总纳税额
Node* p; //p节点复制保存排序后的结果,q负责一直向后寻找小值替换p,temp为中间值
p = list->head;
for (int i = list->size; i >= 0; i--)
{
if (strcmp(p->data.department, dept[j]) == 0)
{
Tax[j] = Tax[j] + (p->data.salary - p->data.realsalary);
}
p = p->next;
if (p == NULL)
{
break;
}
}
}
for (int n = 0; n < 3; n++)
{
printf("\t\t\t\t %s 部门的总纳税额为: %d\n", dept[n],Tax[n]);
}
}
主函数
//员工工作管理系统 主文件 调用
#include "head.h"
//单链表初始化
int main()
{
list = (LinkList)malloc(sizeof(LinkList));
list->head = NULL;
list->size = 0;
//TODO启动时将文件中所有用户信息初始化到链表
if (_access(filename, 00)==0) //如果此文件存咋
{
open_staff_file(list);
}
//printList(list);
#if 1
//进入员工工作管理系统菜单
menu();
#elif 0
//测试代码
//printf("部门排序");
//sort_month(list);
//sort_department(list);
/*printList(list);
delete_id(list,10);
printList(list);*/
//search_name_salary(list, "刘德华");
//dept_staff(list, "营销部");
//year_month_salary(list, 2023, 3);
//统计部分
//sort_id(list);
//every_staff_average_salary(list);
//dept_max_min(list,2023);
//year_month_tax_all(list, 2023, 5);
#endif
return 0;
}
开源
DEV C
和VS2022
查看开源地址
:https://github.com/foryouos/Cplus_study/tree/master/C++练习/员工工资管理