【C语言】基于单链表再次实现通讯录

前言

大家好呀,我是Humble,在之前Humble 写过基于顺序表的通讯录项目,今天则是要分享基于单链表再次实现通讯录

【C语言】基于单链表再次实现通讯录_第1张图片

废话不多说,我们开始吧~

其实大的思路与之前是一致的,只是因为数据结构的不同,从顺序表变成了单链表,所以要进行代码上的修改

我们基于单链表实现的代码也是可以直接在这个通讯录项目上进行复用的~所以这里我们也是在原有的SList.c和Slist.h的基础上加上contact.c和contact.h以及新的测试文件test.c

这里Humble就不多赘述了,直接将所有的代码进行汇总~

参考代码

test.c

#define _CRT_SECURE_NO_WARNINGS
#include "SList.h"

void menu()
{
	printf("**************************************\n");
	printf("*****1、添加联系人 2、删除联系人******\n");
	printf("*****3、修改联系人 4、查找联系人******\n");
	printf("*****5、查看通讯录 0、退出 ***********\n");
	printf("**************************************\n");
	printf("请选择您的操作:\n");
}


int main()
{
	
	contact* con = NULL;

	int op = 0;
	do {
		menu();
		printf("请选择:\n");
		scanf("%d", &op);

		switch (op)
		{
		case 1:
			ContactAdd(&con);
			break;
		case 2:
			ContactDel(&con);
			break;
		case 3:
			ContactModify(con);
			break;
		case 4:
			ContactFind(con);
			break;
		case 5:
			ContactShow(con);
			break;
		case 0:
			printf("退出\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (op != 0);

	ContactDestory(&con);

	return 0;
}

SList.h

#pragma once
#include
#include
#include
#include

#include"contact.h"


//定义链表的结构
//typedef int SLDataType
typedef struct ContactInfo SLDataType;   //更改SLDataType的类型

typedef struct SListNode
{
	SLDataType data;	//保存的数据
	struct SListNode* next;		//指针变量存放下一个节点的地址
}SLNode;



//尾插
void SLPushBack(SLNode** pphead, SLDataType x);


//删除pos节点
void  SLErase(SLNode** pphead, SLNode* pos);


//销毁链表
void SLDestory(SLNode** pphead);

SList.c

#include "SList.h"


// 创建新的节点的函数
SLNode* SLBuyNode(SLDataType x)
{
	SLNode* node = (SLNode*)malloc(sizeof(SLNode));
	node->data = x;
	node->next = NULL;
	return node;
}

//尾插
void SLPushBack(SLNode** pphead, SLDataType x)	//保存第一个节点的指针的地址
{
	assert(pphead);
	//创建一个节点
	SLNode* node = SLBuyNode(x);
	if (*pphead == NULL)
	{
		*pphead = node;
		return;
	}
	//链表不为空,找尾
	SLNode* pcur = *pphead;
	while (pcur->next)//相当于pcur->next!=NULL
	{
		pcur = pcur->next;
	}
	pcur->next = node;
}



// 删除pos节点
void SLErase(SLNode** pphead, SLNode* pos)
{
	assert(*pphead);
	assert(pphead);
	assert(pos);
	//pos是头结点
	if (pos == *pphead)
	{
		*pphead = (*pphead)->next;
		free(pos);
		return;
	}
	//pos不是头结点,找pos的前一个节点
	SLNode* pre = *pphead;
	while (pre->next != pos)
	{
		pre = pre->next;
	}
	pre->next = pos->next;
	free(pos);
	pos = NULL;   //代码规范
}


//销毁
void SLDestory(SLNode** pphead)
{
	assert(pphead);
	SLNode* pcur = *pphead;
	while (pcur)
	{
		SLNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	//头结点记得置空
	*pphead = NULL;
}

contact.h

#pragma once
#define NAME_MAX 120
#define SEX_MAX 4  
#define TEL_MAX 11
#define ADDR_MAX 100

typedef struct ContactInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}ConInfo;

//前置声明
typedef struct SListNode contact;


//1.添加联系人
void ContactAdd(contact** pcon);

//2.删除联系人
void ContactDel(contact** pcon);

//3.修改联系人
void ContactModify(contact* con);

//4.查找联系人
void ContactFind(contact* pcon);

//5.查看通讯录
void ContactShow(contact* pcon);

//销毁通讯录
void ContactDestory(contact** pcon);

contact.c

#define _CRT_SECURE_NO_WARNINGS
#include "SList.h"


//前置声明
typedef struct SListNode contact;



//1.添加联系人
void ContactAdd(contact** pcon)
{
	ConInfo info;

	printf("请输入添加联系人姓名:\n");
	scanf("%s", &info.name);

	printf("请输入添加联系人性别:\n");
	scanf("%s", &info.sex);

	printf("请输入添加联系人年龄:\n");
	scanf("%d", &info.age);

	printf("请输入添加联系人电话:\n");
	scanf("%s", &info.tel);

	printf("请输入添加联系人地址:\n");
	scanf("%s", &info.addr);

	SLPushBack(pcon, info);

	printf("已添加联系人数据\n");
}


contact* FindByName(contact* con, char name[])
{
	contact* cur = con;
	while (cur)
	{
		if (strcmp(cur->data.name, name) == 0)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

//2.删除联系人
void ContactDel(contact** pcon)
{
	char name[NAME_MAX];
	printf("请输入你要删除的联系人姓名:\n");

	scanf("%s", name);
	contact* pos = FindByName(*pcon, name);

	if (pos == NULL)
	{
		printf("该联系人不存在\n");
		return;
	}
	else
	{
		SLErase(pcon, pos);
		printf("已删除该联系人\n");
	}
	
}

//3.修改联系人
void ContactModify(contact* con)
{
	char name[NAME_MAX];
	printf("请输入你要修改的联系人姓名:\n");
	scanf("%s", name);
	contact* pos = FindByName(con, name);

	if (pos == NULL)
	{
		printf("该联系人不存在\n");
	}
	printf("该联系人姓名修改为:\n");
	scanf("%s", pos->data.name);

	printf("该联系人性别修改为:\n");
	scanf("%s", pos->data.sex);

	printf("该联系人年龄修改为:\n");
	scanf("%d", &pos->data.age);

	printf("该联系人电话修改为:\n");
	scanf("%s", pos->data.tel);

	printf("该联系人地址修改为:\n");
	scanf("%s", pos->data.addr);

	printf("修改成功\n");
}


//4.查找联系人
void ContactFind(contact* con)
{
	char name[NAME_MAX];
	printf("请输入你要查找的联系人姓名:\n");
	scanf("%s", name);
	contact* pos = FindByName(con, name);
	if (pos == NULL)
	{
		printf("该联系人不存在\n");
		return;
	}

	printf("找到了\n");
	printf("%s %s %d %s %s\n",
		pos->data.name,
		pos->data.sex,
		pos->data.age,
		pos->data.tel,
		pos->data.addr
	);
}


//5.查看通讯录
void ContactShow(contact* con)
{
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	contact* cur = con;
	while (cur)
	{
		printf("%s %s %d %s %s\n",
			cur->data.name,
			cur->data.sex,
			cur->data.age,
			cur->data.tel,
			cur->data.addr);
		cur = cur->next;
	}
}


//销毁通讯录
void ContactDestory(contact** pcon)
{
	SLDestory(pcon);
}


代码测试

当我们把通讯录的所有功能都实现了之后,最后我们在测试文件test.c中玩一下测试一下吧

【C语言】基于单链表再次实现通讯录_第2张图片

测完后,每个函数的功能都能实现,也说明我们通讯录的实现成功了(鼓掌鼓掌!!!)

结语

好了,今天的这个基于单链表实现的通讯录小项目的分享也结束了

在学习编程的道路上Humble与各位同行,加油吧各位!

最后希望大家点个免费的赞或者关注吧(感谢感谢),也欢迎大家订阅我的专栏

让我们在接下来的时间里一起成长,一起进步吧!

1d8bd2383fe54a7aa576bdd8d41dc462.png

你可能感兴趣的:(C语言进阶之数据结构,c语言,数据结构,算法,链表)