基于顺序表实现通讯录

本篇文章需要基于读者对于顺序表能理解掌握,如果对顺序表还有些许不懂,可以先看以下链接的文章:https://blog.csdn.net/xpcxpt/article/details/147466492?spm=1001.2014.3001.5501

目录:

一、通讯录的介绍

二、实现通讯录

1.准备阶段

2.通讯录的初始化

3.通讯录的销毁

4.实现通讯录的增加联系人

5.实现通讯录的删除联系人

6.展示通讯录里联系人的信息

7.实现通讯录修改联系人信息

8.查找通讯录的联系人

9.编写目录

三、代码

一、通讯录的介绍

我们想要实现通讯录,是要基于顺序表的,我们学会了对顺序表的增删查改等,而对于通讯录,我们也是需要增删查改,所以我们可以以顺序表为基础,来实现通讯录。

首先我们可以了解到,在顺序表中,我们定义了一个结构体,里面分别有数据,顺序表中有效的数据个数和顺序表容量空间的大小。

我们利用 SLdata 表示数据的类型,那如果我们要实现通讯录,一个通讯录包含很多信息,联系人的姓名,年龄,电话号码等等,所以我们可以定义一个结构体来包含他们,那显然易见,我们的SLdata,也就是数据类型将是结构体。

我们假定我们需要的联系人信息是姓名,性别,年龄,电话和家庭住址。我们还需要在顺序表文件的基础上,创建一个contact.h的头文件和一个contact.c的源文件。

二、实现通讯录

1.准备阶段

首先我们按照思路:先来创建一个结构体,将联系人信息包含在里面

这里除了年龄是数字用int类型,其他的都可以用char类型来包含,这里数组里面都用NAME_MAX这类的来表达,这样子如果数据太大,数组包含不下可以方便修改,那我们就要用#define来定义最大值,除了地址,我对于其他几个,给点都是29,地址给的是100。

我们要使用这个结构体,那我们给他改一下方便的名字,叫作PI,如下:

以上都是在contact.h的头文件里面完成的,那我们创建的这个结构体只是通讯录中的数据,我们要让顺序表知道这个的存在,所以我们需要再seq.h中包含contact.h的头文件,接着我们也需要将seq.h改成PI:

但是我们也需要让contach.h这个文件知道有struct seqlist的存在,但是我们又不能再在contact.h里面声明seq.h的头文件,因为我们已经在seq.h的文件里面声明了contact.h的头文件了,那这里就要使用一个方法,叫前置声明!我们也给顺序表改了个名字,叫Contach(通讯录 )

到此为止,还差最后一步,就是对seq.c的文件要有一些修改,我们在seq.c的文件里面,定义了查找函数:

这些都要注释掉,因为这里我们利用的是找下标,但是现在已经不是单纯的类型了,现在是我们呢自定义的结构体类型,所以不能这样子使用!

另外,打印函数也要注释掉:

这里同样,以前是基于int类型的,所以在通讯录里面不适用!

contact.c的文件记得包含头文件:

准备阶段完毕,进入通讯录的编写

2.通讯录的初始化

有了前置的准备,其实下面的内容都很简单,首先要初始化通讯录,那不就是初始化顺序表吗,所以代码如下:

3.通讯录的销毁

销毁也是一样,其实就是在通讯录的代码里面套壳顺序表:

4.实现通讯录的增加联系人

我们要添加联系人,我们就要给出提示,然后根据提示输入联系人的姓名、年龄等等,那我们一开始已经把所有信息定义在结构体PI里面了,所以直接调用就可以了:

这里一定要注意不同于其他的年龄,它是int类型

运行出来如下:

5.实现通讯录的删除联系人

在删除联系人前,我们要先确定删除的是哪个联系人,我们假定输入联系人姓名就可以删除联系人的信息,那我们需要定义一个前置函数,用来找到删除的是哪一个联系人:

接着,我们来完成删除联系人:

6.展示通讯录里联系人的信息

展示数据其实很简单,只需要遍历通讯录里面每一个联系人,然后打印出来就好了:

注意age要用%d

可以随便输入信息看一下效果:

7.实现通讯录修改联系人信息

修改联系人信息的思路和前面一样,首先要输入修改的姓名,然后利用姓名找到要修改联系人的信息,然后进行修改:

8.查找通讯录的联系人

查找的原理也是一样的,利用前置函数找到联系人姓名,然后打印联系人的所有信息:

9.编写目录

编写一个目录,方便用户查看:

首先编写一个目录,1.增加联系人 2.删除联系人 3.修改联系人 4.查找联系人 5.展示联系人 0.退出

接着我们利用dowhile循环进行输入,在利用switch语句选择要进行的操作:

三、代码

下面是全部的代码:

seq.c:

#include "seq.h"


void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

void SLDestroy(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

void checkcapacity(SL *ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLdata* tmp = (SLdata*)realloc(ps->arr, newcapacity * sizeof(SLdata));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		else
		{
			ps->arr = tmp;
			ps->capacity = newcapacity;
		}
	}
}
void SLPushBack(SL* ps, SLdata x)
{
	assert(ps);
	checkcapacity(ps);
	ps->arr[ps->size++] = x;
}

void SLPushFront(SL* ps, SLdata x)
{
	assert(ps);
	checkcapacity(ps);
	for (int i=ps->size;i>0;i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}

//void SLprint(SL s)
//{
//	for (int i = 0;i < s.size;i++)
//	{
//		printf("%d ", s.arr[i]);
//	}
//	printf("\n");
//}

void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}

void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0;i < ps->size - 1;i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

void SLInsert(SL* ps, int pos, SLdata x)
{
	assert(ps);
	//检测顺序表
	assert(pos >= 0 && pos <= ps->size);
	//确保pos的值在顺序表所限定的元素以内
	for (int i = ps->size;i > pos ; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	//顺序表从后往前,一直到pos位置,将pos位置及以后的数据往后移动一位
	ps->arr[pos] = x;
	ps->size++;
	//记得增加了一个元素,size要++
}

void SLErase(SL* ps, int pos)
{
	assert(ps);
	//检测顺序表
	assert(pos >= 0 && pos <= ps->size);
	//确保pos的值在顺序表所限定的元素以内
	for (int i = pos;i < ps->size - 1;i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	//从pos开始,直接让pos以后的元素往前移动一位,直接覆盖了pos,实现了删除
	ps->size--;
	//减少了一个元素,记得size要--
}


//int SLFind(SL* ps, SLdata x)
//{
//	assert(ps);
//	//检测顺序表
//	for (int i = 0;i < ps->size;i++)
//	{
//		if (ps->arr[i] == x)
//		{
//			return i;
//		}
//	}
//	//遍历顺序表,如果有就返回元素下标,没有就返回-1
//	return -1;
//}

seq.h:

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

#include "contact.h"

//typedef int SLdata;

typedef PI SLdata;

typedef struct seqlist
{
	SLdata* arr;
	int size;
	int capacity;
}SL;

void SLInit(SL * ps);
void SLDestroy(SL* ps);
void SLPushBack(SL* ps, SLdata x);
void SLPushFront(SL* ps, SLdata x);
void SLprint(SL s);
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos, SLdata x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLdata x);

contact.h:

#pragma once

#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 100

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

//前置声明 


typedef struct seqlist Contact;//前置声明struct Seqlist

void ContactInit(Contact* con);
void ContactDestroy(Contact* con);
void ContactAdd(Contact* con);
void ContactDel(Contact* con);
void ContactModify(Contact* con);
void ContactFind(Contact* con);
void ContactShow(Contact* con);

contact.c:

#pragma once

#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 100

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

//前置声明 


typedef struct seqlist Contact;//前置声明struct Seqlist

void ContactInit(Contact* con);
void ContactDestroy(Contact* con);
void ContactAdd(Contact* con);
void ContactDel(Contact* con);
void ContactModify(Contact* con);
void ContactFind(Contact* con);
void ContactShow(Contact* con);

test.c:

#include "seq.h"


//void test01()
//{
//	SL s1;
//	SLInit(&s1);
//	SLPushBack(&s1, 1);
//	SLPushBack(&s1, 2);
//	SLPushBack(&s1, 3);
//	SLPushBack(&s1, 4);
//	SLPushBack(&s1, 5);
//	SLprint(s1);
//	int find = SLFind(&s1, 4);
//	if (find < 0)
//	{
//		printf("没有找到\n");
//	}
//	else
//	{
//		printf("找到了,下标是%d\n", find);
//	}
//	SLDestroy(&s1);
//}
//void test01()
//{
//	Contact con;
//	ContactInit(&con);
//	ContactAdd(&con);
//	ContactShow(&con);
//	ContactDestroy(&con);
//}
void menu()
{
	printf("************************************\n");
	printf("*** 1.增加联系人 ** 2.删除联系人 ***\n");
	printf("*** 3.修改联系人 ** 4.查找联系人 ***\n");
	printf("*** 5.展示联系人 ** 0.退出       ***\n");
	printf("************************************\n");
}
int main()
{
	int input = -1;
	Contact con;
	ContactInit(&con);
	do
	{
		menu();
		printf("请选择你的操作:\n");
		scanf("%d", &input);
		switch (input)
		{
		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 (input!=0);
	ContactDestroy(&con);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值