用C语言实现员工工资管理系统

员工工资管理系统

实现功能

  • 程序中的数据存储到文件中。
  • 可以录入员工工资信息,格式如下:
    (工号(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 CVS2022查看开源地址https://github.com/foryouos/Cplus_study/tree/master/C++练习/员工工资管理

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值