数据结构·顺序表实现通讯录

目录

1 基本格式

2 结构体的声明

3 初始化 销毁 扩容 插入 删除

4 增加联系人

5 查看通讯录

6 删除联系人

7 查找联系人

8 修改联系人

9 整体代码


引言:

有了前面顺序表的基础,我们可以尝试利用顺序表实现通讯录,日常使用中,通讯录可以实现的功能有增加联系人,删除联系人,查找联系人,修改联系人,查看联系人等,我们通过本章的学习实现以上五种功能(默认通讯录包含的元素有 名称 性别 年龄 电话号码 地址 )


1 基本格式

通讯录算是一个小的程序了,人们在使用之前都习惯于有菜单,所以我们使用do-while循环,加上switch语句,可以打印菜单,并且用户可以多次选择执行的操作:

void menu()
{
	printf("************通讯录***************\n");
	printf("***1 增加联系人   2 删除联系人***\n");
	printf("***3 查看通讯录   4 修改联系人***\n");
	printf("***5 查找联系人   0 退出通讯录***\n");
}
int main()
{
	int input = 0;
	Seq con;
	ConInit(&con);
	do
	{
		menu();
		
		printf("请输入您的操作:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			ContactAdd(&con);//增加联系人
			break;
		case 2:
			ContactDel(&con);//删除联系人
			break;
		case 3:
			ContactPrint(&con);//查看通讯录
			break;
		case 4:
			ContactMod();//修改联系人
			break;
		case 5:
			ContactFind();//查找联系人
			break;
		case 0:
			printf("正在退出通讯录……\n");
			break;
		default:
			printf("操作无效,重新输入:\n");
			break;
		}
	} while (input);
	ConDestroy(&con);
	return 0;
}

case 对应的语句就是我们要执行的操作,大的操作有增删查改以及查找五个操作,那么在实现之前,顺序表的结构体类型,结构体的初始化,空间扩容,空间的销毁等都是要先写上的,为了方便起见,我们使用两个.c文件,一个.h文件,提高代码的整洁度,一个是contact.c文件,一个是contact.h文件(contact是通讯录的意思),同上篇文章一样,函数的声明,结构体的定义放在头文件里面,函数的具体实现放在contact.c文件里面。


2 结构体的声明

#pragma once
#define NAME_MAX 100
#define TEL_MAX 12
#define GENDER_MAX 10
#define ADDR_MAX 100


typedef struct Contact
{
	int age;
	char name[NAME_MAX];
	char tel[TEL_MAX];
	char gender[GENDER_MAX];
	char addr[ADDR_MAX];
}Con;

typedef Con Datatype;

typedef struct St
{
	Datatype* arr;
	int size;//有效数据个数
	int capacity;//空间大小
}Seq;

在contact头文件里面我们创建好联系人对应的结构体变量Contact,为了方便起见重命名为Con,随后我们创建好一个结构体变量用来给联系人开辟空间,这里可能有点绕,重命名Contact的目的是为了之后数据的易转换,像int全转为float类型,重命名St的目的是为了之后传参方便,我们传参传的是结构体本身,可以理解为Seq*指针指向的arr是Datatype类型的,而Datatype类型又是Con结构的,Con结构体就是我们需要的联系人数据类型,开辟空间的时候就是以整个结构体开辟空间的。


3 初始化 销毁 扩容 插入 删除

void ConInit(Seq* pcon)//初始化
{
	pcon->arr = NULL;
	pcon->size = pcon->capacity = 0;
}
void ConDestroy(Seq* pcon)//销毁
{
	assert(pcon);
	pcon->arr = NULL;
	pcon->size = pcon->capacity = 0;
	free(pcon->arr);
}

初始化和销毁和顺序表的初始化销毁是一样的,当然,引用的头文件不能忘记,指针断言,空间释放都是不能忘记的。

插入数据的时候,我们这里为了方便起见,就用尾部插入,删除我们使用的是指定位置删除,因为之后的删除联系人需要系统需要知道联系人的位置,所以采用的是指定位置删除:

void ConCheckCapacity(Seq* pcon)//扩容
{
	if (pcon->capacity == 0)
	{
		pcon->arr = (Datatype*)malloc(4 * sizeof(Datatype));
		pcon->capacity = 4;
	}
	if (pcon->capacity == pcon->size)
	{
		Datatype* tem = (Datatype*)realloc(pcon->arr, 2 * pcon->capacity * sizeof(Datatype));
		if (tem != NULL)
		{
			pcon->arr = tem;
			pcon->capacity *= 2;
		}
		else
		{
			perror("realloc fail!");
			return;
		}
	}
}
void ConPushBack(Seq* pcon, Datatype x)//尾插
{
	assert(pcon);
	ConCheckCapacity(pcon);
	pcon->arr[pcon->size++] = x;
}
void ContactErase(Seq* pcon, int pos)//指定删除
{
	assert(pcon);
	assert(pos >= 0 && pos < pcon->size);
	for (int i = pos; i < pcon->size - 1; i++)
	{
		pcon->arr[i] = pcon->arr[i + 1];
	}
	pcon->size--;
}

这五个基本操作可以说是为了后面的几大功能做铺垫,且与之前的顺序表并无两样。


4 增加联系人

增加联系人之前,我们已经做好了初始化 判断扩容 插入等基本操作,现在增加联系人可以说是易如反掌了:
我们添加联系人之前,我们需要先创建好一个联系人,这时候就用上了之前重命名的Con结构体了,然后就是大同小异的输入,输出,最后使用尾插函数,把这个联系人存储进去就行了。

void ContactAdd(Seq* pcon)//增加联系人
{
	Con contact;
	printf("输入联系人姓名:");
	scanf("%s", contact.name);
	printf("输入联系人性别:");
	scanf("%s", contact.gender);
	printf("输入联系人年龄:");
	scanf("%d", contact.age);
	printf("输入联系人电话:");
	scanf("%s", contact.tel);
	printf("输入联系人地址:");
	scanf("%s", contact.addr);
	ConPushBack(pcon, contact);
	printf("添加成功!");
}

5 查看通讯录

查看通讯录无非就是打印通讯录,那么只需要用上最基本的for循环就行了:

void ContactPrint(Seq* pcon)//查看通讯录
{
	assert(pcon);
	printf("姓名  性别  年龄  电话号码  地址\n");
	for (int i = 0; i < pcon->size; i++)
	{
		printf("%s %s %d %s %s", pcon->arr[i].name,
			pcon->arr[i].gender,
			pcon->arr[i].age,
			pcon->arr[i].tel,
			pcon->arr[i].addr);
	}
	printf("\n");
}

为了界面整洁我们可以在打印联系人数据的时候打印出联系人的基本框架出来:

最后就是换行符不要忘记就行。


6 删除联系人

在执行删除联系人之前应该先遍历整个通讯录看有没有这个联系人,如果没有,也就不存在删除的说法,所以下一个实现的函数是查找联系人,联系人有多种数据,其中重叠可能性最小的是姓名,即我们可以使用姓名来查找联系人,因为查找联系人是为了之后的删除,修改联系人做准备,查找联系人的返回值可以有正负,i -1,i就表示找到了,存在这个联系人,下标为i,-1就表示没有找到,不存在这个联系人:

int FindByname(Seq* pcon,char name[NAME_MAX])//通过姓名寻找
{
	for (int i = 0; i < pcon->size; i++)
	{
		if (strcmp(name, pcon->arr[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}

我们是通过联系人姓名来寻找的,所以首先遍历空空间,利用strcmp的返回值来判断是否存在

void ContactDel(Seq* pcon)//删除联系人
{
	assert(pcon);
	char name[NAME_MAX];
	printf("请输入要删除的联系人的姓名:");
	scanf("%s", name);
	int tem = FindByname(pcon, name);
	if (tem < 0)
	{
		printf("要删除的联系人不存在!");
		return;
	}
	ContactErase(pcon, tem);
	printf("删除成功!\n");
}

删除就是利用的返回值,大于0呢,就删除,小于0就直接返回。


7 查找联系人

查找联系人用到的函数其实就是FIndByname函数,只不过加了一点点改变而已,通过返回值进行判断,然后进行打印就行了:

void ContactFind(Seq* pcon)//查找联系人
{
	assert(pcon);
	char name[NAME_MAX];
	printf("请输入联系人姓名:");
	scanf("%s", name);
	int tem = FindByname(pcon, name);
	if (tem >= 0)
	{
		printf("找到了!\n");
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%s %s %d %s %s\n", pcon->arr[tem].name,
			pcon->arr[tem].gender,
			pcon->arr[tem].age,
			pcon->arr[tem].tel,
			pcon->arr[tem].addr);
	}
	else
	{
		printf("联系人不存在!\n");
	}
}

8 修改联系人

修改联系人的基础是在于能否找到,所以还是需要FindByname函数,找到这个联系人之后,我们就需要利用返回的下标,来实现修改联系人数据:

void ContactMod(Seq* pcon)//修改联系人
{
	assert(pcon);
	char name[NAME_MAX];
	printf("请输入要修改的联系人的姓名:");
	scanf("%s", name);
	int tem = FindByname(pcon, name);
	if (tem >= 0)
	{
		printf("存在该联系人,请修改:\n");
		printf("输入联系人姓名:");
		scanf("%s", pcon->arr[tem].name);
		printf("输入联系人性别:");
		scanf("%s", pcon->arr[tem].gender);
		printf("输入联系人年龄:");
		scanf("%d", pcon->arr[tem].age);
		printf("输入联系人电话:");
		scanf("%s", pcon->arr[tem].tel);
		printf("输入联系人地址:");
		scanf("%s", pcon->arr[tem].addr);
		printf("修改成功!\n");
	}
	else
	{
		printf("不存在该联系人!\n");
	}
}

在每次函数开头的时候,我们都应该使用assert断言,因为我们不知道程序执行到这一步的时候指针有没有变成空指针,在使用完FindByname的时候,我们利用下标进行修改,修改为无非就是进行重新输入。


9 整体代码

以上就就是顺序表实现通讯录的全部过程,整体代码如下:

contact头文件:

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define NAME_MAX 100
#define TEL_MAX 12
#define GENDER_MAX 10
#define ADDR_MAX 100


typedef struct Contact
{
	int age;
	char name[NAME_MAX];
	char tel[TEL_MAX];
	char gender[GENDER_MAX];
	char addr[ADDR_MAX];
}Con;

typedef Con Datatype;

typedef struct St
{
	Datatype* arr;
	int size;//有效数据个数
	int capacity;//空间大小
}Seq;

void ConInit(Seq* pcon);//初始化
void ConDestroy(Seq* pcon);//销毁
void ConCheckCapacity(Seq* pcon);//扩容
void ConPushBack(Seq* pcon, Datatype x);//尾插
void ContactErase(Seq* pcon, int pos);//指定删除
void ContactAdd(Seq* pcon);// 增加联系人
void ContactPrint(Seq* pcon);//查看通讯录
void ContactDel(Seq* pcon);//删除联系人
void ContactMod(Seq* pcon);//修改联系人
void ContactFind(Seq* pcon);//查找联系人

contact.c文件: 

#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void ConInit(Seq* pcon)//初始化
{
	pcon->arr = NULL;
	pcon->size = pcon->capacity = 0;
}
void ConDestroy(Seq* pcon)//销毁
{
	assert(pcon);
	pcon->arr = NULL;
	pcon->size = pcon->capacity = 0;
	free(pcon->arr);
}
void ContactErase(Seq* pcon, int pos)//指定删除
{
	assert(pcon);
	assert(pos >= 0 && pos < pcon->size);
	for (int i = pos; i < pcon->size - 1; i++)
	{
		pcon->arr[i] = pcon->arr[i + 1];
	}
	pcon->size--;
}
void ConCheckCapacity(Seq* pcon)//扩容
{
	if (pcon->capacity == 0)
	{
		pcon->arr = (Datatype*)malloc(4 * sizeof(Datatype));
		pcon->capacity = 4;
	}
	if (pcon->capacity == pcon->size)
	{
		Datatype* tem = (Datatype*)realloc(pcon->arr, 2 * pcon->capacity * sizeof(Datatype));
		if (tem != NULL)
		{
			pcon->arr = tem;
			pcon->capacity *= 2;
		}
		else
		{
			perror("realloc fail!");
			return;
		}
	}
}
void ConPushBack(Seq* pcon, Datatype x)//尾插
{
	assert(pcon);
	ConCheckCapacity(pcon);
	pcon->arr[pcon->size++] = x;
}
void ContactAdd(Seq* pcon)//增加联系人
{
	Con contact;
	printf("输入联系人姓名:");
	scanf("%s", contact.name);
	printf("输入联系人性别:");
	scanf("%s", contact.gender);
	printf("输入联系人年龄:");
	scanf("%d", &contact.age);
	printf("输入联系人电话:");
	scanf("%s", contact.tel);
	printf("输入联系人地址:");
	scanf("%s", contact.addr);
	ConPushBack(pcon, contact);
	printf("添加成功!\n");
}
void ContactPrint(Seq* pcon)//查看通讯录
{
	assert(pcon);
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (int i = 0; i < pcon->size; i++)
	{
		printf("%s %s %d %s %s\n", pcon->arr[i].name,
			pcon->arr[i].gender,
			pcon->arr[i].age,
			pcon->arr[i].tel,
			pcon->arr[i].addr);
	}
	printf("\n");
}
int FindByname(Seq* pcon,char name[NAME_MAX])//通过姓名寻找
{
	for (int i = 0; i < pcon->size; i++)
	{
		if (strcmp(name, pcon->arr[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void ContactDel(Seq* pcon)//删除联系人
{
	assert(pcon);
	char name[NAME_MAX];
	printf("请输入要删除的联系人的姓名:");
	scanf("%s", name);
	int tem = FindByname(pcon, name);
	if (tem < 0)
	{
		printf("要删除的联系人不存在!");
		return;
	}
	ContactErase(pcon, tem);
	printf("删除成功!\n");
}
void ContactMod(Seq* pcon)//修改联系人
{
	assert(pcon);
	char name[NAME_MAX];
	printf("请输入要修改的联系人的姓名:");
	scanf("%s", name);
	int tem = FindByname(pcon, name);
	if (tem >= 0)
	{
		printf("存在该联系人,请修改:\n");
		printf("输入联系人姓名:");
		scanf("%s", pcon->arr[tem].name);
		printf("输入联系人性别:");
		scanf("%s", pcon->arr[tem].gender);
		printf("输入联系人年龄:");
		scanf("%d", pcon->arr[tem].age);
		printf("输入联系人电话:");
		scanf("%s", pcon->arr[tem].tel);
		printf("输入联系人地址:");
		scanf("%s", pcon->arr[tem].addr);
		printf("修改成功!\n");
	}
	else
	{
		printf("不存在该联系人!\n");
	}
}
void ContactFind(Seq* pcon)//查找联系人
{
	assert(pcon);
	char name[NAME_MAX];
	printf("请输入联系人姓名:");
	scanf("%s", name);
	int tem = FindByname(pcon, name);
	if (tem >= 0)
	{
		printf("找到了!\n");
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%s %s %d %s %s\n", pcon->arr[tem].name,
			pcon->arr[tem].gender,
			pcon->arr[tem].age,
			pcon->arr[tem].tel,
			pcon->arr[tem].addr);
	}
	else
	{
		printf("联系人不存在!\n");
	}
}

  主函数.c: 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "Contact.h"
void menu()
{
	printf("************通讯录***************\n");
	printf("***1 增加联系人   2 删除联系人***\n");
	printf("***3 查看通讯录   4 修改联系人***\n");
	printf("***5 查找联系人   0 退出通讯录***\n");
}
int main()
{
	int input = 0;
	Seq con;
	ConInit(&con);
	do
	{
		menu();
		
		printf("请输入您的操作:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			ContactAdd(&con);//增加联系人
			break;
		case 2:
			ContactDel(&con);//删除联系人
			break;
		case 3:
			ContactPrint(&con);//查看通讯录
			break;
		case 4:
			ContactMod(&con);//修改联系人
			break;
		case 5:
			ContactFind(&con);//查找联系人
			break;
		case 0:
			printf("正在退出通讯录……\n");
			break;
		default:
			printf("操作无效,重新输入:\n");
			break;
		}
	} while (input);
	ConDestroy(&con);
	return 0;
}

感谢阅读!

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是用 Python 数据结构顺序表实现通讯录编辑代码: ```python class Contact: def __init__(self, name, phone): self.name = name self.phone = phone class ContactList: def __init__(self): self.contacts = [] def add_contact(self, name, phone): contact = Contact(name, phone) self.contacts.append(contact) def remove_contact(self, name): for contact in self.contacts: if contact.name == name: self.contacts.remove(contact) return def update_contact(self, name, phone): for contact in self.contacts: if contact.name == name: contact.phone = phone return def search_contact(self, name): for contact in self.contacts: if contact.name == name: return contact.phone def display_contacts(self): for contact in self.contacts: print(f"{contact.name}: {contact.phone}") contact_list = ContactList() while True: print("***************************") print("欢迎使用通讯录") print("1. 添加联系人") print("2. 删除联系人") print("3. 修改联系人") print("4. 查找联系人") print("5. 显示所有联系人") print("0. 退出程序") print("***************************") choice = int(input("请输入对应操作的数字:")) if choice == 0: break elif choice == 1: name = input("请输入联系人姓名:") phone = input("请输入联系人电话:") contact_list.add_contact(name, phone) print("联系人添加成!") elif choice == 2: name = input("请输入要删除的联系人姓名:") contact_list.remove_contact(name) print("联系人删除成!") elif choice == 3: name = input("请输入要修改的联系人姓名:") phone = input("请输入修改后的电话号码:") contact_list.update_contact(name, phone) print("联系人修改成!") elif choice == 4: name = input("请输入要查找的联系人姓名:") phone = contact_list.search_contact(name) if phone: print(f"{name}的电话号码是:{phone}") else: print("联系人不存在!") elif choice == 5: contact_list.display_contacts() else: print("无效的选择,请重新输入!") ``` 这个程序中,我们定义了两个类:`Contact` 和 `ContactList`。`Contact` 类表示一个联系人,包括姓名和电话号码;`ContactList` 类表示一个通讯录,包含了添加联系人、删除联系人、修改联系人、查找联系人和显示所有联系人等操作。 在程序运行时,我们不断循环,根据用户输入的选择执行相应的操作。用户可以通过输入数字来选择不同的操作。每个操作都会调用 `ContactList` 中对应的方法来实现能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值