跳到主要内容数据结构:顺序表实现通讯录实战 | 极客日志C算法
数据结构:顺序表实现通讯录实战
基于 C 语言顺序表实现通讯录功能,涵盖结构体定义、初始化、销毁、增删改查及展示操作。通过封装 Seqlist 与 Contact 模块,演示了动态内存管理、结构体数组存储及字符串处理等核心知识点,适合数据结构初学者巩固线性表实操。
佛系玩家4 浏览 一、通讯录的实现前期思考
对于通讯录,我们要做的就是初始化,销毁,添加,删除,修改,查找,展示联系人数据。这和顺序表的操作如出一辙,顺序表就是通讯录的底层存储结构。通讯录是对联系人数据的操作,而一条联系人数据包括姓名、性别、年龄、电话、住址等,这些数据可以包含在一个结构体中。
二、通讯录的实现
1. 前期准备
在之前顺序表三个文件 Seqlist.h、Seqlist.c、test.c 的基础上,增加 Contact.c、Contact.h 两个文件作为通讯录的源文件和头文件。
- 在 Contact.h 中定义结构体以及声明通讯录实现的方法。
- 在 Contact.c 中实现通讯录项目。
2. 注意事项(重点难点易错点)
- 在 Contact.h 中定义结构体并进行类型重命名 peoInfo。
- 原本顺序表是存储整型数据,所以需要把 Seqlist.h 中的
typedef int SLDataType 改为自定义类型 typedef struct personInfo SLDataType,这里用到了结构体类型的数据,所以需要包含通讯录的头文件 Contact.h。
- 因为通讯录和顺序表是等同的,所以将顺序表改名为通讯录,在 Contact.h 中前置声明
struct Seqlist 并给顺序表改名为 Contact。
- 为什么是
struct Seqlist 而不是 SL,因为在 Contact.h 中没有包含顺序表的头文件(头文件不能互相包含),所以找不到 SL,但为什么能够 typedef peoInfo SLDataType,因为在 Seqlist.h 中包含了 Contact.h,所以没有使用 struct personInfo。
- 把之前关于整形数据的打印和查找删掉,因为通讯录用到的是结构体这种自定义类型数据。
三、通讯录的实现
1. 定义结构体
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 100
#define ADDR_MAX 100
struct personInfo {
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
};
typedef struct personInfo peoInfo;
2. 通讯录的初始化
void ContactInit(Contact *con) {
SLInit(con);
}
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
3. 通讯录的销毁
void ContactDestroy(Contact *con) {
SLDestroy(con);
}
4. 添加联系人数据
void ContactAdd(Contact *con) {
peoInfo info;
printf("请输入新添加的联系人名字:\n");
scanf("%s", info.name);
printf("请输入新添加的联系人性别:\n");
scanf("%s", info.gender);
printf("请输入新添加的联系人年龄:\n");
scanf("%d", &info.age);
printf("请输入新添加的联系人电话:\n");
scanf("%s", info.tel);
printf("请输入新添加的联系人住址:\n");
scanf("%s", info.addr);
SLPushBack(con, info);
}
5. 删除联系人数据
int FindByName(Contact *con, char name[]) {
for (int i = 0; i < con->size; i++) {
if (strcmp(name, con->arr[i].name) == 0) {
return i;
}
}
return -1;
}
void ContactDel(Contact *con) {
char name[NAME_MAX];
printf("请输入要删除的联系人名字:\n");
scanf("%s", name);
int find = FindByName(con, name);
if (find < 0) {
printf("要删除的联系人数据不存在\n");
}
SLErase(con, find);
printf("删除成功\n");
}
6. 修改联系人数据
void ContactModify(Contact *con) {
char name[NAME_MAX];
printf("请输入要修改的联系人名字:\n");
scanf("%s", name);
int find = FindByName(con, name);
if (find < 0) {
printf("要修改的联系人数据不存在\n");
return;
}
printf("请输入新的联系人姓名\n");
scanf("%s", con->arr[find].name);
printf("请输入新的联系人性别\n");
scanf("%s", con->arr[find].gender);
printf("请输入新的联系人年龄\n");
scanf("%d", &con->arr[find].age);
printf("请输入新的联系人电话\n");
scanf("%s", con->arr[find].tel);
printf("请输入新的联系人住址\n");
scanf("%s", con->arr[find].addr);
printf("修改成功\n");
}
7. 展示联系人数据
void ContactShow(Contact *con) {
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
for (int i = 0; i < con->size; i++) {
printf("%s %s %d %s %s\n", con->arr[i].name, con->arr[i].gender, con->arr[i].age, con->arr[i].tel, con->arr[i].addr);
}
}
8. 查找联系人数据
void ContactFind(Contact *con) {
char name[NAME_MAX];
printf("请输入要查找的联系人姓名\n");
scanf("%s", name);
int find = FindByName(con, name);
if (find < 0) {
printf("要查找的联系人数据不存在\n");
return;
}
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%s %s %d %s %s\n", con->arr[find].name, con->arr[find].gender, con->arr[find].age, con->arr[find].tel, con->arr[find].addr);
}
9. 总代码展示
9.1 Contact.h
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
struct personInfo {
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
};
typedef struct personInfo peoInfo;
typedef struct Seqlist Contact;
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);
9.2 Contact.c
#include"Contact.h"
#include"Seqlist.h"
void ContactInit(Contact *con) {
SLInit(con);
}
void ContactDestroy(Contact *con) {
SLDestroy(con);
}
void ContactAdd(Contact* con) {
peoInfo info;
printf("请输入要添加的联系人姓名:\n");
scanf("%s", info.name);
printf("请输入要添加的联系人年龄:\n");
scanf("%d", &info.age);
printf("请输入要添加的联系人性别:\n");
scanf("%s", info.gender);
printf("请输入要添加的联系人电话:\n");
scanf("%s", info.tel);
printf("请输入要添加的联系人住址:\n");
scanf("%s", info.addr);
SLPushBack(con, info);
}
int FindByName(Contact* con, char name[]) {
for (int i = 0; i < con->size; i++) {
if (0 == strcmp(con->arr[i].name, name)) {
return i;
}
}
return -1;
}
void ContactDel(Contact* con) {
char name[NAME_MAX];
printf("请输入要删除的联系人姓名:\n");
scanf("%s", name);
int find = FindByName(con, name);
if (find < 0) {
printf("要删除的联系人数据不存在\n");
return;
}
SLErase(con, find);
printf("删除成功\n");
}
void ContactShow(Contact* con) {
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
for (int i = 0; i < con->size; i++) {
printf("%s %s %d %s %s\n", con->arr[i].name, con->arr[i].gender, con->arr[i].age, con->arr[i].tel, con->arr[i].addr);
}
}
void ContactModify(Contact* con) {
char name[NAME_MAX];
printf("请输入要修改的用户姓名\n");
scanf("%s", name);
int find = FindByName(con, name);
if (find < 0) {
printf("要修改的联系人数据不存在\n");
return;
}
printf("请输入新的姓名\n");
scanf("%s", con->arr[find].name);
printf("请输入新的性别\n");
scanf("%s", con->arr[find].gender);
printf("请输入新的年龄\n");
scanf("%d", &con->arr[find].age);
printf("请输入新的电话\n");
scanf("%s", con->arr[find].tel);
printf("请输入新的地址\n");
scanf("%s", con->arr[find].addr);
printf("修改成功\n");
}
void ContactFind(Contact* con) {
char name[NAME_MAX];
printf("请输入要查找的联系人姓名\n");
scanf("%s", name);
int find = FindByName(con, name);
if (find < 0) {
printf("要查找的联系人数据不存在\n");
return;
}
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%s %s %d %s %s\n", con->arr[find].name, con->arr[find].gender, con->arr[find].age, con->arr[find].tel, con->arr[find].addr);
}
9.3 Seqlist.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
typedef peoInfo SLDataType;
struct Seqlist {
SLDataType* arr;
int size;
int capacity;
};
typedef struct Seqlist SL;
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
9.4 Seqlist.c
#include"Seqlist.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 SLCheckCapacity(SL* ps) {
if (ps->capacity == ps->size)
{
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));
if (tmp == NULL) {
perror("realloc fail");
exit(1);
}
ps->arr = tmp;
ps->capacity = newCapacity;
}
}
void SLPushBack(SL* ps, SLDataType x) {
assert(ps);
SLCheckCapacity(ps);
ps->arr[ps->size] = x;
++ps->size;
}
void SLPushFront(SL* ps, SLDataType x) {
assert(ps);
SLCheckCapacity(ps);
for (int i = ps->size - 1; i >= 0; i--) {
ps->arr[i + 1] = ps->arr[i];
}
ps->arr[0] = x;
ps->size++;
}
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, SLDataType x) {
assert(ps);
assert(pos >= 0 && pos <= ps->size);
SLCheckCapacity(ps);
for (int i = ps->size; i > pos; i--) {
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[pos] = x;
ps->size++;
}
void SLErase(SL* ps, int pos) {
assert(ps);
assert(ps->size);
assert(pos >= 0 && pos < ps->size);
for (int i = pos; i < ps->size - 1; i++) {
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
9.5 test.c
#include"Seqlist.h"
void menu() {
printf("******************通讯录********************\n");
printf("******1.增加联系人*********2.删除联系人*****\n");
printf("******3.修改联系人*********4.查找联系人*****\n");
printf("******5.展示联系人*********0. 退出 *****\n");
printf("******************通讯录********************\n");
}
int main() {
int op = -1;
Contact con;
ContactInit(&con);
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:
break;
}
} while (op);
return 0;
}