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

news2024/11/16 19:39:11

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

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

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.coloradmin.cn/o/1595892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

锂电池寿命预测 | Matlab基于BiLSTM双向长短期记忆神经网络的锂电池寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 锂电池寿命预测 | Matlab基于BiLSTM双向长短期记忆神经网络的锂电池寿命预测 程序设计 完整程序和数据获取方式&#xff1a;私信博主回复Matlab基于BiLSTM双向长短期记忆神经网络的锂电池寿命预测。 参考资料 [1] h…

如何为不同内容主题选择最适合的移动滑轨屏方案?

在数字化信息时代背景下&#xff0c;多媒体互动装置作为当前内容展示的常用手段&#xff0c;颇受大众的喜爱&#xff0c;比如应用在展厅、商业推广、活动会议等领域的滑轨屏&#xff0c;便是其中一种新颖的互动展示装置&#xff0c;并且它还能根据不同的内容主题&#xff0c;来…

企业级OVSSL证书的五大优势

在数字化时代&#xff0c;企业级OVSSL&#xff08;Organization Validation Secure Sockets Layer&#xff09;证书已成为保护网站安全、提升用户信任度的重要工具。越来越多企业在自身网络安全方面更倾向于OVSSL证书&#xff0c;以下就带你了解企业级OVSSL证书的五大优势&…

硬件测试学习——电源纹波测试(2024.04.15)

参考链接1: 测试开关电源的纹波 在此感谢各位前辈大佬的总结&#xff0c;写这个只是为了记录学习大佬资料的过程&#xff0c;内容基本都是搬运的大佬博客&#xff0c;觉着有用自己搞过来自己记一下&#xff0c;如果有大佬觉着我搬过来不好&#xff0c;联系我删。 硬件测试学习—…

Flask框架——安装与第一个应用

安装 Flask是一个轻量级的Python Web框架。它是一个微型框架&#xff0c;具有灵活性和可扩展性。Flask使用Python语言编写&#xff0c;它是一个开源框架&#xff0c;使得它可以自由地使用和修改。Flask框架可以用于构建任何类型的Web应用程序&#xff0c;包括单页面应用程序、…

【vue】用vite创建vue项目

前置要求 要有Node.js 1. 用vite创建vue项目 在cmd中&#xff0c;进入一个文件夹 在文件资源管理器上面的文件目录中&#xff0c;输入cmd&#xff0c;回车在cmd中通过cd命令进入对应文件夹 创建项目 npm create vitelatest # 创建项目创建项目过程中的一些选项 Ok to pro…

【Qt编译】ARM环境 Qt5.14.2-QtWebEngine库编译 (完整版)

ARM 编译Qt5.14.2源码 1.下载源码 下载Qt5.14.2源代码&#xff08;可根据自己的需求下载不同版本&#xff09; 下载网站&#xff1a;https://download.qt.io/new_archive/qt/5.14/5.14.2/single/ 2.相关依赖(如果需要的话) 先参考官方文档的需求进行安装&#xff1a; 官方…

突破界限 千视将在 NAB 2024 展会上展示领先的 AV over IP 技术

突破界限&#xff01;千视将在 NAB 2024 展会上展示领先的 AV over IP技术 作为AV over IP领域的先驱者&#xff0c;Kiloview将于2024年4月14日至17日在NAB展会&#xff08;展台号&#xff1a;SU6029&#xff09;隆重登场&#xff0c;展示我们领先业界的AV over IP产品、解决方…

构建跨设备3D应用:HOOPS的跨平台开发能力

在当今数字化和可视化需求不断提升的时代&#xff0c;三维技术的应用越来越广泛&#xff0c;尤其在制造、建筑、工程及媒体行业。HOOPS&#xff0c;由Tech Soft 3D开发&#xff0c;是一套全面的软件开发工具包&#xff0c;用于构建高性能的三维应用程序。该工具包涵盖了从三维渲…

企业中台技术架构解决方案(中台建设指南Word原件2024)

通过中台建设实现企业能力复用&#xff0c;包括能力整合、业务创新、业务和数据闭环、组织模式演进等。 数字能力整合 企业的数字能力一般包括数字化营销、数字化产品、数字化供应链、数字化生产、数字化运营等。企业的数字化能力的充分利用&#xff0c;从而达到可持续发展。数…

UE5 C++ TimeHandle 定时器练习

一.加相关头文件 #include "TimerManager.h" 二.声明定时器 变量 //声明定时器 FTimerHandle Time; 三.在BeginPaly里面 设参数 GetWorld()->GetTimerManager().SetTimer(Time,this,&AMyCharacter::Printf,1.0,true); //时间句柄 Time 每一秒 调用Pri…

力扣面试150 反转字符串中的单词 API 双指针

Problem: 151. 反转字符串中的单词 &#x1f468;‍&#x1f3eb; 参考思路 &#x1f496; API 大法 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) class Solution {public String reverseWords(String s){s s.trim();// 去除首尾空格List<String&…

笔试的解题思路很多,

昨天发的笔试题目&#xff0c;留言的人还挺多&#xff0c;这道笔试题目是字节的嵌入式笔试题目&#xff0c;从面试的朋友描述说&#xff0c;对方的面试过程很专业。 现场写代码&#xff0c; 金三银四一直是铁律&#xff0c;去年我一个朋友离职后&#xff0c;也是最近这几天拿到…

瑞芯微RK3568/RK3588+鸿蒙,矿鸿工控屏、矿鸿工控板、矿鸿网关,推动矿业数智化变革

4月10日至12日&#xff0c;以“绿色智能创新&#xff0c;携手共赢未来”为主题的第二届中国国际矿业装备与技术展览会在西安举行。信迈科技携矿鸿解决方案及产品亮相&#xff0c;赋能矿山行业数智化升级和国产化改造进程全面提速。 作为华为矿山军团矿鸿生态使能合作伙伴&#…

网络靶场实战-反射DLL注入

在之前的文章中&#xff0c;通过模拟 Windows 映像加载程序的功能&#xff0c;完全从内存中加载 DLL 模块&#xff0c;而无需将 DLL 存储到磁盘上&#xff0c;但这只能从本地进程中加载进内存中&#xff0c;如果想要在目标进程中通过内存加载 DLL 模块&#xff0c;可以通过一些…

每个人都可以做一个赚钱的社群

如何创建并运营一个赚钱的社群 一、引言 大家好&#xff0c;今天&#xff0c;我想和大家分享一下如何创建并运营一个赚钱的社群。我的分享目的是希望能够持续输出有价值的内容。 二、心态建设 1. 重要性&#xff1a;创业心态与平常心 在开始社群运营之前&#xff0c;我们需…

【论文精读】MedIAnomaly:医学图像异常检测的比较研究

文章目录 一、前言&#xff08;一&#xff09;异常检测&#xff08;二&#xff09;文章贡献 二、文献综述&#xff08;一&#xff09;基于重建的异常检测1、图像重建2、特征重建 &#xff08;二&#xff09;基于自监督学习的异常检测1、一阶段方法2、两阶段方法3、其他与 SSL 相…

每日OJ题_BFS解决最短路①_力扣1926. 迷宫中离入口最近的出口

目录 力扣1926. 迷宫中离入口最近的出口 解析代码 力扣1926. 迷宫中离入口最近的出口 1926. 迷宫中离入口最近的出口 难度 中等 给你一个 m x n 的迷宫矩阵 maze &#xff08;下标从 0 开始&#xff09;&#xff0c;矩阵中有空格子&#xff08;用 . 表示&#xff09;和墙&…

2024最新数据分级分类的架构方法流程指南(附下载)

以下是资料目录&#xff0c;如需下载请前往知识星球下载&#xff1a;https://t.zsxq.com/18KTZnJMX ​ ​ ​​​​​​​​​​​​​ 以下是资料目录&#xff0c;如需下载请前往知识星球下载&#xff1a;https://t.zsxq.com/18KTZnJMX ​

Linux/Iclean

Iclean Enumeration nmap 先使用默认规则扫描常用的端口&#xff0c;发现对外开放了 22 和 80 端口&#xff0c;然后扫描这两个端口的详细信息&#xff0c;结果如下&#xff0c;很常规的结果&#xff0c;没发现什么有趣的东西 ┌──(kali㉿kali)-[~/vegetable/HTB/Iclean] …