【探索数据结构与算法】——基于顺序表实现通讯录

目录

一. 通讯录功能要求

二.思路分析 

三.实现方法 

3.1顺序表的实现

SeqList.h

SeqList.c 

3.2通讯录的实现 

Contact.h

Contact.c 

四.通讯录的菜单设置 

  text.c


 

 

💓 博客主页:C-SDN花园GGbond

⏩ 文章专栏:探索数据结构与算法

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

一. 通讯录功能要求

1)至少少能够存储100个⼈的通讯信息
2)能够保存用户信息:名字、性别、年龄、电话、地址等
3)增加联系人信息
4)删除指定联系人
5)查找制定联系人
6)修改指定联系人
7)显示联系⼈信息

二.思路分析 

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

 

三.实现方法 

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

3.1顺序表的实现
SeqList.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);
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;
}
3.2通讯录的实现 
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);
Contact.c 

通讯录初始化和销毁 

//通讯录的初始化
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);//将联系人信息结构体存入顺序表中
}

删除联系人 

删除联系人之前,我们先写一个通过名字在通讯录查找是否有此人,如果有就返回他是第几位,如果没有就返回一个-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");
 
}

修改联系人信息  

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

//通讯录的修改
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
        );
    }
 
}

 contact.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
        );
    }
 
}

四.通讯录的菜单设置 

  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;
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值