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

在上一节我们基本了解了顺序表的基本知识,接下来我们就用顺序表来实现一下通讯录。

一、基于动态顺序表实现通讯录

1.1 功能介绍

1. 能够保存用户信息:姓名,性别,年龄,电话,地址等

2. 添加联系人信息

3. 删除指定联系人

4. 查找指定联系人

5. 修改联系人信息

6.显示联系人信息

1.2 思路分析

我们之前创建的顺序表可以实现连续存储数据(类型可以为整型、字符等),但无论是哪种类型,存储信息都比较单一,但是通讯录存储信息比较多,有联系人姓名、性别、年龄等,所以我们把一个联系人的所有信息作为一个整体存储到顺序表,原来我们写的是整型作为数据存储每个数组元素空间,现在转化通讯录,把一个人的所有信息打包变为结构体然后存储到数组元素元素的空间,然后基于顺序表实现通讯录功能。

 1.3 通讯录的实现

因为我们是在动态顺序表的前提下来实现通讯录的,所以我们先把顺序表中要用到的内容写好

1.3.1顺序表

1.3.1.1SeqList.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "Contact.h"//动态顺序表
typedef  peoInfo SLDatatype;//peoInfo就是下面要讲的通讯录联系人的信息结构体
typedef struct SeqList
{SLDatatype *a;int size;int capacity;
}SL;void SLInit(SL* psl);void SLDestroy(SL* psl);void SLPrint(SL* psl);//STL命名风格
void SLPushBack(SL* psl,SLDatatype x);
void SLPushFront(SL* psl,SLDatatype x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);void SLInsert(SL* psl,int pos,SLDatatype x);
void SLErase(SL* psl,int pos);int SLFind(SL* psl,SLDatatype x);
void SLModify(SL* psl,int pos,SLDatatype x);
1.3.1.2 SeqList.c
#include "SeqList.h"
void SLInit(SL* psl)
{psl->a=(SLDatatype*) malloc(sizeof(SLDatatype)*4);if(psl->a==NULL){perror("malloc fail");return;}psl->capacity=4;psl->size=0;
}void SLDestroy(SL* psl)
{free(psl->a);psl->a=NULL;psl->size=0;psl->capacity=0;
}void SLCheckCapacity(SL* psl)
{if(psl->size==psl->capacity){SLDatatype* tmp=(SLDatatype*)realloc(psl->a,sizeof(SLDatatype)*psl->capacity*2);if(tmp==NULL){perror("realloc fail");return;}psl->a=tmp;psl->capacity*=2;}
}void SLPushBack(SL* psl,SLDatatype x)
{SLCheckCapacity(psl);psl->a[psl->size++]=x;
}
void SLPushFront(SL* psl,SLDatatype x)
{SLCheckCapacity(psl);int end=psl->size-1;while(end>=0){psl->a[end+1]=psl->a[end];-end;}psl->a[0]=x;psl->size++;
}
void SLPopBack(SL* psl)
{if(psl->size==0)return;psl->size--;
}
void SLPopFront(SL* psl)
{assert(psl->size>0);int start=0;while (start<psl->size-1){psl->a[start]=psl->a[start+1];start++;}psl->size--;}void SLInsert(SL* psl,int pos,SLDatatype x)
{assert(psl);assert(0<=pos && pos<=psl->size);SLCheckCapacity(psl);int end=psl->size-1;while(end >= pos){psl->a[end+1]=psl->a[end];--end;}psl->a[pos]=x;psl->size++;
}void SLErase(SL* psl,int pos)
{assert(psl);assert(0<=pos && pos<psl->size);int start=pos+1;while(start<psl->size){psl->a[start-1]=psl->a[start];++start;}psl->size--;
}void SLModify(SL* psl,int pos,SLDatatype x)
{assert(psl);assert(0<=pos && pos<psl->size);psl->a[pos]=x;
}

1.3.2 通讯录的实现

1.3.2.1通讯录头文件,Contact.h

首先定义联系人数据

#define NAME_MAX 20
#define GENDER_MAX 10
#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];
}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);
1.3.2.2通讯录初始化和销毁

通讯录的初始化和销毁实际上就是顺序表的初始化和销毁

//通讯录的初始化
void ContactInit(Contact* con)
{SLInit(con);
}//通讯录的销毁
void ContactDesTroy(Contact* con)
{SLDestroy(con);
}
 1.3.2.3通讯录联系人的添加
//通讯录添加数据
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);//将联系人信息结构体存入顺序表中
}
  1.3.2.4删除联系人

删除联系人之前,我们先写一个通过名字在通讯录查找是否有此人,如果有就返回他是第几位,如果没有就返回一个-1.(也可以是通过其他方法比如年龄,性别,电话等等,根据自己的喜好)

int FindByName(Contact *con,char name[])
{for(int i=0;i<con->size;i++){if(strcmp(con->a[i].name,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");return;}SLErase(con,find);printf("删除成功!\n");}
1.3.2.5修改联系人信息 

依然跟删除联系人一样,需要先判断是否存在此人,再进行修改

//通讯录的修改
void ContactModify(Contact* con)
{printf("请输入您要修改的联系人姓名:\n");char name[NAME_MAX];scanf("%s",name);int find= FindByName(con,name);if(find<0){printf("您要修改的联系人不存在!\n");return;}printf("请输入新的姓名:");scanf("%s",con->a[find].name);printf("请输入新的性别:");scanf("%s",con->a[find].gender);printf("请输入新的年龄:");scanf("%d",con->a[find].age);printf("请输入新的电话:");scanf("%s",con->a[find].tel);printf("请输入新的住址:");scanf("%s",con->a[find].addr);printf("修改成功!\n");
}
1.3.2.6通讯录查找
//通讯录查找
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("%3s    %3s    %3d    %3s    %3s\n",con->a[find].name,con->a[find].gender,con->a[find].age,con->a[find].tel,con->a[find].addr);
}
 1.3.2.7通讯录展示
//展示通讯录数据
void ContactShow(Contact* con)
{printf("%s  %s  %s  %s  %s \n","姓名","性别","年龄","电话","地址");for(int i=0;i<con->size;i++){printf("%3s    %3s    %3d    %3s    %3s\n",con->a[i].name,con->a[i].gender,con->a[i].age,con->a[i].tel,con->a[i].addr);}}

1.3.3Contact.c完整代码

#include "Contact.h"
#include "SeqList.h"
#include <string.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("%s",info.gender);printf("请输入要添加的联系人年龄:\n");scanf("%d",info.&age);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(strcmp(con->a[i].name,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");return;}SLErase(con,find);printf("删除成功!\n");}
//通讯录的修改
void ContactModify(Contact* con)
{printf("请输入您要修改的联系人姓名:\n");char name[NAME_MAX];scanf("%s",name);int find= FindByName(con,name);if(find<0){printf("您要修改的联系人不存在!\n");return;}printf("请输入新的姓名:");scanf("%s",con->a[find].name);printf("请输入新的性别:");scanf("%s",con->a[find].gender);printf("请输入新的年龄:");scanf("%d",con->a[find].age);printf("请输入新的电话:");scanf("%s",con->a[find].tel);printf("请输入新的住址:");scanf("%s",con->a[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("%3s    %3s    %3d    %3s    %3s\n",con->a[find].name,con->a[find].gender,con->a[find].age,con->a[find].tel,con->a[find].addr);
}
//展示通讯录数据
void ContactShow(Contact* con)
{printf("%s  %s  %s  %s  %s \n","姓名","性别","年龄","电话","地址");for(int i=0;i<con->size;i++){printf("%3s    %3s    %3d    %3s    %3s\n",con->a[i].name,con->a[i].gender,con->a[i].age,con->a[i].tel,con->a[i].addr);}}

 1.4通讯录的菜单设置

1.4.1 text.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 select=-1;Contact con;ContactInit(&con);do {menu();printf("请选择您的操作:\n");scanf("%d",&select);switch(select){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(select!=0);ContactDesTroy(&con);return 0;
}

1.4.2通讯录界面

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/309689.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创新营销利器:淘宝扭蛋机小程序开发全解析

在数字化浪潮的推动下&#xff0c;淘宝扭蛋机小程序的开发成为了一种全新的购物体验。它巧妙地将传统扭蛋机的乐趣与移动技术的便捷相结合&#xff0c;为用户带来了前所未有的惊喜与互动。 淘宝扭蛋机小程序的开发&#xff0c;不仅是一次技术的革新&#xff0c;更是一次购物方…

使用Python写接口压测2简单递归

递归其实在压测场景用的不多&#xff0c;但是批量造数据或批量导出&#xff0c;用的比较多&#xff0c;常见的压测登陆&#xff0c;首先你要有登陆账号的csv&#xff0c;这个时候自己可以实现一个批量获取账号的py就很惬意。 编辑器 VScode VSCode 全称 Visual Studio Code&…

基于数据库现有表导出为设计文档

1.查询 SELECTCOLUMN_NAME 字段名,COLUMN_COMMENT 字段描述,COLUMN_TYPE 字段类型,false as 是否为主键 FROMINFORMATION_SCHEMA.COLUMNS wheretable_NAME region -- 表名2.查询结果 3.导出为excel

Python学习笔记20 - 模块

什么叫模块 自定义模块 Python中的包 Python中常用的内置模块 第三方模块的安装与使用

如何提升软件发布管理过程?

大家都说&#xff0c;实践出真知。在成为一位首席技术官&#xff08;CTO&#xff09;之前&#xff0c;我也是做着跑腿活&#xff0c;我的职业生涯是从软件工程师开始的&#xff0c;后来开始管理开发和 QA 团队&#xff0c;并负责发布管理管道。我做过上百个项目&#xff0c;其中…

【第十五届】蓝桥杯省赛C++b组

今年的蓝桥杯省赛已经结束了&#xff0c;与以往不同&#xff0c;今年又回到了8道题&#xff0c;而22&#xff0c;23年出现了10道题 大家觉得难度怎么样&#xff0c;欢迎进来讨论&#xff0c;博主今年没参加哈&#xff0c;大家聊聊&#xff0c;我听听大家的意见和看法哈 试题A:…

九州金榜|孩子青春期应该如何家庭教育?

青春期&#xff0c;是一个人从儿童走向成年的重要过渡阶段&#xff0c;也是心理、生理发生巨大变化的时期。面对这一特殊时期的孩子&#xff0c;家庭教育显得尤为重要。那么&#xff0c;作为家长&#xff0c;我们该如何进行青春期孩子的家庭教育呢&#xff1f;九州金榜家庭教育…

Langchain入门到实战-第一弹

Langchain入门到实战 Langchain简介官网地址Langchain概述Langchain作用Langchain开源包使用案例更新计划 Langchain简介 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://python.langchain.com/Langchain概述 LangC…

29、链表-删除链表的倒数第N个结点

思路: 首先找到倒数第N个结点 第一种方式 先统计链表的节点数&#xff0c;然后再次遍历len-N即可得到倒数第N个结点&#xff0c;然后将前一个节点的next指针指向next的下一个节点使用快慢指针&#xff0c;快指针先跑N个结点然后慢指针开始跑&#xff0c;等快指针到达尾节点后…

Kafka 简单介绍

目录 一 消息队列&#xff08;MQ&#xff09; 1&#xff0c;为什么需要消息队列&#xff08;MQ 2&#xff0c;常见的 MQ 中间件 3&#xff0c;MQ 传统应用场景之异步处理 4&#xff0c;使用消息队列的好处 5&#xff0c;消息队列的两种模式 5.1点对点模式&#xf…

如何在Odoo 17库存中通过批次号和序列号追踪产品

在Odoo 17库存管理中&#xff0c;通过批次号和序列号追踪产品是一种确保产品从生产到销售全程可追溯的重要方式。在产品打包时或生产过程中会分配这些编号。批次号是指应用于具有相似属性的一组产品的一系列数字或代码&#xff0c;而序列号则是分配给特定单一物品的独特编号。O…

matlab使用教程(44)—绘制带标记的二维曲线图

在线图中添加标记是区分多个线条或突出显示特定数据点的有用方法。使用下面的一种方式添加标记&#xff1a; • 在线条设定输入参数&#xff08;例如 plot(x,y,-s) &#xff09;中包含标记符号。 • 将 Marker 属性指定为一个名称-值对组&#xff0c;例如 plot(x,y,Marker,s…

【干货】【常用电子元器件介绍】【晶振】--晶体振荡器/陶瓷谐振元器件的识别、检测、选用

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。 一、 石英晶体振荡器 石英晶体振荡器(Quartz Crystal Oscillator)又称石英晶体谐振器,简称石英晶振或者   石英晶体振荡器是一种用于稳定频率和选择频率的电子元件,是高精度和高稳定度的…

信息系统项目管理师0051:管理基础(4信息系统管理—4.1管理方法—4.1.1管理基础)

点击查看专栏目录 文章目录 第四章 信息系统管理4.1管理方法4.1.1管理基础1.层次结构2.系统管理第四章 信息系统管理 在信息技术和数据资源要素的推动下,社会各领域已经并正在加速进入数字化的全新发展时期,基于智能、网络和大数据的新经济业态正在形成,从“数字融合”向“数…

EVenn 的维恩图综合方法(自备)

imeta最新文献&#xff1a;Visualizing set relationships: EVenns comprehensive approach to Venn diagrams 网址EVenn &#xff08;Evenn&#xff09; 提供多种在线可视化方法。 维恩图由于易于解释&#xff0c;可作为可视化集合关系的宝贵工具。广泛应用于代谢组学、基因…

SQLite超详细的编译时选项(十六)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite数据库文件格式&#xff08;十五&#xff09; 下一篇&#xff1a;SQLite 在Android安装与定制方案&#xff08;十七&#xff09; 1. 概述 对于大多数目的&#xff0c;SQLite可以使用默认的 编译选项。但是…

Python学习笔记15 - 字符串

字符串是一个不可变的字符序列&#xff0c;另一个不可变的序列是元组 字符串的驻留机制 字符串的常用操作 字符串的查询 字符串的大小写转换 字符串内容 对齐操作的方法 字符串的劈分操作 字符串的判断 字符串替换 字符串合并 字符串的比较 字符串的切片 格式化字符串 字符串…

地表蒸散发遥感产品信息提取验证与融合应用

蒸散发是陆地水循环重要变量&#xff0c;同时对农业水资源规划与管理、全球环境变化等研究异常关键。本文主要介绍常用的区域及全球蒸散发产品&#xff0c;讲解蒸散发数据产品的下载、处理、可视化、数值统计等方法&#xff1b;蒸散发产品的验证方法、精度评价、不确定性评估&a…

程序员必读:Python 中如何完美处理日志记录?

日志记录在软件开发中扮演着至关重要的角色。它不仅可以帮助开发人员跟踪应用程序的状态和行为&#xff0c;还能提供有价值的诊断信息。Python 提供了内置的 logging 模块&#xff0c;为开发者提供了一个强大且灵活的日志记录工具。 日志的重要性 在软件开发中&#xff0c;对…

HW面试经验分享 | 某服蓝队初级

前言 依稀记得是22年 7、8月份参加的HW&#xff0c;当时是比较炎热的时候&#xff0c;但又夹杂一丝秋意。也是头一次去离家乡比较远的地方&#xff0c;多少有点忐忑……&#xff08;怕被噶腰子、水土不服、吃穿用住没着落等等&#xff09;&#xff0c;但最终也是平安无事且顺利…