目录
前情提示:
在学习了顺序表的基础知识后,我们就可以基于顺序表的实现来制作一个简易的通讯录项目,来增强我们对顺序表的应用和理解。
在日常通讯录的使用中,我们通常会用到:创建通讯录、销毁通讯录、增加联系人、删除联系人、查找联系人、展示通讯录等六种操作。
因此,本篇博客将对这六种功能的实现做详细的讲解。
一:定义联系人
在上一篇顺序表的基本操作中,顺序表里储存的每个元素为整形。
而在通讯录里,里面储存的每一个元素都是一个联系人。
一个联系人里面又包含许多信息,如姓名、性别、年龄、电话、住址等。
因此我们可以用一个结构体来定义联系人,并且放在contact.h中进行声明。
contact.h
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 12
#define ADDR_MAX 100
typedef struct PersonInfo
{
char name[NAME_MAX];//姓名
char sex[SEX_MAX];//性别
int age;//年龄
char tel[TEL_MAX];//电话
char add[ADDR_MAX];//住址
}People;把结构体重命名为People
并且通过#define对结构体内字符串的长度做出了限制。
二:顺序表是通讯录的底层
通讯录的实现是基于顺序表的基本操作实现的,因此我们要先把顺序表的创建(初始化)、销毁、添加、删除、查找、打印的相关操作实现出来。
先用头文件声明顺序表和顺序表的基本实现形式。
SeqList.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#include"contact.h"
typedef People SLDataType;//定义新的数据类型
#define CAPACITY 4
typedef struct Seqlist
{
SLDataType* arr;
int size; //有效数据个数
int capacity; //数组容量
} SL;
//初始化顺序表
void SLInit(SL* pa);
//销毁顺序表
void SLDel(SL* pa);
//顺序表空间检查和扩容
void SLCheakCapacity(SL* pa);
//顺序表尾部插入数据
void SLPushBack(SL* pa, SLDataType x);//x为插入的数据
//顺序表头部插入数据
void SLPushHead(SL* pa, SLDataType x);
//顺序表尾部删除数据
void SLDelBack(SL* pa);
//顺序表头部删除数据
void SLDelHead(SL* pa);
//顺序表指定位置插入数据
void SLSpecifyInsert(SL* pa, int pos, SLDataType x);//pos为插入的位置
//顺序表指定位置删除数据
void SLErase(SL* pa, int pos);
注意:我们在"SeqList.h"头文件中调用了头文件"contact.h",并且把"contact.h"中的People结构体重命名为了SLDataType类型,也是由于现在顺序表中存储的都为联系人类型的数据。
接下来就是顺序表基本操作的实现,我们在上一章已经讲解过了,这里就直接上代码。
SeqList.c
//顺序表初始化
void SLInit(SL* pa)
{
assert(pa);
pa->arr = (SLDataType*)malloc(sizeof(SLDataType) * CAPACITY);开辟动态数组
if (pa->arr==NULL)
{
perror("初始化失败");
return 1;
}
pa->size = 0;
pa->capacity = CAPACITY;
}
//销毁顺序表
void SLDel(SL* pa)
{
assert(pa);
free(pa->arr);//释放数组空间
pa->arr = NULL;
pa->size = pa->capacity =0;
}
//顺序表空间检查和扩容
void SLCheakCapacity(SL* pa)
{
assert(pa);
if (pa->size == pa->capacity)
{
SLDataType *pb;
pb = (SLDataType*)realloc(pa->arr, sizeof(SLDataType) * pa->capacity * 2);//扩容
if (pb == NULL)
{
perror("扩容失败");
return 1;
}
free(pa->arr);
pa->arr = pb;
pa->capacity *= 2;
}
}
//顺序表尾部插入数据
void SLPushBack(SL* pa, SLDataType x)
{
assert(pa);
SLCheakCapacity(pa);//扩容
pa->arr[pa->size] = x;
pa->size++;
}
//顺序表头部插入数据
void SLPushHead(SL* pa, SLDataType x)
{
SLCheakCapacity(pa);
for (int i = pa->size; i > 0; i--)
{
pa->arr[i] = pa->