首页 > 编程语言 >基于顺序表实现通讯管理系统!(有完整源码!)

基于顺序表实现通讯管理系统!(有完整源码!)

时间:2024-04-06 22:04:54浏览次数:25  
标签:arr 顺序 管理系统 void pos 源码 通讯录 printf con

​​​​​​​

                                                                                个人主页:秋风起,再归来~

                                                                                文章专栏:C语言实战项目                              

                                                                        个人格言:悟已往之不谏,知来者犹可追

                                                                                        克心守己,律己则安!​​​​​​​

目录

1、实现思路

​编辑

2、各种接口的实现

2.1 初始化通讯录

2.2 添加通讯录数据

2.3 删除通讯录数据

2.4 展示通讯录数据

2.5 查找通讯录数据

2.6 修改通讯录数据

2.7 销毁通讯录数据

2.8 制作一个简易的菜单 

3、完整源码

SeqList.h

Contact.h

SeqList.c

Contact.c

test.c

4、 完结散花


1、实现思路

前言:在我之前的文章当中已经写过一篇关于如何实现顺序表的文章(点击这里),而这篇文章主要是讲解如何基于顺序表实现通讯管理系统,所以要看明白这篇文章的宝子们一定要先看完写的顺序表的文章哦~

1.1 首先我们知道顺序表的底层就是数组,而通讯录就是顺序表通过封装过后的产物~

所以我们可以说通讯录的底层其实就是顺序表啦~

1.2我们知道之前实现顺序表的时候,每个数组中存放的是内置类型int,而我们如果想要将各种联系人的数据存放并管理起来,那么我们就必须先自定义一个结构体类型来存放每个联系人的数据。然后将每个联系人的数据存放到数组中统计管理起来~

我们用宏定义来表示数组的大小方便以后的调整~(这些代码都是写在contact.h头文件当中)

#define NAME_MAX 20
#define GENDER_MAX 20
#define TELE_MAX 20
#define ADDR_MAX 200
//定义一个自定义类型来存放我们所要的联系人信息
typedef struct PersonInformation
{
	char name[NAME_MAX];//名字
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//住址
}PeoInfo;

 ​​

1.3 我们知道顺序表是这样定义的~

//定义一个动态顺序表的结构体变量
typedef struct SeqList
{
	SLDataType* arr;
	size_t num;//记录有效数据的个数
	size_t capacity;//该顺序表的容量大小
}SL;//将该结构体类型重命名为SL

我们在顺序表的头文件当中引入Contact.h头文件(因为我们要将顺序表中的每个元素改成我们自定义是类型)

​​

1.4 接下来我们就让顺序表摇身一变成为通讯录!

//前置申明
typedef struct SeqList contact;

 这里我只是给顺序表重新取了一个名字(contact)!

因为头文件之间不可以互相包含,所以我们不可以将SeqList.h中的SL进行重命名,只能通过前置声明。

到这里我们就可以对通讯录进行各种接口的实现了!

Contact.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TELE_MAX 20
#define ADDR_MAX 200

//定义一个自定义类型来存放我们所要的联系人信息
typedef struct PersonInformation
{
	char name[NAME_MAX];//名字
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//住址
}PeoInfo;

//前置申明
typedef struct SeqList contact;

//初始化通讯录
void InitContact(contact* con);

//添加通讯录数据
void AddContact(contact* con);

//删除通讯录数据
void DelContact(contact* con);

//展示通讯录数据
void ShowContact(contact* con);

//查找通讯录数据
void FindContact(contact* con);

//修改通讯录数据
void ModifyContact(contact* con);

//销毁通讯录数据
void DestroyContact(contact* con);

SeqList.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once//避免头文件的多次包含
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"Contact.h"//需要自定义的类型,所以引入contact头文件
typedef PeoInfo SLDataType;//便于类型的改动

//定义一个动态顺序表的结构体变量
typedef struct SeqList
{
	SLDataType* arr;
	size_t num;//记录有效数据的个数
	size_t capacity;//该顺序表的容量大小
}SL;//将该结构体类型重命名为SL

//加入增删查改接口

//1. 顺序表初始化
void SeqListInit(SL* p);

//2. 检查顺序表容量是否已满
void CheckSeqList(SL* p);

//3. 顺序表的尾插
void SeqListPushBack(SL* p, SLDataType x);

//4. 顺序表的尾删
void SeqListPopBack(SL* p);

//5. 顺序表的头插
void SeqListPushFront(SL* p, SLDataType x);

//6. 顺序表的头删
void SeqListPopFront(SL* p);

//7. 顺序表在pos位置插入
void SeqListInsert(SL* p, size_t pos, SLDataType x);

//8. 顺序表在pos位置删除
void SeqListErase(SL* p, size_t pos);

//9. 顺序表的查找
int SeqListFind(SL* p, SLDataType x);//如果该数字存在则返回该数字的下标,否则返回-1

//10 顺序表的销毁
void SeqListDestory(SL* p);

//11. 顺序表的打印
void SeqListPrint(SL* p);

2、各种接口的实现

2.1 初始化通讯录

因为我们希望在初始化通讯录时可以将我们之前保存的数据加载到通讯中,所以我们可以通过文件操作将数据加载到通讯录当中~

//导入原文件中的数据
void DoadContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	while (fread(&info, sizeof(PeoInfo), 1, pf))
	{
		SeqListPushBack(con, info);
	}
	printf("历史数据导入成功!\n");
	fclose(pf);
	pf = NULL;
}

在初始化时,我们就可以调用顺序表中的初始化接口来实现通讯录的初始化 ,然后再导入原数据~

//初始化通讯录
void InitContact(contact* con)
{
	SeqListInit(con);
	DoadContact(con);
}

2.2 添加通讯录数据

添加数据,我们就是在尾插的基础上对顺序表进行封装(头插也可以)!

//添加通讯录数据
void AddContact(contact* con)
{
	PeoInfo p;
	printf("请输入您要添加的联系人的姓名!\n");
	scanf("%s", p.name);
	printf("请输入您要添加的联系人的性别!\n");
	scanf("%s", p.gender); 
	printf("请输入您要添加的联系人的年龄!\n");
	scanf("%d", &(p.age));
	printf("请输入您要添加的联系人的电话!\n");
	scanf("%s", p.tele);
	printf("请输入您要添加的联系人的住址!\n");
	scanf("%s", p.addr);
	SeqListPushBack(con, p);
	printf("插入成功\n");
}

2.3 删除通讯录数据

这里我们通过名字来删除通讯录的数据!(当然我们也可以通过其他方式来删除数据)

//通过名字来查找通讯录中是否存在该联系人数据
int  FindByName(contact* con,char* name)
{
	for (int i = 0; i < con->num; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;//如果找到就返回他的下标
		}
	}
	return -1;//如果没找到返回一个无效的下标
}
//删除通讯录数据
void DelContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要删除的联系人的名字!\n");
	scanf("%s", name);
	int pos=FindByName(con, name);
	if (pos < 0)
	{
		printf("您要删除的联系人不存在!\n");
		return;
	}
	//调用顺序表中的在指定位置删除数据的函数
	SeqListErase(con, pos);
	printf("删除成功!\n");
}

2.4 展示通讯录数据

//展示通讯录数据
void ShowContact(contact* con)
{
	printf("名字\t\t性别\t\t年龄\t\t电话\t\t\t住址\n");
	for (int i = 0; i < con->num; i++)
	{
		printf("%s\t\t%s\t\t%d\t\t%s\t\t%s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tele,
			con->arr[i].addr
		);
	}
}

2.5 查找通讯录数据

//查找通讯录数据
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要查找的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要查找的联系人不存在!\n");
		return;
	}
	printf("名字\t性别\t年龄\t电话\t住址\n");
	printf("%s\t%s\t%d\t%s\t%s\t\n",
		con->arr[pos].name,
		con->arr[pos].gender,
		con->arr[pos].age,
		con->arr[pos].tele,
		con->arr[pos].addr
	);
}

2.6 修改通讯录数据

//修改通讯录数据
void ModifyContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要修改的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要修改的联系人不存在!\n");
		return;
	}
	printf("请输入新的名字\n");
	scanf("%s", con->arr[pos].name);
	printf("请输入新的性别\n");
	scanf("%s", con->arr[pos].gender);
	printf("请输入新的年龄\n");
	scanf("%d", &con->arr[pos].age);
	printf("请输入新的电话\n");
	scanf("%s", con->arr[pos].tele);
	printf("请输入新的住址\n");
	scanf("%s", con->arr[pos].addr);
	printf("修改成功!\n");
}

2.7 销毁通讯录数据

在退出通讯录时我们希望将我们对通讯录进行的操作保存下来!

//将输入的数据保存到通讯录中
void SaveContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	for (int i = 0; i < con->num; i++)
	{
		fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);
	}
	printf("历史数据保存成功!\n");
	fclose(pf);
	pf = NULL;
}
//先保存数据到文件中再销毁通讯录数据
void DestroyContact(contact* con)
{
	SaveContact(con);
	//调用顺序表的销毁函数即可
	SeqListDestory(con);
}

2.8 制作一个简易的菜单 

#define _CRT_SECURE_NO_WARNINGS

#include"SeqList.h"
#include"contact.h"

void menu()
{
	printf("**********************************\n");
	printf("*****1、增加用户 2、删除用户  ****\n");
	printf("*****3、查找用户 4、修改用户  ****\n");
	printf("*****5、展示用户 0、退出通讯录****\n");
	printf("**********************************\n");
}


int main()
{
	contact con = { 0 };
	InitContact(&con);
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择!\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			FindContact(&con);
			break;
		case 4:
			ModifyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 0:
			printf("退出通讯录成功!\n");
			break;
		default:
			printf("输入错误,请重新选择!\n");
			break;
		}
	} while(input);
	DestroyContact(&con);
	return 0;
}

3、完整源码

SeqList.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once//避免头文件的多次包含
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"Contact.h"//需要自定义的类型,所以引入contact头文件
typedef PeoInfo SLDataType;//便于类型的改动

//定义一个动态顺序表的结构体变量
typedef struct SeqList
{
	SLDataType* arr;
	size_t num;//记录有效数据的个数
	size_t capacity;//该顺序表的容量大小
}SL;//将该结构体类型重命名为SL

//加入增删查改接口

//1. 顺序表初始化
void SeqListInit(SL* p);

//2. 检查顺序表容量是否已满
void CheckSeqList(SL* p);

//3. 顺序表的尾插
void SeqListPushBack(SL* p, SLDataType x);

//4. 顺序表的尾删
void SeqListPopBack(SL* p);

//5. 顺序表的头插
void SeqListPushFront(SL* p, SLDataType x);

//6. 顺序表的头删
void SeqListPopFront(SL* p);

//7. 顺序表在pos位置插入
void SeqListInsert(SL* p, size_t pos, SLDataType x);

//8. 顺序表在pos位置删除
void SeqListErase(SL* p, size_t pos);

//9. 顺序表的查找
int SeqListFind(SL* p, SLDataType x);//如果该数字存在则返回该数字的下标,否则返回-1

//10 顺序表的销毁
void SeqListDestory(SL* p);

//11. 顺序表的打印
void SeqListPrint(SL* p);

Contact.h

#define _CRT_SECURE_NO_WARNINGS

#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TELE_MAX 20
#define ADDR_MAX 200

//定义一个自定义类型来存放我们所要的联系人信息
typedef struct PersonInformation
{
	char name[NAME_MAX];//名字
	char gender[GENDER_MAX];//性别
	int age;//年龄
	char tele[TELE_MAX];//电话
	char addr[ADDR_MAX];//住址
}PeoInfo;

//前置申明
typedef struct SeqList contact;

//初始化通讯录
void InitContact(contact* con);

//添加通讯录数据
void AddContact(contact* con);

//删除通讯录数据
void DelContact(contact* con);

//展示通讯录数据
void ShowContact(contact* con);

//查找通讯录数据
void FindContact(contact* con);

//修改通讯录数据
void ModifyContact(contact* con);

//销毁通讯录数据
void DestroyContact(contact* con);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
//1. 顺序表初始化
void SeqListInit(SL* p)
{
	assert(p);//判断指针的有效性
	p->arr = NULL;
	p->capacity = 0;
	p->num = 0;
}

//2. 检查顺序表容量是否已满
void CheckSeqList(SL* p)
{
	assert(p);//判断指针的有效性
	if (p->num == p->capacity)
	{
		size_t newcapacity = p->capacity == 0 ? p->capacity = 4 : p->capacity * 2;
		//如果原来没有空间,就给上4,有的话就扩大为原来的两倍
		SLDataType* ptr = (SLDataType*)realloc(p->arr, newcapacity * sizeof(SLDataType));//动态扩容
		if (ptr == NULL)
		{
			perror("realloc fail;");
			return;
		}
		//也可以用assert断言一下
		p->arr = ptr;//开辟成功将地址传给arr
		p->capacity = newcapacity;//更新容量
	}
}

//3. 顺序表的尾插
void SeqListPushBack(SL* p, SLDataType x)
{
	assert(p);//判断指针的有效性
	CheckSeqList(p);//尾插前先判断有没有容量或容量够不够
	p->arr[p->num] = x;//尾部插入数据
	p->num++;//有效数加一
}

//4. 顺序表的尾删
void SeqListPopBack(SL* p)
{
	assert(p);//判断指针的有效性
	assert(p->num > 0);//断言存在有效数据
	p->num--;//尾删一个数据
}

//5. 顺序表的头插
void SeqListPushFront(SL* p, SLDataType x)
{
	assert(p);//判断指针的有效性
	CheckSeqList(p);//先判断容量是否满了
	size_t end = p->num;
	while (end)
	{
		p->arr[end] = p->arr[end - 1];//整体向后移动
		end--;
	}
	p->arr[0] = x;//头插
	p->num++;//有效数据加一
}

//6. 顺序表的头删
void SeqListPopFront(SL* p)
{
	assert(p);//判断指针的有效性
	assert(p->num > 0);//有数据才删除
	size_t begin = 1;
	while (begin < p->num)
	{
		p->arr[begin - 1] = p->arr[begin];//整体向前移动
		begin++;
	}
	p->num--;// 有效数据减一

}

//7. 顺序表在pos位置插入
void SeqListInsert(SL* p, size_t pos, SLDataType x)
{
	assert(p);//判断指针的有效性
	assert(pos >= 0 && pos < p->num);//pos必须小于num并且大于等于0
	CheckSeqList(p);//判断容量是否满了
	for (int i = p->num; i > pos - 1; i--)
	{
		p->arr[i] = p->arr[i - 1];//将pos后面的元素往后挪
	}
	p->arr[pos - 1] = x;//在pos位置加入数据
	p->num++;//有效个数加一
}

//8. 顺序表在pos位置删除
void SeqListErase(SL* p, size_t pos)
{
	assert(p);//判断指针的有效性
	assert(pos >= 0 && pos < p->num);//pos必须小于num并且大于等于0
	assert(p->num > 0);//有数据才能删除
	for (int i = pos; i < p->num-1; i++)
	{
		p->arr[i] = p->arr[i+1];//将pos后面的元素往后挪
	}
	p->num--;//有效个数减一
}

//9. 顺序表的查找
int SeqListFind(SL* p, SLDataType x)//如果该数字存在则返回该数字的下标,否则返回-1
{
	assert(p);//断言
	for (int i = 0; i < p->num; i++)
	{
		if (p->arr[i] == x)
		{
			return i;//查到返回下标
		}
	}
	return -1;//没有查到
}


//10 顺序表的销毁
void SeqListDestory(SL* p)
{
	assert(p);//判断指针的有效性
	free(p->arr);//释放动态内存开辟的空间
	p->arr = NULL;
	p->capacity = 0;//容量置为0
	p->num = 0;//有效个数置为0
}

//11. 顺序表的打印
void SeqListPrint(SL* p)
{
	assert(p);//判断指针的有效性
	if (p->num == 0)
	{
		printf("顺序表为空!\n");
		return;
	}
	for (int i = 0; i < p->num; i++)
	{
		printf("%d ", p->arr[i]);//打印数据
	}
	printf("\n");
}

Contact.c

#define _CRT_SECURE_NO_WARNINGS

#include"SeqList.h"
#include"Contact.h"


//导入原文件中的数据
void DoadContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	while (fread(&info, sizeof(PeoInfo), 1, pf))
	{
		SeqListPushBack(con, info);
	}
	printf("历史数据导入成功!\n");
	fclose(pf);
	pf = NULL;
}


//初始化通讯录
void InitContact(contact* con)
{
	SeqListInit(con);
	DoadContact(con);
}

//添加通讯录数据
void AddContact(contact* con)
{
	PeoInfo p;
	printf("请输入您要添加的联系人的姓名!\n");
	scanf("%s", p.name);
	printf("请输入您要添加的联系人的性别!\n");
	scanf("%s", p.gender); 
	printf("请输入您要添加的联系人的年龄!\n");
	scanf("%d", &(p.age));
	printf("请输入您要添加的联系人的电话!\n");
	scanf("%s", p.tele);
	printf("请输入您要添加的联系人的住址!\n");
	scanf("%s", p.addr);
	SeqListPushBack(con, p);
	printf("插入成功\n");
}

//通过名字来查找通讯录中是否存在该联系人数据
int  FindByName(contact* con,char* name)
{
	for (int i = 0; i < con->num; i++)
	{
		if (strcmp(con->arr[i].name, name) == 0)
		{
			return i;//如果找到就返回他的下标
		}
	}
	return -1;//如果没找到返回一个无效的下标
}

//删除通讯录数据
void DelContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要删除的联系人的名字!\n");
	scanf("%s", name);
	int pos=FindByName(con, name);
	if (pos < 0)
	{
		printf("您要删除的联系人不存在!\n");
		return;
	}
	//调用顺序表中的在指定位置删除数据的函数
	SeqListErase(con, pos);
	printf("删除成功!\n");
}

//展示通讯录数据
void ShowContact(contact* con)
{
	printf("名字\t\t性别\t\t年龄\t\t电话\t\t\t住址\n");
	for (int i = 0; i < con->num; i++)
	{
		printf("%s\t\t%s\t\t%d\t\t%s\t\t%s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tele,
			con->arr[i].addr
		);
	}
}


//查找通讯录数据
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要查找的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要查找的联系人不存在!\n");
		return;
	}
	printf("名字\t性别\t年龄\t电话\t住址\n");
	printf("%s\t%s\t%d\t%s\t%s\t\n",
		con->arr[pos].name,
		con->arr[pos].gender,
		con->arr[pos].age,
		con->arr[pos].tele,
		con->arr[pos].addr
	);
}

//修改通讯录数据
void ModifyContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要修改的联系人的名字!\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos < 0)
	{
		printf("您要修改的联系人不存在!\n");
		return;
	}
	printf("请输入新的名字\n");
	scanf("%s", con->arr[pos].name);
	printf("请输入新的性别\n");
	scanf("%s", con->arr[pos].gender);
	printf("请输入新的年龄\n");
	scanf("%d", &con->arr[pos].age);
	printf("请输入新的电话\n");
	scanf("%s", con->arr[pos].tele);
	printf("请输入新的住址\n");
	scanf("%s", con->arr[pos].addr);
	printf("修改成功!\n");
}

//将输入的数据保存到通讯录中
void SaveContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		perror("open fail\n");
		return;
	}
	PeoInfo info = { 0 };
	for (int i = 0; i < con->num; i++)
	{
		fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);
	}
	printf("历史数据保存成功!\n");
	fclose(pf);
	pf = NULL;
}

//先保存数据到文件中再销毁通讯录数据
void DestroyContact(contact* con)
{
	SaveContact(con);
	//调用顺序表的销毁函数即可
	SeqListDestory(con);
}

test.c

#define _CRT_SECURE_NO_WARNINGS

#include"SeqList.h"
#include"contact.h"

void menu()
{
	printf("**********************************\n");
	printf("*****1、增加用户 2、删除用户  ****\n");
	printf("*****3、查找用户 4、修改用户  ****\n");
	printf("*****5、展示用户 0、退出通讯录****\n");
	printf("**********************************\n");
}


int main()
{
	contact con = { 0 };
	InitContact(&con);
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择!\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			FindContact(&con);
			break;
		case 4:
			ModifyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 0:
			printf("退出通讯录成功!\n");
			break;
		default:
			printf("输入错误,请重新选择!\n");
			break;
		}
	} while(input);
	DestroyContact(&con);
	return 0;
}

4、 完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

​​​​

标签:arr,顺序,管理系统,void,pos,源码,通讯录,printf,con
From: https://blog.csdn.net/2301_80221228/article/details/137420312

相关文章

  • Python 基于列表实现的通讯录管理系统(有完整源码)
    目录通讯录管理系统PersonInformation类ContactList类menu函数main函数程序的运行流程完整代码运行示例通讯录管理系统这是一个基于文本的界面程序,用户可以通过命令行与之交互,它使用了CSV文件来存储和读取联系人信息,这使得数据可以持久化保存。此外,程序还提供了一......
  • Node.js毕业设计基于的班委报名投票系统(Express+附源码)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着信息技术的飞速发展,互联网已经深入到我们生活的各个角落,包括教育领域。在传统的班委选举中,通常采用纸质投票的方式,这种方式不仅浪费资源,而且效率低下,统......
  • Node.js毕业设计基于的OA办公系统的设计与实现(Express+附源码)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着信息技术的飞速发展和互联网应用的普及,办公自动化(OA)系统已经成为企业、机构乃至政府部门不可或缺的工具。传统的手工办公方式效率低下、易出错且难以管......
  • 数据结构---顺序表实现
    目录1.顺序表2.动态顺序表的实现(4)顺序表初始化(5)顺序表销毁(6)顺序表的插入a.尾插b.头插(7)顺序表的删除a.尾删b.头删(8)指定位置之前插入(9)指定位置删除(10)顺序表查找数据3.我的心得体会(可跳过)4.顺序表完整代码(1)seqlist.h文件(2)seqlist.c文件(3)test.c文件1.顺序表......
  • python基于flask汽车4s店服务销售配件管理系统django+echart 数据可视化_od8kr
     该系统采用python技术,结合flask框架使页面更加完善,后台使用MySQL数据库进行数据存储。系统主要分为三大模块:即管理员模块,员工管理模块和用户模块。本文从汽车服务流程分析入手,分析了其功能性需求和非功能性需求,设计了一个由管理员,用户和员工三部分组成的汽车服务管理系统。用......
  • Python常用算法--排序算法【附源码】
    应用具体python案例方式展示各种排序的要点,特别是希尔排序、插入排序、选择排序、冒泡排序、堆排序、快速排序、归并排序七个具体的排序算法。一、希尔排序:解释:希尔排序(ShellSort)是一种插入排序的改进版本,也被称为缩小增量排序。希尔排序通过比较相距一定间隔的元素,将大间隔......
  • 基于SpringBoot+Vue导师选择管理系统设计和实现(源码+LW+部署讲解)
    博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌主要内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs......
  • Springboot+Vue宿舍管理系统
    Springboot+Vue宿舍管理系统体验地址见:http://www.cdmzl.cn/index宿舍管理系统的一些主要功能介绍:基本信息管理(完成)学生信息管理:录入、修改和查询学生的基本信息,如姓名、性别、学号、班级、联系方式等。宿舍信息管理:录入、修改和查询宿舍的基本信息,如宿舍号、楼层、房间类......
  • ubuntu上安装某个程序的符号表和源码包
    查询软件包以/bin/kill为例,可以先查询这个文件位于哪个安装包里:$dpkg-S/bin/killprocps:/bin/kill安装符号表然后参考下面的方法,配置符号表仓库:https://www.cnblogs.com/pengdonglin137/articles/16295482.html配置完成后,执行:sudoaptinstallprocps-dbgsym安装源......
  • 【包远程安装运行】SpringBoot+Mysql实现的在线兼职实习招聘管理系统源码+运行教程+开
    今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的在线招聘系统,主要实现了在线招聘基本操作流程的全部功能,系统分普通用户、管理员等角色,除基础脚手架外,实现的功能有:管理员:系统管理、职位管理、新闻咨询管理、简历投递管理、在线统计等。普通用户(......