【数据结构项目】基于单链表实现的通讯录

2024-06-06 20:55:06 浏览数 (2)

一、准备知识

主要的就是单链表相关的知识,我们在之前已经实现过了基于顺序表的通讯录,这里我们新学习了单链表,我们用单链表实现一下通讯录项目 需要的内容:单链表,指针,循环,结构体等知识

二、写之前的思路

我们需要一个单链表文件,在这里我给它们分别命名为project.h和project.c,然后是通讯录文件tel.h和tel.c,最后就是测试文件test.c 单链表文件我们就不必多说了,上篇博文中有,这里我们直接将上篇博文中的内容复制粘贴过来了,主要来实现通讯录

project.h

代码语言:javascript复制
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "tel.h"
typedef PeoInfo SLTDataType;
typedef struct SListNode
{
	SLTDataType* data; //节点数据
	struct SListNode* next; //指针保存下?个节点的地址
}SLTNode;
//打印
void SLTPrint(SLTNode* phead);
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);
//尾删
void SLTPopBack(SLTNode** pphead);
//头删
void SLTPopFront(SLTNode** pphead);
//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);
//在指定位置之后插?数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos);
//销毁链表
void SListDesTroy(SLTNode** pphead);
//创建节点
SLTNode* SLTBuyNode(SLTDataType x);

project.c

代码语言:javascript复制
#include "project.h"

//打印
void SLTPrint(SLTNode* phead)
{
	assert(phead);
	SLTNode* pur = phead;
	while (pur)
	{
		printf("%s ", pur->data->name);
		printf("%s ", pur->data->sex);
		printf("%d ", pur->data->age);
		printf("%s ", pur->data->tel);
		printf("%s ", pur->data->addr);
		printf("n");
		pur = pur->next;
	}
}

//创建节点
SLTNode* SLTBuyNode(SLTDataType x)
{
	SLTNode* newcode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newcode == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	*newcode->data = x;
	newcode->next = NULL;
	return newcode;
}
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* new = SLTBuyNode(x);
	if (*pphead == NULL)
	{
		*pphead = new;
	}
	else
	{
		SLTNode* pur = *pphead;
		while (pur->next)
		{
			pur = pur->next;
		}
		pur->next = new;
	}
}
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* new = SLTBuyNode(x);
	new->next = *pphead;
	*pphead = new;
}

void SLTPopBack(SLTNode** pphead)
{
	assert(pphead && *pphead);
	SLTNode* pur = *pphead;
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLTNode* prev = *pphead;
		SLTNode* ptail = *pphead;
		while (ptail->next)
		{
			prev = ptail;
			ptail = ptail->next;
		}
		prev->next = NULL;
		ptail = NULL;
		free(ptail);
	}
}
//头删
void SLTPopFront(SLTNode** pphead)
{
	assert(pphead && *pphead);
	SLTNode* node = (*pphead)->next;
	(*pphead)->next = NULL;
	free(*pphead);
	*pphead = node;
}
//指定位置前插
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead && *pphead);
	assert(pos);
	SLTNode* pur = *pphead;
	SLTNode* new = SLTBuyNode(x);
	if (*pphead == pos)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		while (pur->next != pos)
		{
			pur = pur->next;
		}
		new->next = pos;
		pur->next = new;
		
	}
}
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(*pphead);
	if (*pphead == pos)
	{
		SLTNode* prev = *pphead;
		*pphead = (*pphead)->next;
		free(prev);
	}
	else
	{
		SLTNode* pur = *pphead;
		while (pur->next != pos)
		{
			pur = pur->next;
		}
		SLTNode* pucr = pos->next;
		pur->next = pucr;
		pos->next = NULL;
		free(pos);
	}
}
//在指定位置后插入节点
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	SLTNode* new = SLTBuyNode(x);
	SLTNode* pur = pos->next;
	pos->next = new;
	new->next = pur;
}
//删除pos后边这个节点
void SLTEraseAfter(SLTNode* pos)
{
	SLTNode* pur = pos->next;
	SLTNode* pucr = pur->next;
	pos->next = pucr;
	pur->next = NULL;
	free(pur);
}
//销毁链表
void SListDesTroy(SLTNode** pphead)
{
	SLTNode* pur = *pphead;
	while ((*pphead)->next != NULL)
	{
		pur = *pphead;
		*pphead = (*pphead)->next;
		pur->next = NULL;
		free(pur);
	}
	free(*pphead);
}

tel.h

代码语言:javascript复制
#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100

//前置声明
typedef struct SListNode contact;

//用户数据
typedef struct PersonInfo
{
    char name[NAME_MAX];
    char sex[SEX_MAX];
    int age;
    char tel[TEL_MAX];
    char addr[ADDR_MAX];
}PeoInfo;

//初始化通讯录
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);

tel.c

代码语言:javascript复制
#include "tel.h"
#include "project.h"


//初始化通讯录
void InitContact(contact** con)
{
	*con = (contact*)malloc(sizeof(contact));
	if (*con == NULL) 
		return;
	(*con)->data = NULL;
	(*con)->next = NULL;
}

//添加通讯录数据
void AddContact(contact** con)
{
	PeoInfo* i = (PeoInfo*)malloc(sizeof(PeoInfo));//定义一个通讯录用户
	if (i == NULL)
	{
		return;
	}
	printf("请输入联系人姓名:n");
	scanf("%s", i->name);
	printf("请输入联系人性别:n");
	scanf("%s", i->sex);
	printf("请输入联系人年龄:n");
	scanf("%d", &i->age);
	printf("请输入联系人电话:n");
	scanf("%s", i->tel);
	printf("请输入联系人地址:n");
	scanf("%s", i->addr);
	printf("添加成功!n");
	contact* newcode = (contact*)malloc(sizeof(contact));
	if (newcode == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	contact* pur = *con;
	while (pur->next)
	{
		pur = pur->next;
	}
	newcode->data = i;
	pur->next = newcode;
	newcode->next = NULL;
}
//删除通讯录数据
void DelContact(contact** con)
{
	contact* n = (*con)->next;
	contact* prev = NULL;
	char name[NAME_MAX];
	printf("请输入你要删除的联系人:n");
	scanf("%s", name);
	if (strcmp(n->data->name, name) == 0 && n)
	{
		*con = n->next;
		free(n);
		return;
	}
	while (strcmp(n->data->name, name) && n)
	{
		prev = n;
		n = n->next;
	}
	if (n == NULL)
	{
		printf("不存在这个数据n");
	}
	else
	{
		if (prev == NULL) // 如果要删除的是头节点  
		{
			*con = n->next; // 更新头指针  
		}
		else
		{
			prev->next = n->next;
			free(n->data);
			free(n);
			printf("删除成功!n");
		}
	}
}

//展示所有通讯录数据
void ShowContact(contact* con)
{
	assert(con);
	contact* pur = con->next;
	while (pur != NULL)
	{
		printf("%5s %5s %5s %5s %5sn", "姓名","性别","年龄","电话","地址");
		printf("%5s ", pur->data->name);
		printf("%5s ", pur->data->sex);
		printf("] ", pur->data->age);
		printf("%5s ", pur->data->tel);
		printf("%5s ", pur->data->addr);
		printf("n");
		pur = pur->next;
	}
}

//查找通讯录数据
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找人的姓名:n");
	scanf("%s", name);
	contact* n = con->next;
	while (strcmp(n->data->name, name) && n)
	{
		n = n->next;
	}
	if (n == NULL)
	{
		printf("此用户不存在!n");
		return;
	}
	printf("被查找到人的信息:n");
	printf("%5s %5s %5s %5s %5sn", "姓名","性别","年龄","电话","地址");
	printf("%5s ", n->data->name);
	printf("%5s ", n->data->sex);
	printf("] ", n->data->age);
	printf("%5s ", n->data->tel);
	printf("%5s ", n->data->addr);
	printf("n");
}

//修改通讯录数据
void ModifyContact(contact** con)
{
	char name[NAME_MAX];
	printf("请输入你要修改对象的原姓名:n");
	scanf("%s", name);
	contact* n = (*con)->next;
	while (strcmp(n->data->name, name) && n)
	{
		n = n->next;
	}
	if (n == NULL)
	{
		printf("此用户不存在!n");
		return;
	}
	printf("请输入你要修改对象的姓名:n");
	scanf("%s", n->data->name);
	printf("请输入你要修改对象的性别:n");
	scanf("%s", n->data->sex);
	printf("请输入你要修改对象的年龄:n");
	scanf("%d", &n->data->age);
	printf("请输入你要修改对象的电话:n");
	scanf("%s", n->data->tel);
	printf("请输入你要修改对象的地址:n");
	scanf("%s", n->data->addr);
	printf("修改成功!n");
}
//
//销毁通讯录数据
void DestroyContact(contact** con)
{
	SListDesTroy(con);
}

test.c

代码语言:javascript复制
#include "tel.h"
void test1()
{
	contact* s1;
	InitContact(&s1);
	AddContact(&s1);
	ShowContact(s1);
	AddContact(&s1);
	ShowContact(s1);
	/*AddContact(&s1);
	ShowContact(s1);
	DelContact(&s1);
	ShowContact(s1);*/
	//FindContact(s1);
	ModifyContact(&s1);
	ShowContact(s1);
	DestroyContact(&s1);
}
int main()
{
	test1();
	return 0;
}

调试结果

今天的分享就到这里了~

0 人点赞