顺序表实现--通讯录

简介: 顺序表实现--通讯录

前言:

       通过对数据结构--顺序表的学习,了解了顺序表的增加数据,删除数据等功能;我们就可以基于顺序表来实现通讯录,接下来就一起来实现通讯录。

首先我们需要存储通讯录中联系人信息,这里创建一个结构体,

存储联系人姓名、性别、年龄、电话、住址等信息

#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 50
 
typedef struct personinfo //联系人信息
{
  char name[NAME_MAX];//姓名
  char gender[GENDER_MAX];//性别
  int age; //年龄
  char tel[TEL_MAX];//电话
  char addr[ADDR_MAX];//住址
}person;

这里使用#define定义常量,以后方便修改

现在创建好了应该结构体(联系人信息)那又如何有顺序表来实现呢?

       在数据结构--顺序表中,实现顺序表时,存储的是整形数据,那现在需要将用户信息存储起来,我们就让顺序表存储的数据是我们结构体(联系人信息)。

这里只需将数据类型中 int 改为 结构体类型即可;

typedef struct personinfo Type;//person

因为在结构体定义时就重命名为了person,这里可以使用person替换struct personinfo

       当然,为了方便操作,我们也会将(动态)顺序表(SeqList)重命名成通讯录(Contact)

不过这里需要注意的时:我们是基于顺序表来实现通讯录,我们需要通讯录的头文件,也需要用到顺序表的相关代码,两个头文件在使用时都会用到另一个头文件的东西,而头文件又不能相互包含,(这里在通讯录头文件Contact.h中只需声明顺序表结构体就可以了(不可以直接使用重命名后的结构体名)),顺序表实现的头文件直接包含Contact.h即可(因为会涉及到数据类型重命名和插入、查找数据等)。

       到这里,对于通讯录的实现准备工作已经做的差不多了,接下来就来就实现通讯录:

通讯录功能预览:

我们想要通讯录实现以下几种功能:

  1. 能够保存联系人信息姓名、性别、年龄、电话、地址等
  2. 增加联系人信息
  3. 删除指定联系人
  4. 查找指定联系人
  5. 修改指定联系人
  6. 显示联系人信息

先来看以下这些功能实现代码的头文件

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 50
 
typedef struct personinfo //联系人信息
{
  char name[NAME_MAX];//姓名
  char gender[GENDER_MAX];//性别
  int age; //年龄
  char tel[TEL_MAX];//电话
  char addr[ADDR_MAX];//住址
}person;
 
typedef struct SeqList Con;//重命名顺序表
 
//通讯录初始化
void ConInit(Con* con);
//通讯录销毁
void ConDesTroy(Con* con);
//查看通讯录
void ConShow(Con* con);
//添加联系人
void ConAdd(Con* con);
//修改联系人
void Conrev(Con* con);
//删除联系人
void ConDel(Con* con);
//查找联系人
void ConFind(Con* con);

接下来就一一实现这些功能函数

通讯录初始化

通讯录销毁

       通讯录的初始化和销毁其实就是顺序表的初始化和销毁,这里直接使用顺序表的初始化和销毁函数即可。

//通讯录初始化
void ConInit(Con* con)
{
  SLInit(con);
}
//通讯录销毁
void ConDesTroy(Con* con)
{
  SLDesTroy(con);
}

查看通讯录

       这里查看联系人信息也就是将联系人信息输出(打印)到电脑屏幕上,先看以下预期效果图

这样在下面依次输出即可,这里就需要一些格式

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

       我这里使用%-10s(%-10d)来限制输出对齐的格式%-10d是靠左对齐。(这里也可以给更多%-20d等)

添加联系人

       接下来就是添加联系人信息,这个这里就先从键盘上读取数据存储进来

}
//添加联系人
void ConAdd(Con* con)
{
  person psi;
  printf("请输入添加的联系人姓名:\n");
  scanf("%s", psi.name);
  printf("请输入添加的联系人性别:\n");
  scanf("%s", psi.gender);
  printf("请输入添加的联系人年龄:\n");
  scanf("%d", &psi.age);
  printf("请输入添加的联系人电话:\n");
  scanf("%s", psi.tel);
  printf("请输入添加的联系人住址:\n");
  scanf("%s", psi.addr);
 
  SLAddEnd(con, psi);
  printf("添加成功\n");
}

这里也可以像下面这种方式直接输入到顺序表数据中。

//添加联系人
void ConAdd(Con* con)
{
  if (con->size >= con->num) {
    Conzengrong(con);
  }
  printf("请输入添加联系人的姓名:\n");
  scanf("%s", con->arr[con->size].name);
  printf("请输入添加联系人的性别:\n");
  scanf("%s", con->arr[con->size].gender);
  printf("请输入添加联系人的年龄:\n");
  scanf("%d", &con->arr[con->size].age);
  printf("请输入添加联系人的电话:\n");
  scanf("%s", con->arr[con->size].tel);
  printf("请输入添加联系人的地址:\n");
  scanf("%s", con->arr[con->size].addr);
  printf("添加成功\n");
  con->size++;
}

       但我们这是基于顺序表来实现的通讯录,这里就使用第一种方式。

这里就不一一测试了;

删除联系人

       删除联系人,我们首先要找到这个联系人信息,就要先写一个函数先找到联系人信息(在查找联系人,修改联系人都会用到):

//按照名字查找
int Find_name(Con* con, char* name)
{
  for (int i = 0; i < con->size; i++) 
  {
    if (strcmp(con->arr[i].name, name) == 0)
    {
      return i;
    }
  }
  return -1;
}

这里如果找到联系人数据,就返回其下标,如果找不到就返回-1;

       接下来就通过查找函数的返回值来删除数据:这里会用到顺序表中删除指定位置的函数

//删除联系人
void ConDel(Con* con)
{
  char name[NAME_MAX];
  printf("请输入删除的联系人姓名:\n");
  scanf("%s", name);
  int find = Find_name(con, name);
  if (find < 0)
  {
    printf("需要删除的联系人不存在\n");
    return;
  }
  SLDeleve(con, find);
  printf("删除成功\n");
}

当然这里也可以不使用顺序表的函数,直接进行查找到下标如何进行删除,这里就不添加这种方式的代码了,(其实就是将顺序表的代码写到这个函数中)

查找联系人

       与删除函数相同的是,查找也需要先找到指定联系人的下标,再通过下标将数据输出出来

代码如下:

//查找联系人
void ConFind(Con* con)
{
  char name[NAME_MAX];
  printf("请输入查找的联系人姓名:\n");
  scanf("%s", name);
  int find = Find_name(con, name);
  if (find < 0)
  {
    printf("查找的联系人不存在\n");
    return;
  }
  printf("查找成功\n");
  printf("%-10s%-10s%-10s%-10s%-10s\n", "姓名", "性别", "年龄", "电话", "住址");
  printf("%-10s%-10s%-10d%-10s%-10s\n",
    con->arr[find].name,
    con->arr[find].gender,
    con->arr[find].age,
    con->arr[find].tel,
    con->arr[find].addr);
}

修改联系人

       修改与删除和查找都需要先找到指定联系人数据的下标,再通过下标对联系人信息进行操作

//修改联系人
void Conrev(Con* con)
{
  char name[NAME_MAX];
  printf("请输入需要修改的联系人姓名:\n");
  scanf("%s", name);
  int find = Find_name(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");
}

到这里通讯录的基本代码已经完了,先来写测试代码来测试以下

测试代码test.c:

#include"SeqList.h"
 
void Contact()
{
  int n = 0;
  Con con;
  ConInit(&con);
  do
  {
    printf("******************************通讯录******************************\n");
    printf("********************1.添加联系人  2.删除联系人********************\n");
    printf("********************3.修改联系人  4.查找联系人********************\n");
    printf("********************5.查看通讯录  0.退出通讯录********************\n");
    printf("******************************************************************\n");
    printf("------------------------------请选择------------------------------\n");
    scanf("%d", &n);
    switch (n)
    {
    case 1:
      ConAdd(&con);
      break;
    case 2:
      ConDel(&con);
      break;
    case 3:
      Conrev(&con);
      break;
    case 4:
      ConFind(&con);
      break;
    case 5:
      ConShow(&con);
      break;
    case 0:
      break;
    default:
      printf("输入错误,请重新输入\n");
 
    }
  } while (n);
  ConDesTroy(&con);
}
int main()
{
  Contact();
  return 0;
}

结果预览


image.png

顺序表实现通讯录

       当然这样写,我们的通讯录信息再程序结束后就丢失了,要想长久保存,我们就要将通讯录信息写到文件中,文件操作相关知识在之前有所了解

这里就不进行文件相关操作了,可以自行尝试

代码总览

       有很多是顺序表实现的相关代码,这里可以直接拿来用,这里只展示通讯录的相关代码,顺序表的代码可以查看上篇文章 顺序表

Contact.c

#include"SeqList.h"
#include"Contact.h"
 
//通讯录初始化
void ConInit(Con* con)
{
  SLInit(con);
}
//通讯录销毁
void ConDesTroy(Con* con)
{
  SLDesTroy(con);
}
//查看通讯录
void ConShow(Con* con)
{
  printf("%-10s%-10s%-10s%-10s%-10s\n", "姓名", "性别", "年龄", "电话", "住址");
  for (int i = 0; i < con->size; i++)
  {
    printf("%-10s%-10s%-10d%-10s%-10s\n", 
      con->arr[i].name,
      con->arr[i].gender,
      con->arr[i].age,
      con->arr[i].tel,
      con->arr[i].addr);
  }
}
//添加联系人
void ConAdd(Con* con)
{
  person psi;
  printf("请输入添加的联系人姓名:\n");
  scanf("%s", psi.name);
  printf("请输入添加的联系人性别:\n");
  scanf("%s", psi.gender);
  printf("请输入添加的联系人年龄:\n");
  scanf("%d", &psi.age);
  printf("请输入添加的联系人电话:\n");
  scanf("%s", psi.tel);
  printf("请输入添加的联系人住址:\n");
  scanf("%s", psi.addr);
 
  SLAddEnd(con, psi);
  printf("添加成功\n");
}
//按照名字查找
int Find_name(Con* con, char* name)
{
  for (int i = 0; i < con->size; i++) 
  {
    if (strcmp(con->arr[i].name, name) == 0)
    {
      return i;
    }
  }
  return -1;
}
 
//删除联系人
void ConDel(Con* con)
{
  char name[NAME_MAX];
  printf("请输入删除的联系人姓名:\n");
  scanf("%s", name);
  int find = Find_name(con, name);
  if (find < 0)
  {
    printf("需要删除的联系人不存在\n");
    return;
  }
  SLDeleve(con, find);
  printf("删除成功\n");
}
//修改联系人
void Conrev(Con* con)
{
  char name[NAME_MAX];
  printf("请输入需要修改的联系人姓名:\n");
  scanf("%s", name);
  int find = Find_name(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 ConFind(Con* con)
{
  char name[NAME_MAX];
  printf("请输入查找的联系人姓名:\n");
  scanf("%s", name);
  int find = Find_name(con, name);
  if (find < 0)
  {
    printf("查找的联系人不存在\n");
    return;
  }
  printf("查找成功\n");
  printf("%-10s%-10s%-10s%-10s%-10s\n", "姓名", "性别", "年龄", "电话", "住址");
  printf("%-10s%-10s%-10d%-10s%-10s\n",
    con->arr[find].name,
    con->arr[find].gender,
    con->arr[find].age,
    con->arr[find].tel,
    con->arr[find].addr);
}

Coontact.h

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 50
 
typedef struct personinfo //联系人信息
{
  char name[NAME_MAX];//姓名
  char gender[GENDER_MAX];//性别
  int age; //年龄
  char tel[TEL_MAX];//电话
  char addr[ADDR_MAX];//住址
}person;
 
typedef struct SeqList Con;//重命名顺序表
 
//通讯录初始化
void ConInit(Con* con);
//通讯录销毁
void ConDesTroy(Con* con);
//查看通讯录
void ConShow(Con* con);
//添加联系人
void ConAdd(Con* con);
//修改联系人
void Conrev(Con* con);
//删除联系人
void ConDel(Con* con);
//查找联系人
void ConFind(Con* con);

感谢各位大佬支持并指出问题,

如果本篇内容对你有帮助,可以一键三连支持以下,感谢支持!!!

相关文章
|
24天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2577 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
164 2
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1576 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
22天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
978 14
|
4天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
221 2
|
17天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
735 9