数据结构——通讯录(基于顺序表实现)

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

动态顺序表:https://blog.csdn.net/YUYUJOB/article/details/136688509

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

通讯录本质将一个通讯录结构体类型的变量存放在指针数组内

Contact.h --文件

#define NAME_MAX 100
#define SEX_MAX 10
#define TEL_MAX 15
#define ADDR_MAX 100

typedef struct ContactInfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}CInfo;

//这样重新命名方便有辨识度
typedef struct SeqList contact; 

//通讯录初始化与销毁
void ContactInit(contact* pcon); //等价于(SL* pcon),讲究代码的一致性
void ContactDestroy(contact* pcon);

//添加联系人
void ContactAdd(contact* pcon);
//删除联系人
void ContactDel(contact* pcon);
//修改联系人
void ContactModify(contact* pcon);
//查看联系人
void Contactshow(contact* pcon);
//查找联系人
void ContactFind(contact* pcon);


SeqList.h --文件

typedef struct ContactInfo SLDataType;  //自定义一个可随时改变存储类型的类型名
typedef struct SeqList
{
	SLDataType* a;
	int size;   //顺序表内的有效个数
	int capacity; //顺序表的空间大小
}SL;


//对顺序表进行初始化
void SLInit(SL* ps);

//进行顺序表进行销毁
void SLDestroy(SL* ps);

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

//任意位置删除
void SLErase(SL* ps, int pos);

//
bool SLIsEmpty(SL* ps);

SeqList.c --文件

#include"SeqList.h"
//初始化
void SLInit(SL* ps) {
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}
//销毁
void SLDestroy(SL* ps) {
	if (ps->a)
		free(ps->a);
	//防止变为野指针
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}
//是否需要开辟新的空间
void SLCheckCapacity(SL* ps) {
	//判断此时的空间是否充足
	if (ps->size == ps->capacity) {
		//判断初始值的Capacity是否为0,毕竟0二倍还是0
		int newCapatity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//空间不足则需要扩容 (一般情况都以1.5/2倍扩容)
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapatity * sizeof(SLDataType));
		//realloc 也存在申请失败
		if (tmp == NULL) {
			perror("realloc fail!\n");
			return 1;
		}
		ps->a = tmp;
		ps->capacity = newCapatity;
	}
}

//  尾插
void SLPushBack(SL* ps, SLDataType x) {
	//判断是否为空指针
	assert(ps);
	//判断此时的空间是否充足
	SLCheckCapacity(ps);

	//size也需要++,下列直接简便式 
	ps->a[ps->size++] = x;
}

//头插
void SLPushFront(SL* ps, SLDataType x) {
	assert(ps);
	//判断是否空间足够,不够则扩容
	SLCheckCapacity(ps);
	//头部插入数据,历史数据后移一位
	for (size_t i = ps->size; i > 0; i--) {
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->size++;
}

//尾删
void SLPopback(SL* ps) {
	assert(!SLIsEmpty(ps));//等价于 assert(ps->size)  如果size为假,则断言
	assert(ps);

	ps->size--;
}

//任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x) {
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//判断是否空间足够,不够则扩容
	SLCheckCapacity(ps);
	for (size_t i = ps->size; i > pos; i--) {
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->size++;
}
//任意位置删除
void SLErase(SL* ps, int pos) {
	assert(ps);
	assert(!SLIsEmpty(ps));
	assert(pos >= 0 && pos < ps->size);
	for (size_t i = pos; i < ps->size - 1; i++) {
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

bool SLIsEmpty(SL* ps) {
	assert(ps);
	//这样是不对的,这样只能判断空间是否足够
	//return ps->szie == ps->capacity
	return ps->size == 0;
}

Contact.c --文件

#include"Contact.h"
#include"SeqList.h"
//通讯录的初始化
void ContactInit(contact* pcon) {
	SLInit(pcon);
}
//通讯录的销毁
void ContactDestroy(contact* pcon) {
	SLDestroy(pcon);
}
//通讯录中添加联系人
void ContactAdd(contact* pcon) {
	CInfo info;
	printf("请输入联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入联系人性别:\n");
	scanf("%s", info.sex);
	printf("请输入联系人年龄:\n");
	scanf("%d", &info.age);
	printf("请输入联系人电话:\n");
	scanf("%s", info.tel);
	printf("请输入联系人地址:\n");
	scanf("%s", info.addr);
	//联系人数据添加到SL结构类型的a首地址去
	SLPushBack(pcon, info);
}

//查找通讯录联系人
int FindByName(contact* pcon,char name[]){
	for (int i = 0; i < pcon->size; i++) {
		if (strcmp(pcon->a[i].name, name) == 0) {
			return i;
		}
	}
	return -1;
}
//删除通讯录联系人
void ContactDel(contact* pcon) {
	printf("请输入要删除的联系人姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int findidex = FindByName(pcon, name);
	//不存在的情况
	if (findidex < 0) {
		printf("所要删除的联系人不存在!\n");
		return;
	}
	SLErase(pcon, findidex);
}
//修改通讯录联系人
void ContactModify(contact* pcon) {
	printf("请输入要修改的用户名称:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int findidex = FindByName(pcon, name);
	if (findidex < 0) {
		printf("要修改的用户不存在!\n");
		return;
	}
	//以下进行修改
	printf("请输入联系人姓名:\n");
	scanf("%s", pcon->a[findidex].name);
	printf("请输入联系人性别:\n");
	scanf("%s", pcon->a[findidex].sex);
	printf("请输入联系人年龄:\n");
	scanf("%d", &pcon->a[findidex].age);
	printf("请输入联系人电话:\n");
	scanf("%s", pcon->a[findidex].tel);
	printf("请输入联系人地址:\n");
	scanf("%s", pcon->a[findidex].addr);

	printf("修改成功!");
}
//查看通讯录联系人
void Contactshow(contact* pcon) {
	//也就是打印通讯录里的信息
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pcon->size; i++) {
		printf("%-4s %-4s %-4d %-4s %-4s\n",
			pcon->a[i].name,
			pcon->a[i].sex,
			pcon->a[i].age,
			pcon->a[i].tel,
			pcon->a[i].addr
		);
	}
}
//查找通讯录指定联系人
void ContactFind(contact* pcon) {
	char name[NAME_MAX];
	printf("请输入查找联系人姓名:\n");
	scanf("%s", name);
	int findidex = FindByName(pcon, name);
	if (findidex < 0) {
		printf("查找的用户不存在!");
		return;
	}
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("%-4s %-4s %-4d %-4s %-4s\n",
		pcon->a[findidex].name,
		pcon->a[findidex].sex,
		pcon->a[findidex].age,
		pcon->a[findidex].tel,
		pcon->a[findidex].addr
	);
}

SeqList.c --文件

#include"SeqList.h"

void SLInit(SL* ps) {
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

void SLDestroy(SL* ps) {
	if (ps->a)
		free(ps->a);
	//防止变为野指针
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

void SLCheckCapacity(SL* ps) {
	//判断此时的空间是否充足
	if (ps->size == ps->capacity) {
		//判断初始值的Capacity是否为0,毕竟0二倍还是0
		int newCapatity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//空间不足则需要扩容 (一般情况都以1.5/2倍扩容)
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapatity * sizeof(SLDataType));
		//realloc 也存在申请失败
		if (tmp == NULL) {
			perror("realloc fail!\n");
			return 1;
		}
		ps->a = tmp;
		ps->capacity = newCapatity;
	}
}

//  尾插
void SLPushBack(SL* ps, SLDataType x) {
	//判断是否为空指针
	assert(ps);
	//判断此时的空间是否充足
	SLCheckCapacity(ps);

	//size也需要++,下列直接简便式 
	ps->a[ps->size++] = x;
}

//任意位置删除
void SLErase(SL* ps, int pos) {
	assert(ps);
	assert(!SLIsEmpty(ps)); //等价于ps->size != 0
	assert(pos >= 0 && pos < ps->size);
	for (size_t i = pos; i < ps->size - 1; i++) {
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

bool SLIsEmpty(SL* ps) {
	assert(ps);
	//这样是不对的,这样只能判断空间是否足够
	//return ps->szie == ps->capacity  ----错误
	return ps->size == 0;
}

test.c --文件

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

void menu() {
	printf("    *************  通讯录  *********************\n");
	printf("************1、添加  2、删除  3、修改  *************\n");
	printf("************4、查找  5、查看  0、退出  *************\n");
	printf("    ********************************************\n");

}
int main()
{
	int op = -1;
	contact con;
	ContactInit(&con);
	
	do {
		menu();
		printf("请选择你的操作:\n");
		scanf("%d", &op);
		switch (op)
		{
		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("goodbye!\n");
			break;
		default:
			printf("输入有误请在菜单里选择!");
			break;
		}
	} while (op != 0);
	return 0;
}

ok,今天的分享就到这里啦,欢迎你的莅临,也非常希望你宝贵的建议,让我们一起进步!
您的三连就是对yuyu在编程路上最强的动力!

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,我们需要定义通讯录的联系人实体类: ```java public class Contact { private String name; private String phoneNumber; private String email; public Contact(String name, String phoneNumber, String email) { this.name = name; this.phoneNumber = phoneNumber; this.email = email; } public String getName() { return name; } public String getPhoneNumber() { return phoneNumber; } public String getEmail() { return email; } @Override public String toString() { return "Name: " + name + ", Phone number: " + phoneNumber + ", Email: " + email; } } ``` 接下来,我们需要实现顺序表类: ```java public class ContactList { private Contact[] contacts; private int size; public ContactList(int capacity) { contacts = new Contact[capacity]; size = 0; } public int getSize() { return size; } public void addContact(Contact contact) { if (size == contacts.length) { throw new RuntimeException("Contact list is full"); } contacts[size++] = contact; } public Contact getContact(int index) { if (index < 0 || index >= size) { throw new RuntimeException("Invalid index"); } return contacts[index]; } public void removeContact(int index) { if (index < 0 || index >= size) { throw new RuntimeException("Invalid index"); } for (int i = index; i < size - 1; i++) { contacts[i] = contacts[i + 1]; } contacts[size - 1] = null; size--; } public void updateContact(int index, Contact contact) { if (index < 0 || index >= size) { throw new RuntimeException("Invalid index"); } contacts[index] = contact; } public Contact[] getAllContacts() { Contact[] result = new Contact[size]; for (int i = 0; i < size; i++) { result[i] = contacts[i]; } return result; } } ``` 然后,我们可以在主函数中使用顺序表类来实现通讯录: ```java public static void main(String[] args) { ContactList contactList = new ContactList(10); contactList.addContact(new Contact("Alice", "1234567890", "alice@example.com")); contactList.addContact(new Contact("Bob", "2345678901", "bob@example.com")); contactList.addContact(new Contact("Charlie", "3456789012", "charlie@example.com")); contactList.removeContact(1); contactList.updateContact(0, new Contact("Alice", "0987654321", "alice@example.com")); Contact[] contacts = contactList.getAllContacts(); for (Contact contact : contacts) { System.out.println(contact); } } ``` 输出结果: ``` Name: Alice, Phone number: 0987654321, Email: alice@example.com Name: Charlie, Phone number: 3456789012, Email: charlie@example.com ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值