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

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

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

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通讯录界面

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

零基础使用FlexLua打造LoRa无线气体流量计,硬件轻松快速开发。

在工业领域&#xff0c;对气体流量进行准确监测和管理是保障生产安全和提高效率的重要环节。而LoRa&#xff08;长距离低功耗无线技术&#xff09;作为一种适用于远距离、低功耗的通信技术&#xff0c;为无线传感器网络的建设提供了可靠的解决方案。结合气体流量传感技术&#…

【JS】querySelectorAll和getElementsByClassName

现有一段代码&#xff0c;li的类名均为item&#xff0c;有一按钮可动态添加类名为item的li。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge…

vue表格操作列,按钮太多显示... 点击后悬浮显示全部按钮

效果: 分析原理: 一共就三步,仔细看看很简单,位置要加对,代码结构下边有demo 代码结构demo: <el-table-columnlabel"操作"align"center"fixed"right"show-overflow-tooltip><template slot-scope"scope"><el-buttonsi…

润乾报表平台 InputServlet 任意文件读取漏洞复现

0x01 产品简介 润乾报表是一个纯JAVA的企业级报表工具&#xff0c;支持对J2EE系统的嵌入式部署&#xff0c;无缝集成。服务器端支持各种常见的操作系统&#xff0c;支持各种常见的关系数据库和各类J2 EE的应用服务器&#xff0c;客户端采用标准纯html方式展现&#xff0c;支持…

1000BASE-SX VS 1000BASE-LX SFP光模块

SFP光模块是一种小型可插拔光模块&#xff0c;用于支持1G速率的光纤通信&#xff0c;有多种不同类型。市场上使用较广泛是1000BASE-SX和1000BASE-LX SFP光模块。在本文中&#xff0c;飞速&#xff08;FS&#xff09;将对这两种LC SFP光模块进行简要介绍。 什么是1000BASE-SX S…

3dmax制作小熊猫的基本流程

1.透视图插入面片&#xff0c;改高度宽度&#xff0c;把参考图放进面片里。 2.角度捕捉切换&#xff0c;角度改为90 3.shift旋转&#xff0c;旋转面片&#xff0c;复制一个出来 4.在前视图&#xff0c;把参考图片中的正式图小熊猫的一半的位置&#xff08;可以是眼睛&#x…

Android Studio引入framework.jar包

一. 前言 Android Studio 引入framework.jar 步骤&#xff0c;记录笔记 Android源码编译产生的framework.jar 在不同的版本上生成路径是不同的 Android N/O: 7 和 8 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar Android P/Q: 9 和 10 out/s…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十二 简单图片添加水印效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十二 简单图片添加水印效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十二 简单图片添加水印效果 一、简单介绍 二、简单图片添加水印效果实现原理 三、简单图片添加水印效果案例…

c++ - 类的默认成员函数

文章目录 前言一、构造函数二、析构函数三、拷贝构造函数四、重载赋值操作符五、取地址及const取地址操作符重载 前言 默认成员函数是编译器自动生成的&#xff0c;也可以自己重写&#xff0c;自己重写之后编译器就不再生成&#xff0c;下面是深入了解这些成员函数。 一、构造…

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

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

面试官:MySQL的自增 ID 用完了,怎么办?

如果你用过或了解过MySQL&#xff0c;那你一定知道自增主键了。每个自增id都是定义了初始值&#xff0c;然后按照指定步长增长&#xff08;默认步长是1&#xff09;。虽然&#xff0c;自然数是没有上限的&#xff0c;但是我们在设计表结构的时候&#xff0c;通常都会指定字段长…

Flink入门学习 | 大数据技术

⭐简单说两句⭐ ✨ 正在努力的小新~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &…

优化汽车制造中的库存管理

在拥有足够的库存以满足客户需求和最大限度地减少过剩库存之间取得适当的平衡&#xff0c;对于高效运营和正向现金流运营至关重要。我们将探讨如何利用数据见解和预测技术来支持汽车制造商进行精益运营&#xff0c;避免库存过多或不足的缺陷。 销售模式告诉我们什么&#xff1…

手拉手安装启动Kafka2.13

启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。 这种动作&#xff08;网页浏览&#xff0c;搜索和其他用户的行动&#xff09;是在现代网络上的许多社会功能的一个关键因素。 Kafka启动…

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

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

c++中常用库函数

大小写转换 islower/isupper函数 char ch1 A; char ch2 b;//使用islower函数判断字符是否为小写字母 if(islower(ch1)){cout << ch1 << "is a lowercase letter." << end1; } else{cout << ch1 << "is not a lowercase lette…

Java单例集合

Collection接口介绍 Collection 表示一组对象&#xff0c;它是集中、收集的意思。Collection接口的两个子接口是List、Set接口。 Collection接口中定义的方法 方法说明boolean add(Object element)增加元素到容器中boolean remove(Object element)从容器中移除元素 boolean c…

【源码】2024全开源多语言多商户跨境商城源码|多语言跨境外贸电商系统App

ikTok SHOP跨境电商系统V8版是一套B2CB2B跨境电商商城系统源码&#xff0c;多商户多语言&#xff0c;全新百变DIY模板&#xff1b;该系统支持B-C自营、B-B-C第三方卖家系统、B2B批发电商模式&#xff1b;该源码是使用Laravel框架PHP开发的&#xff0c;前后端全开源可二开。 版…

行业模板|DataEase批发零售大屏模板推荐

DataEase开源数据可视化分析平台于2022年6月发布模板市场&#xff08;https://templates-de.fit2cloud.com&#xff09;&#xff0c;并于2024年1月新增适用于DataEase v2版本的模板分类。模板市场旨在为DataEase用户提供专业、美观、拿来即用的大屏模板&#xff0c;方便用户根据…

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

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