数据结构——通讯录(顺序表的实战项目)

(---).通讯录的功能

大家应该都十分了解通讯录的功能吧,无非就是对联系人的增添删除,还有信息的修改,并且联系人信息要包含名字,电话,性别,地址等。我把通讯录的功能总结如下:

1)⾄少能够存储100个⼈的通讯信息

2)能够保存⽤⼾信息:名字、性别、年龄、电话、地址等

3)增加联系⼈信息

4)删除指定联系⼈

5)查找制定联系⼈

6)修改指定联系⼈

7)显⽰联系⼈信息

接下来我们就根据以上信息进行代码的实现。

(二).通讯录的代码实现

2.1定义结构体

cs 复制代码
//通讯录头文件
#define NAME_MAX 20
#define GENDER_MAX 10
#define AGE_MAX 100
#define TEL_MAX 20
#define ADDRESS_MAX 20

//定义联系人数据结构
//名字 性别 年龄 电话 地址
typedef struct personInfo 
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int  age;
	char tel[TEL_MAX];
	char address[ADDRESS_MAX];

}peoInfo;

2.2通讯录的初始化

cs 复制代码
//通讯录的初始化,实际上就是顺序表的初始化,这里的con就是sl
void ContactInit(Contact* con)
{
	SLInit(con);
}

//这里通讯录的初始化实际上就是顺序表的初始化
//顺序表初始化
void SLInit(SL* s)
{
	s->arr = NULL;
	s->size = s->capacity = 0;
}

2.3通讯录的销毁

cs 复制代码
//通讯录的销毁
void ContactDestory(Contact* con)
{
	SLDestroy(con);
}

//同样这里通讯录的销毁实际上就是顺序表的销毁

//顺序表的销毁
void SLDestroy(SL* ps)
{
	if (ps->arr != NULL)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

2.4通讯录的添加数据

cs 复制代码
//通讯录的添加数据
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.address);

	//往通讯录中添加联系人数据
	SLPushBack(con, Info);

}


void SLPushBack(SL* ps, SLDataType x)
{
	//首先要判断空间够不够

	assert(ps);//断言ps不为空指针

	SLCheckcapacity(ps);
	/*ps->arr[ps->size] = x;
	ps->size++;*/
	ps->arr[ps->size++] = x;
}

//判断内存空间够不够
void SLCheckcapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		//三目表达式
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//对顺序表进行成倍的扩充
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("ralloc fail!");
			return 1;
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}

当然这里进行通讯录数据的添加我们使用顺序表的头插,尾插,在任意位置插入都是可以的,这里我选择的尾插。

2.5通讯录的删除数据

cs 复制代码
//通讯录的删除数据
void ContactDel(Contact* con)
{
	//要删除的信息必须要存在,才能进行删除操作
	char name[NAME_MAX];
	printf("请输入要删除联系人姓名:");
	scanf("%s", name);
	int Find=Findbyname(con, name);
	if (Find < 0)
	{
		printf("要删除的信息不存在!\n");
		return;
	}
	SLErase(con, Find);

	printf("删除成功!\n");

}
//在任意位置删除
void SLErase(SL* ps, int pos)
  {
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

2.6通讯录的修改

cs 复制代码
//通讯录的修改
void ContactModify(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要修改用户名的名字:\n");
	scanf("%s", name);
	int Find = Findbyname(con, name);
	if (Find < 0)
	{
		printf("要删除的信息不存在!\n");
		return;
	}
	printf("请输入新的名字:\n");
	scanf("%s", con->arr[Find].name);

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

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

	printf("请输入新的电话:\n");
	scanf("%s", con->arr[Find].tel);

	printf("请输入新的地址:\n");
	scanf("%s", con->arr[Find].address);

}

Findbyname(Contact* con,char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			return i;
		}
	}
	return -1;

}

2.7通讯录的查找

cs 复制代码
Findbyname(Contact* con,char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			return i;
		}
	}
	return -1;

}

//通讯录的查找
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 %5s %4d %4s %4s\n",
			con->arr[Find].name,
			con->arr[Find].gender,
			con->arr[Find].age,
			con->arr[Find].tel,
			con->arr[Find].address);

}

2.8展示通讯录数据

cs 复制代码
//展示通讯录数据
void ContactShow(Contact* con)
{
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%3s %5s %4d %4s %4s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].address);
	}
}

2.9通讯录代码实现汇总

SqList.h:

cs 复制代码
#pragma once
//SeqList.h进行顺序表结构的声明
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
//创建结构体
//静态结构体
//struct seqlist 
//{
//	int arr[100];
//	int size;
//};

typedef peoInfo SLDataType;
//动态结构体
typedef struct SeqList
{
	SLDataType* arr;
	int size;//有效数据的个数
	int capacity;//顺序表的大小
}SL;

//初始化顺序表
void SLInit(SL* ps);
//销毁顺序表
void SLDestroy(SL* ps);
//打印代码
void SLPrint(SL ps);

//头部插⼊删除 / 尾部插⼊删除

//尾部插入
void SLPushBack(SL* ps, SLDataType x);
//头部插入
void SLPushFront(SL* ps, SLDataType x);

//头部删除
void SLPopFront(SL* ps);
//尾部删除
void SLPopBack(SL* ps);
//任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x);
//任意位置删除
void SLErase(SL* ps, int pos);
//查找数据
int SLFind(SL* ps, SLDataType x);

Contact.h:

cs 复制代码
#pragma once
//通讯录头文件
#define NAME_MAX 20
#define GENDER_MAX 10
#define AGE_MAX 100
#define TEL_MAX 20
#define ADDRESS_MAX 20

//定义联系人数据结构
//名字 性别 年龄 电话 地址
typedef struct personInfo 
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int  age;
	char tel[TEL_MAX];
	char address[ADDRESS_MAX];

}peoInfo;

//要用到顺序表的相关方法,对通讯录的操作实际上是对顺序表进行操作
//给顺序表起个名字叫通讯录
typedef struct SeqList Contact;//重新对顺序表起名叫通讯录

//通讯录实现的方法

//通讯录的初始化
void ContactInit(Contact* con);
//通讯录的销毁
void ContactDestory(Contact* con);
//通讯录的添加数据
void ContactAdd(Contact* con);
//通讯录的删除数据
void ContactDel(Contact* con);
//通讯录的修改
void ContactModify(Contact* con);
//通讯录的查找
void ContactFind(Contact* con);
//展示通讯录数据
void ContactShow(Contact* con);

SqList.c:

cs 复制代码
//进行顺序表的实现
#include"SeqList.h";
//顺序表初始化
void SLInit(SL* s)
{
	s->arr = NULL;
	s->size = s->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{
	if (ps->arr != NULL)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

//判断内存空间够不够
void SLCheckcapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		//三目表达式
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//对顺序表进行成倍的扩充
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("ralloc fail!");
			return 1;
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}

//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	//首先要判断空间够不够

	assert(ps);//断言ps不为空指针

	SLCheckcapacity(ps);
	/*ps->arr[ps->size] = x;
	ps->size++;*/
	ps->arr[ps->size++] = x;
}


//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckcapacity(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}
//打印
//void SLPrint(SL ps)
//{
//	for (int i = 0; i < ps.size; i++)
//	{
//		printf("%d ", ps.arr[i]);
//	}
//	printf("\n");
//}
//尾删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	/*ps->arr[ps->size - 1] = -1;*/
	--ps->size;
}

//头删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	--ps->size;
}

//任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLCheckcapacity(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;

}

//在任意位置删除
void SLErase(SL* ps, int pos)
  {
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}


//查找数据
//int SLFind(SL* ps, SLDataType x)
//{
//	assert(ps);
//	for (int i = 0; i < ps->size; i++)
//	{
//		if (ps->arr[i] == x)
//		{
//			return i;
//		}
//	}
//	return -1;
//}

Contact.c:

cs 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

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

//通讯录的初始化,实际上就是顺序表的初始化,这里的con就是sl
void ContactInit(Contact* con)
{
	SLInit(con);
}

//通讯录的销毁
void ContactDestory(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.address);

	//往通讯录中添加联系人数据
	SLPushBack(con, Info);

}

Findbyname(Contact* con,char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			return i;
		}
	}
	return -1;

}
//通讯录的删除数据
void ContactDel(Contact* con)
{
	//要删除的信息必须要存在,才能进行删除操作
	char name[NAME_MAX];
	printf("请输入要删除联系人姓名:");
	scanf("%s", name);
	int Find=Findbyname(con, name);
	if (Find < 0)
	{
		printf("要删除的信息不存在!\n");
		return;
	}
	SLErase(con, Find);

	printf("删除成功!\n");

}


//展示通讯录数据
void ContactShow(Contact* con)
{
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%3s %5s %4d %4s %4s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].address);
	}
}


//通讯录的修改
void ContactModify(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要修改用户名的名字:\n");
	scanf("%s", name);
	int Find = Findbyname(con, name);
	if (Find < 0)
	{
		printf("要删除的信息不存在!\n");
		return;
	}
	printf("请输入新的名字:\n");
	scanf("%s", con->arr[Find].name);

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

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

	printf("请输入新的电话:\n");
	scanf("%s", con->arr[Find].tel);

	printf("请输入新的地址:\n");
	scanf("%s", con->arr[Find].address);

}
//通讯录的查找
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 %5s %4d %4s %4s\n",
			con->arr[Find].name,
			con->arr[Find].gender,
			con->arr[Find].age,
			con->arr[Find].tel,
			con->arr[Find].address);

}

test.c:

cs 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

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

//通讯录的初始化,实际上就是顺序表的初始化,这里的con就是sl
void ContactInit(Contact* con)
{
	SLInit(con);
}

//通讯录的销毁
void ContactDestory(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.address);

	//往通讯录中添加联系人数据
	SLPushBack(con, Info);

}

Findbyname(Contact* con,char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			return i;
		}
	}
	return -1;

}
//通讯录的删除数据
void ContactDel(Contact* con)
{
	//要删除的信息必须要存在,才能进行删除操作
	char name[NAME_MAX];
	printf("请输入要删除联系人姓名:");
	scanf("%s", name);
	int Find=Findbyname(con, name);
	if (Find < 0)
	{
		printf("要删除的信息不存在!\n");
		return;
	}
	SLErase(con, Find);

	printf("删除成功!\n");

}


//展示通讯录数据
void ContactShow(Contact* con)
{
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%3s %5s %4d %4s %4s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].address);
	}
}


//通讯录的修改
void ContactModify(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入要修改用户名的名字:\n");
	scanf("%s", name);
	int Find = Findbyname(con, name);
	if (Find < 0)
	{
		printf("要删除的信息不存在!\n");
		return;
	}
	printf("请输入新的名字:\n");
	scanf("%s", con->arr[Find].name);

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

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

	printf("请输入新的电话:\n");
	scanf("%s", con->arr[Find].tel);

	printf("请输入新的地址:\n");
	scanf("%s", con->arr[Find].address);

}
//通讯录的查找
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 %5s %4d %4s %4s\n",
			con->arr[Find].name,
			con->arr[Find].gender,
			con->arr[Find].age,
			con->arr[Find].tel,
			con->arr[Find].address);

}

好了,各位大佬们,以上就是我对通讯录知识的全部讲解,如果有什么不对的地方还请各位大佬们指出,如果觉得小编写的还不错的话,您的免费一键三连将是对小编最大的支持!谢谢大家!后面我也一定会持续更新为大家提供更加高质量的作品!

相关推荐
小字节,大梦想1 小时前
【C++】二叉搜索树
数据结构·c++
我是哈哈hh1 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
丶Darling.2 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5202 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法
Indigo_code2 小时前
【数据结构】【链表代码】合并有序链表
数据结构·windows·链表
jiyisuifeng19912 小时前
代码随想录训练营第54天|单调栈+双指针
数据结构·算法
我言秋日胜春朝★2 小时前
【C++】红黑树
数据结构
新晓·故知3 小时前
<基于递归实现线索二叉树的构造及遍历算法探讨>
数据结构·经验分享·笔记·算法·链表
gorgor在码农3 小时前
Mysql 索引底层数据结构和算法
数据结构·数据库·mysql
武昌库里写JAVA4 小时前
【Java】Java面试题笔试
c语言·开发语言·数据结构·算法·二维数组