单链表写通信录

单链表写通讯录

单链表实现通讯录,增加,删除,更改一个联系人等功能。其中增加了一个内存池功能,用于对废弃内存的回收和利用。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1024
void addPerson(struct Presonlist **node);//添加一个联系人
void displayContact(struct Presonlist *node);//显示通信录
void changPerson(struct Presonlist *node, char **str1, char **str2);//更改联系人
void delPerson(struct Presonlist **node, char *str);//删除一个联系人
void welcome(void);//欢迎界面
struct Presonlist *pool = NULL;//定义一个内存池
void pooldelete(void);
int count;
struct Presonlist {//定义一个结构体
	char name[200];
	char number[100];
	struct Presonlist *next;
};
void addPerson(struct Presonlist **node)
{
	struct Presonlist *newlist;
	static struct Presonlist *tail= *node;//定义尾指针
	
	if (pool != NULL)//如果内存池非空,则直接从里面获取空间
	{
		newlist = pool;
		pool = pool->next;
		count--;
	}
		//如果内存池为空,则用malloc申请空间
	else {
		newlist = (struct Presonlist *)malloc(sizeof(struct Presonlist));
		if (newlist == NULL)
		{
			printf("分配失败\n");
			exit(1);
		}
	}
	
	printf("请输入新增联系人姓名\n");
	scanf_s("%s", newlist->name,sizeof(newlist->name));

	printf("请输入新增联系人电话号码\n");
	scanf_s("%s", newlist->number, sizeof(newlist->number));


	if(*node == NULL)//如果指针为空,直接将新节点插入即可
	{
		*node = newlist;
		newlist->next = NULL;
	}
	else//采用尾插法
	{
		tail->next = newlist;
		newlist->next = NULL;
	}
	tail = newlist;//保证尾指针指向链表的最末尾
}

void displayContact(struct Presonlist *node)
{
	while (node != NULL)
	{
		printf("%s:%s\n", node->name,node->number);
		node = node->next;
	}
}
void delPerson(struct Presonlist **node, char *str)//输入链表和要删除的字符串
{
	struct Presonlist *current, *previous, *newlist;
	current = *node;
	previous = NULL;
	
	
	while (current != NULL && strcmp(current->name, str)&& strcmp(current->number, str))//如果当前指针不为空而且不是我们查找的名字或者号码,程序就继续执行。
	{
		previous = current;//指针后移一个
		current = current->next;
	}
	if (current == NULL)
	{
		printf("没有找到或者链表为空\n");
	}
	else
	{
		if (previous == NULL)//如果只有一个结点current,previous处于初始化状态
		{
			*node = current->next;
		}
		else {
			previous->next = current->next;//删除节点
		}
		if (count < MAX)//如果内存池大小小于MAX,则把删除的current存放在pool中
		{
			if (pool != NULL)//如果pool不为空。采用头插法插入current
			{
				current->next = pool;
				pool = current;
			}
			else//否则直接插入即可
		    {
				pool = current;
				current->next = NULL;
			}
			count++;
		}
		else//如果内存池大小大于MAX,直接释放current结点
		{
			free(current);
		}
		
	}
}
void Contactexit(struct Presonlist **node)//直接释放所有的链表结点
{
	struct Presonlist *nextlist;
	while (*node!=NULL)
	{
		nextlist = (*node)->next;
		free(*node);
		*node = nextlist;
	}
}
void pooldelete(void)//删除内存池
{
	struct Presonlist *nextlist;
	while (pool != NULL)
	{
		nextlist = pool->next;
		free(pool);
		pool = nextlist;
	}
}
struct Presonlist *findPerson(struct Presonlist *node,char *str)
{
	struct Presonlist *sear=node;
	while ((sear!=NULL)&&(strcmp(sear->name,str))&&(strcmp(sear->number, str)))//如果不为空而且没有找到则继续循环
	{
		sear = sear->next;
	}
	if (sear != NULL)//如果不为空
	{
		if (!strcmp(sear->name, str) || !strcmp(sear->number, str))//找到名字或者电话号码则返回
		{
			return sear;
		}
		else {
			printf("查找错误\n");
		}
	}
	else
	{
		printf("没有找到\n");
		return sear;
	}
	
}
void changPerson(struct Presonlist *node, char *str1, char *str2)
{
	struct Presonlist *sear = node;
	while ((sear != NULL) && (strcmp(sear->name, str1))&& (strcmp(sear->number, str1)))//如果链表不为空,而且没有找到
	{
		sear = sear->next;
	}
	if (sear != NULL)
	{
		if (!strcmp(sear->name, str1))//如果找到的str1是更改联系人的名字
		{
			memset(sear->name, 0, sizeof(sear->name));//先把名字置为0
			strcpy_s(sear->name, strlen(str2) + 1, str2);//再把str2拷贝到名字中
		}
		else if (!strcmp(sear->number, str1))//不然就是电话号码
		{
			memset(sear->number, 0, sizeof(sear->number));
			strcpy_s(sear->number, strlen(str2) + 1, str2);
		}
		else {
			printf("更改失败,请重新输入\n");
		}
	}
	else
	{
		printf("没有找到,请重新输入\n");
	}
	
}
void welcome(void)
{
printf("欢迎使用袁强的通信录\n\
请输入以下命令:\n\
  --- 1:新建联系人 ---|\n\
  --- 2:查找联系人 ---|\n\
  --- 3:删除联系人 ---|\n\
  --- 4:显示通讯录 ---|\n\
  --- 5:更改联系人 ---|\n\
  --- 6:删除通讯录 ---|\n\
  --- 7:退出通讯录 ---|\n");
}
int main(void)
{

	struct Presonlist *node = NULL;
	struct Presonlist *findlist = NULL;
	char c = 0;
	char input[100] = {0};
	char change[100] = { 0 };
	welcome();
	while (1)
	{
		
		c = getchar();
		switch (c)
		{
			case '1':addPerson(&node);
			printf("count:%d\n", count);
			printf("增加联系人成功\n");
			break;
			case '2':
			printf("请输入要查找的联系人或者号码\n");
			scanf_s("%s", input, sizeof(input));
			findlist = findPerson(node, input);
			if (findlist != NULL)
			{
				printf("查找出的联系人是%s:%s\n", findlist->name, findlist->number);
			}
			break;
			case '3':
			printf("请输入要删除的联系人/号码\n");
			scanf_s("%s", change, sizeof(change));
			delPerson(&node, change);
			printf("count:%d\n",count);
			break;
			case '4':
			displayContact(node);
			break;
			case '5':
			printf("请输入需要更改的名字/电话号码\n");
			memset(input, 0, sizeof(input));
			scanf_s("%s", input, sizeof(input));
			printf("请输入更改后的名字/电话号码\n");
			scanf_s("%s", change, sizeof(change));
			changPerson(node, input, change);
			printf("更改后的联系人列表:\n");
			displayContact(node);
			break;
			case '6':
			Contactexit(&node);
			pooldelete();
			printf("已删除所有列表\n");
			welcome();
			break;
			case '7':
			return 0;
		}
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一个模块——主函数main()的功能是:根据选单的选项调用各函数,并完成相应的功能。 
   第二个模块——Menu()的功能是:显示提示选单。 
   第三个模块——Quit()的功能是:退出选单。 
   第四个模块——Create()的功能是:创建新的数据记录。 
   第五个模块——Add()的功能是:增加新的数据记录,并返回选单。 
   第六个模块——Find()的功能是:按要求查询相关的信息,如果找到了,则显示该信息,如果未找到,则提示文件中没有该信息,并返回选单。 
   第七个模块——Alter()[的功能是:修改某条记录的信息,如果未找到要修改的记录,则提示系统中无此记录,并返回选单。 
   第八个模块——Delete()的功能是:删除某条记录,如果未找到要删除的记录,则提示通讯录中没有,并返回选单。 
   第九个模块——List()的功能是:显示所有记录。 一、用链表或者顺序表实现以下系统,完成线性表的建立(至少包括10个结点),以及线性表中信息(结点)的插入、查找、删除、修改、输出等操作,具体的模块要求见上方的“总的模块要求”。建议用“文件”存储数据。 1.通讯录管理系统的设计与实现 (1)通讯者信息包括:编号(char num[10])、姓名(char name[10])、性别(char sex[10])、电话(char phone[20]) (2)除了总的模块要求外,还需统计通讯录中男性人数及女性人数,并求出通讯录中的第一个模块——主函数main()的功能是:根据选单的选项调用各函数,并完成相应的功能。 
   第二个模块——Menu()的功能是:显示提示选单。 
   第三个模块——Quit()的功能是:退出选单。 
   第四个模块——Create()的功能是:创建新的数据记录。 
   第五个模块——Add()的功能是:增加新的数据记录,并返回选单。 
   第六个模块——Find()的功能是:按要求查询相关的信息,如果找到了,则显示该信息,如果未找到,则提示文件中没有该信息,并返回选单。 
   第七个模块——Alter()[的功能是:修改某条记录的信息,如果未找到要修改的记录,则提示系统中无此记录,并返回选单。 
   第八个模块——Delete()的功能是:删除某条记录,如果未找到要删除的记录,则提示通讯录中没有,并返回选单。 
   第九个模块——List()的功能是:显示所有记录。 一、用链表或者顺序表实现以下系统,完成线性表的建立(至少包括10个结点),以及线性表中信息(结点)的插入、查找、删除、修改、输出等操作,具体的模块要求见上方的“总的模块要求”。建议用“文件”存储数据。 1.通讯录管理系统的设计与实现 (1)通讯者信息包括:编号(char num[10])、姓名(char name[10])、性别(char sex[10])、电话(char phone[20]) (2)除了总的模块要求外,还需统计通讯录中男性人数及女性人数,并求出通讯录中的男女比例。 男女比例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值