数据结构(初阶):顺序表实战通讯录

这篇具有很好参考价值的文章主要介绍了数据结构(初阶):顺序表实战通讯录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言 

数据结构(初阶)第一节:数据结构概论-CSDN博客

数据结构(初阶)第二节:顺序表-CSDN博客

        本文将以C语言和顺序表实现通讯录基础管理,实现功能包括增、删、改、查等,在实现相关功能时需要用到在第二节中顺序表的相关内容,需要友友们掌握顺序表的相关内容以及函数的实现方式。

目录

前言 

要用到的两个文件

正文

文件包含关系

Contact.h

Contast.c

头文件

菜单

初始化

销毁

添加

判断名字是否存在

删除

显示

修改

查找

测试文件test.c


要用到的两个文件

SeqList.h

//.h文件定义
#include "Contact.h"//头文件互相包含会报错
#include <malloc.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>

typedef peoInfo SLDataType;

//定义顺序表
typedef struct SeqList
{
	SLDataType* a;//数组
	int size;//有效元素
	int capacity;//容量
}SL;

//初始化
void SLinit(SL* p1);

//销毁
void SLdestory(SL* p1);

//扩容
void SLcheckCapcity(SL* p1);

//尾插
void SLpushBack(SL* p1, SLDataType x);

//打印顺序表
void SLprint(SL* p1);

//头插
void SLpushFront(SL* p1, SLDataType x);

//尾删
void SLpopBack(SL* p1);

//头删
void SLpopFront(SL* p1);

//指定插入
void SLinsert(SL* p1, int pos, SLDataType x);

//指定删除
void SLerase(SL* p1, int pos);

//查询
//int SLfind(SL* p1, SLDataType x);

SeqList.c

#include "SeqList.h"

//初始化
void SLinit(SL* p1)
{
	p1->a = (SLDataType*)malloc((sizeof(SLDataType)) * 4);
	if (p1->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	p1->capacity = 4;
	p1->size = 0;
}

//销毁
void SLdestory(SL* p1)
{
	free(p1->a);
	p1->a = NULL;
	p1->capacity = 0;
	p1->size = 0;
}

//扩容
void SLcheckCapcity(SL* p1)
{
	if (p1->size >= p1->capacity)
	{
		SLDataType* tmp = (SLDataType*)realloc(p1->a, sizeof(SLDataType) * p1->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		p1->a = tmp;
		p1->capacity *= 2;
	}
}

//尾插
void SLpushBack(SL* p1, SLDataType x)
{
	assert(p1);
	SLcheckCapcity(p1);//检查是否需要扩容
	p1->a[(p1->size)++] = x;//在size处插入数据
}

//打印顺序表
void SLprint(SL* p1)
{
	for (int i = 0; i < p1->size; i++)
	{
		printf("%d\n", p1->a[i]);
	}
}

//头插
void SLpushFront(SL* p1, SLDataType x)
{
	assert(p1);
	SLcheckCapcity(p1);
	for (int i = p1->size; i > 0; i--)
	{
		p1->a[i] = p1->a[i - 1];
	}
	p1->a[0] = x;
	p1->size++;
}

//尾删
void SLpopBack(SL* p1)
{
	assert(p1);
	assert(p1->size);//顺序表不为空
	//p1->a[p1->size - 1] = -1;
	p1->size--;
}

//头删
void SLpopFront(SL* p1)
{
	assert(p1);
	assert(p1->size);
	for (int i = 1; i < p1->size; i++)
	{
		p1->a[i - 1] = p1->a[i];
	}
	p1->size--;
}

//指定下标添加
void SLinsert(SL* p1, int pos, SLDataType x)
{
	//要注意p1->size指向的是最后一个有效数据的下一位
	//pos是指定的插入位置的下标(如果为0则是头插,如果为ps->size-1则为尾插)
	//x是待插入的数据
	assert(p1 && pos >= 0 && pos < p1->size);
	SLcheckCapcity(p1);
	for (int i = p1->size; i > pos; i--)
	{
		p1->a[i] = p1->a[i - 1];
	}
	p1->a[pos] = x;
	p1->size++;
}

//指定下标删除
void SLerase(SL* p1, int pos)
{
	assert(p1 && pos >= 0 && pos < p1->size);
	for (int i = pos; i < p1->size - 1; i++)
	{
		p1->a[i] = p1->a[i + 1];
	}
	p1->size--;
}

//查询
//int SLfind(SL* p1, SLDataType x)
//{
//	assert(p1);
//	for (int i = 0; i < p1->size; i++)
//	{
//		if (p1->a[i] == x)
//		{
//			return i;//找到后返回下标
//		}
//	}
//	return -1;//没有找到返回-1
//}

正文

文件包含关系

在实现通讯录的工程文件中一共包含了5个子文件,分别是

  • test.c:用于在编写过程中测试代码能否正常运行
  • SeqList.h:用于在实现顺序表的过程中定义结构体和各种方法
  • SeqList.c:用于实现在头文件中定义的方法
  • Contact.h:定义通讯录中实现功能的函数
  • Contact.c:实现头文件中定义的函数

        通讯录实质上就是顺序表,只不过是改了名字(换汤不换药),我们只需要在实现顺序表的基础上给他起个别名通讯录(Contact)即可。

        在顺序表中,数组中存储的是单一的元素,在通讯录中,原数组中的元素变成了存储联系人数据的结构体(personInfo),数组中的每个元素都是结构体类型,包括姓名、电话、性别、住址等,本质上是两个结构体的嵌套。

在Contact.h中我们定义好联系人结构体和要用到的方法

#define NAME_MAX 20
#define GENDER_MAX 5
#define PHONE_MAX 20
#define ADDS_MAX 20

typedef struct personInfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char phoneNum[PHONE_MAX];
	char adds[ADDS_MAX];
}peoInfo;

//前置声明
typedef struct SeqList Contact;//将顺序表命名为"通讯录"

//菜单
void menu();

//初始化
void ContactInit(Contact* p);

//销毁
void ContactDestory(Contact* p);

//添加
void ContactAdd(Contact* p);

//删除
void ContactDle(Contact* p);

//修改
void ContactModify(Contact* p);

//查找
void ContactFind(Contact* p);

//显示
void ContactShow(Contact* p);

        typedef struct SeqList Contact;在这一句代码中使用前置声明将Seqlist重命名为Contact,在该文件中我们并没有定义结构体SeqList,使用前置声明只是为了让编译器知道有这个结构体的存在,而无法直接对之前重命名过的SL(typedef struct SeqList SL;)再命名的原因是编译器不能识别到SL的存在,如果想要识别必须包含"SeqList.h",但是头文件相互包含会导致报错,后面会讲到。

        在SeqList.h中将SLDateType自定义类型更改为perInfo,需要将"Contact.h"包含进文件,不能将"SeqList.h"同时包含进Contact.h中,这样会导致程序报错。

typedef peoInfo SLDataType;

//定义顺序表
typedef struct SeqList
{
	SLDataType* a;//数组
	int size;//有效元素
	int capacity;//容量
}SL;

        在Contact.h中对SeqList重命名,在SeqList.h中更改自定义数据类型,此时我们通过Contact*p和SL*p定义的两种结构体指针都会被程序正确识别,本质上Contact*p等价于SL*p。文章来源地址https://www.toymoban.com/news/detail-853053.html

Contact.h

#define NAME_MAX 20
#define GENDER_MAX 5
#define PHONE_MAX 20
#define ADDS_MAX 20

typedef struct personInfo
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char phoneNum[PHONE_MAX];
	char adds[ADDS_MAX];
}peoInfo;

//前置声明
typedef struct SeqList Contact;//将顺序表命名为"通讯录"

//菜单
void menu();

//初始化
void ContactInit(Contact* p);

//销毁
void ContactDestory(Contact* p);

//添加
void ContactAdd(Contact* p);

//删除
void ContactDle(Contact* p);

//修改
void ContactModify(Contact* p);

//查找
void ContactFind(Contact* p);

//显示
void ContactShow(Contact* p);

Contast.c

头文件

#include "Contact.h"
#include "SeqList.h"

菜单

void menu()
{
	printf("-----------------------\n");
	printf("        1.添加        \n");
	printf("        2.删除        \n");
	printf("        3.查找        \n");
	printf("        4.显示        \n");
	printf("        5.修改        \n");
	printf("        0.退出        \n");
	printf("-----------------------\n");
}

初始化

//初始化
void ContactInit(Contact* p)
{
	SLinit(p);//直接调用已经在SeqList.c中实现好的初始化函数即可
} 

销毁

void ContactDestory(Contact* p)
{
	SLdestory(p);
}

添加

void ContactAdd(Contact* p)
{
	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.phoneNum);

	printf("请输入联系人的住址:\n");
	scanf("%s", info.adds);

	SLpushBack(p, info);//这里选择尾插

	printf("添加成功!\n\n");

}

判断名字是否存在

int FindName(Contact* p, char* name)
{
	for (int i = 0; i < p->size; i++)
	{
		if (strcmp(p->a[i].name, name) == 0)
			return i;//返回下标
	}
	return -1;
}

删除

void ContactDle(Contact* p)
{
	char n[NAME_MAX];
	printf("请输入要删除的联系人姓名:\n");
	scanf("%s", n);
	int ret = FindName(p, n);
	if (ret < 0)
	{
		printf("删除对象不存在!\n");
		return;
	}
	SLerase(p, ret);
	printf("删除成功!\n");
}

显示

void ContactShow(Contact* p)
{
	printf("%-15s%-15s%-15s%-15s%-15s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < p->size; i++)
	{
		printf("%-15s%-15s%-15d%-15s%-15s\n", p->a[i].name, p->a[i].gender, p->a[i].age,
			p->a[i].phoneNum, p->a[i].adds);
	}
}

修改

void ContactModify(Contact* p)
{
	char name[NAME_MAX];
	printf("请输入要修改的联系人姓名:\n");
	scanf("%s", name);
	int ret = FindName(p, name);
	if (ret < 0)
	{
		printf("修改对象不存在!\n");
		return;
	}
	printf("请输入新的姓名:\n");
	scanf("%s", p->a[ret].name);

	printf("请输入新的性别:\n");
	scanf("%s", p->a[ret].gender);

	printf("请输入新的年龄:\n");
	scanf("%d", &p->a[ret].age);

	printf("请输入新的电话:\n");
	scanf("%s", p->a[ret].phoneNum);

	printf("请输入新的地址:\n");
	scanf("%s", p->a[ret].adds);

	printf("修改成功!\n\n");
}

查找

void ContactFind(Contact* p)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名:\n");
	scanf("%s", name);
	
	int ret = FindName(p, name);
	if (ret < 0)
	{
		printf("联系人不存在!\n");
		return;
	}
	printf("%-15s%-15s%-15s%-15s%-15s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("%-15s%-15s%-15d%-15s%-15s\n", p->a[ret].name, p->a[ret].gender, p->a[ret].age,
		p->a[ret].phoneNum, p->a[ret].adds);
	printf("查询成功!\n\n");
}

测试文件test.c

#include "SeqList.h"

int main()
{
	Contact con;
	ContactInit(&con);
	while (1)
	{
		menu();
		int i = 0;
		printf("请选择你的操作:");
		scanf("%d", &i);
		switch (i)
		{
			case 1:
				ContactAdd(&con);
				break;
			case 2:
				ContactDle(&con);
				break;
			case 3:
				ContactFind(&con);
				break;
			case 4:
				ContactShow(&con);
				break;
			case 5:
				ContactModify(&con);
				break;
			case 0:
				printf("程序已退出!\n");
				break;
		}
	}
	return 0;
}

到了这里,关于数据结构(初阶):顺序表实战通讯录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【(数据结构) —— 顺序表的应用-通讯录的实现】

    C语言基础要求:结构体、动态内存管理、顺序表、文件件操作 (1). 功能要求 1)至少能够存储100个人的通讯信息 2)能够保存用户信息:名字、性别、年龄、电话、地址等 3)增加联系人信息 4)删除指定联系人 5)查找制定联系人 6)修改指定联系人 7)显示联系人信息 (2).重

    2024年02月08日
    浏览(28)
  • 数据结构课设—C语言实现通讯录管理系统(顺序表实现)

    这个项目是我大一时期数据结构的课程设计,在我潜心研究下出来的,对于当时的我来说算是非常满意啦,哈哈哈哈哈哈哈哈哈哈☆*: .。. o(≧▽≦)o .。.:*☆ 目录 一、引言 1.目的: 2.意义: 3.主要任务: 4.程序功能: 5.编译工具: 二、正文 1.系统模块: 2.算法流程图: 3.各

    2024年02月02日
    浏览(61)
  • 数据结构--学生通讯录管理系统

    文章目录 一、问题描述 二、系统功能设计 三、各个代码部分 四、整体代码及其运行 五、总结 学生通讯录管理系统--C语言实现 在现实中,用学号和姓名来记录学生需要花费大量的纸质材料,并且出现容易丢失、查找困难等问题。 “学生通讯管理系统”是为了帮助老师、同

    2024年02月11日
    浏览(36)
  • 【(数据结构)—— 基于单链表实现通讯录】

    (1). 知识要求 C语言基础要求:结构体、动态内存管理、单链表、文件件操作 (2). 功能要求 1)至少能够存储100个人的通讯信息 2)能够保存用户信息:名字、性别、年龄、电话、地址等 3)增加联系人信息 4)删除指定联系人 5)查找制定联系人 6)修改指定联系人 7)显示联系

    2024年02月08日
    浏览(25)
  • python数据结构实验设计(单链表):通讯录管理

    目录 摘要 一、课程设计目的及内容 创新功能: 二、算法及设计过程分析 1.总流程 2.主界面 3.文件处理与生成单链表 4.查看所有联系人信息 5.查看人数 6.查找联系人(以姓名或号码为依据) 7.对姓名或号码输入进行模糊查找  8.添加联系人 9.删除联系人  10.合并两个通

    2024年01月16日
    浏览(24)
  • C语言实现建立手机通讯录(顺序结构)

    今天来和大家分享一个简易通讯录(C语言实现) 首先要介绍一下通讯录的基本功能 添加联系人信息 删除指定联系人信息 查找指定联系人信息 修改指定联系人信息 显示所有联系人信息 总结,考虑到数据结构中的顺序表和单链表,我们可以采用这两种结构来实现。本文选择

    2024年02月07日
    浏览(29)
  • 初阶数据结构:顺序表

    了解到学习数据结构与算法的重要性后,又学习了评判程序效率高低算法好坏的标准,时间空间复杂度。接下来,进行一些简单数据结构的初步学习。所有数据结构中存在着可以划分为一大类的简单结构, 线性表 ,即在 逻辑上都呈现线性关系 的数据结构(物理结构上不一定

    2024年01月20日
    浏览(33)
  • 【数据结构初阶】顺序表

    线性表(linear list) 是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上

    2024年02月02日
    浏览(33)
  • 数据结构(初阶)第二节:顺序表

    数据结构(初阶)第一节:数据结构概论-CSDN博客 从本文正式进入对数据结构的讲解,开始前友友们要有C语言的基础,熟练掌握 动态内存管理 、 结构体 、 指针 等章节,方便后续的学习。 顺序表(Sequence List) 顺序表的分类 静态顺序表 动态顺序表 顺序表的功能 初始化 扩

    2024年04月12日
    浏览(26)
  • 初阶数据结构之---二叉树的顺序结构-堆

    今天要讲的堆,不是操作系统虚拟进程地址空间中(malloc,realloc等开空间的位置)的那个堆,而是数据结构中的堆,它们虽然名字相同,却是截然不同的两个概念。堆的底层其实是 完全二叉树 ,如果你问我,完全二叉树是什么。好吧,那我先从树开始讲起,开始我们今天的

    2024年03月14日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包