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

前言:

  数据结构是计算机储存,组织数据的方式,今天我们主要来了解顺序表的实现,就是如何去实现我们的增删查改,顺序表的底层就是数组,对数组进行了封装,实现了常用的增删查改等接口,顺序表贴近我们大家的生活,比如说我们的通讯录,也可以靠顺序表的加工来实现,在实现顺序表需要一些c语言的基础知识,比如结构体,指针等等,就让我们来了解一下吧!

一.顺序表的实现

1.顺序表的概念

1.1顺序表属于线性表的一种(线性表是具有相同特性的数据结构的集合)

1.2顺序表在物理结构是连续的,在逻辑结构也是连续

2.顺序表的分类

2.1静态顺序表

静态顺序表就是给定一些固定值

  接下来我们来分析一下静态顺序表的缺点,静态顺序表需要我们定义一个定长数组,在我们写项目的时候,我们无法得知这个定长数组的大小应该定多大,如果定长数组给大,就会空间浪费,但是如果定长数组给小,空间不够用,可能出现用户信息泄露的问题 ,所以我们在实现顺序表一般推荐大小使用动态顺序表的方法

2.2动态顺序表

当我们使用动态顺序表实现就比较灵活了,当我们定义的顺序表空间不够时,我们可以使用realloc来扩大我们的动态内存,这样就不会出现空间不够用的情况了,在增加容量是成倍数的增加,合理使用内存空间

 3.文件创建

这里我们需要进行三个文件的创建

4.定义顺序表结构,初始化及销毁

4.1定义顺序表

//定义顺序表结构
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;
	int capacity;
}SL;

4.2顺序表初始化 

 让我们调试来查看一下

我们发现初始化成功了全为0 

4.3顺序表的销毁

因为我们在增加容量要使用动态realloc函数,所以要用free将其进行释放。

5.顺序表的插入

5.1顺序表尾插

我们先来分析一下,我们想要尾插,首先我们应该注意的问题是空间,我们的空间是否足够,如果不够,我们要用realloc来开辟动态内存,保证我们的数据可以足够储存

​​​​​​​

ps->arr[ps->size++] = x;
void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		//增加容量
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);
		}
		//申请空间成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}
//顺序表的尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	//1.判断空间是否足够
	SLCheckCapacity(ps);
	//尾插
	ps->arr[ps->size++] = x;
}

 让我们来测试一下是否可以达到预期的效果

通过这两张图片我们可以看出我们尾插到了想要插入的地方并且正确合理开辟了空间

5.2顺序表头插

画图分析:

//头插
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];//arr[1]=arr[0] 
	}
	ps->arr[0] = x;
    ps->size++;
}

测试代码: 

 为了更方便观察,我们可以打印一下

//顺序表打印
void SLPrint(SL s)
{
	for (int i = 0; i < s.size; i++)
	{
		printf("%d ", s.arr[i]);
	}
	printf("\n");
}

6.顺序表删除

6.1顺序表尾删

我们可以先来画图分析一下:

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);//判断顺序表地址是否为空
	assert(ps->arr);//判断数组是否为空
	ps->size--;
}

代码测试:

6.2顺序表头删

//头删
void SLPopFront(SL* ps)
{
	assert(ps);//判断顺序表地址是否为空
	assert(ps->arr);//判断数组是否为空
	for (int i = 0; i<ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i+1];//arr[0]=arr[1]
	}
	ps->size--;
}

代码测试:

 7.顺序表指定位置插入

先来画图分析一下:

//指定位置添加
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++;
}

代码测试:

  8.顺序表指定位置删除

 

//指定位置删除
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	//向前移动
	for (int i = pos; i<ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
    ps->size--;
}

测试:

 9.顺序表的查找

//顺序表的查找
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;
}

代码测试 

完整代码:

SeqList.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//定义顺序表结构
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;
	int capacity;
}SL;

//顺序表初始化
void SLinit(SL* ps);

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

//顺序表的头插和尾插
void SLPushBack(SL* ps, SLDataType x);//尾插
void SLPushFront(SL* ps, SLDataType x);//头插

//顺序表打印
void SLPrint(SL s);

//顺序表的头删和尾删
void SLPopBack(SL* ps);//尾删
void SLPopFront(SL* ps);//头删

//指定位置添加
void SLInsert(SL* ps, int pos, SLDataType x);

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


//顺序表的查找
int SLFind(SL* ps, SLDataType x);

SeqList.c 

#include"SeqList.h"

//顺序表初始化
void SLinit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}


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


void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		//增加容量
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);
		}
		//申请空间成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}
//顺序表的尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	//1.判断空间是否足够
	SLCheckCapacity(ps);
	//尾插
	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];//arr[1]=arr[0] 
	}
	ps->arr[0] = x;
	ps->size++;
}

//顺序表打印
void SLPrint(SL s)
{
	for (int i = 0; i < s.size; i++)
	{
		printf("%d ", s.arr[i]);
	}
	printf("\n");
}

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);//判断指针是否为空
	assert(ps->arr);//判断数组是否为空
	ps->size--;
}


//头删
void SLPopFront(SL* ps)
{
	assert(ps);//判断指针是否为空
	assert(ps->arr);//判断数组是否为空
	for (int i = 0; i<ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i+1];//arr[0]=arr[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-1; 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;
}

test.c 

这里只测试了几组,有兴趣的可以多测试几组

#include"SeqList.h"
SLtest()
{
	SL sl;
	SLinit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//SLPrint(sl);
	/*SLPushFront(&sl, 5);
	SLPrint(sl);*/
	/*SLPopBack(&sl);
	SLPrint(sl);*/
	/*SLPopFront(&sl);
	SLPrint(sl);*/
	/*SLInsert(&sl, 3, 5);
	SLPrint(sl);
	SLErase(&sl, 3);
	SLPrint(sl);*/
	int find = SLFind(&sl, 3);
	if (find > 0)
	{
		printf("找到了,下标为%d\n", find);
	}
	else
	{
		printf("没有找到\n");
	}
	SLDestroy(&sl);
}

int main()
{
	SLtest();
	return 0;
}

 二.基于顺序表实现通讯录

1.大概思路

顺序表可以存储任意类型的数据,可以是内置类型,也可以是自定义类型

我们需要创建通讯录的头文件和源文件,在顺序表的基础上进行添加,以实现我们想要的通讯录

接下来给大家画一个图方便大家理解:

2.文件创建

我们还需要创建通讯录的头文件源文件

3.定义通讯录结构体,初始化及销毁

3.1定义通讯录结构体

 3.2通讯录初始化

 

3.3通讯录的销毁 

 4.通讯录的数据添加

//通讯录添加数据
void ContactAdd(Contact* con)
{
	//输入要添加的数据
	PI pi;
	printf("请输入想要添加的姓名:\n");
	scanf("%s", pi.name);

	printf("请输入想要添加的性别:\n");
	scanf("%s", pi.gender);

	printf("请输入想要添加的年龄:\n");
	scanf("%d", &pi.age);

	printf("请输入想要添加的电话:\n");
	scanf("%s", pi.tel);

	printf("请输入想要添加的地址:\n");
	scanf("%s", pi.addr);
	//在顺序表中有头插,尾插,指定插入都可以使用
	SLPushBack(con, pi);
}

 测试一下:

5.通讯录的显示

//展示通讯录
void ContactShow(Contact* con)
{
    //首先打印表头 姓名 性别 年龄 电话 地址
    printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
    //遍历数组
    for (int i = 0; i < con->size; i++)
    {
        printf("%-4s %-4s %-4d %-4s %-4s\n",
            con->arr[i].name,
            con->arr[i].gender,
            con->arr[i].age,
            con->arr[i].tel,
            con->arr[i].addr
        );
    }
} 

6.通讯录的删除 

//通讯录删除
//判断删除内容是否纯在
int Find_name(Contact* con, char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr->name, name) == 0)
		{
			//找到了,返回下标
			return i;
		}
	}
	//没有找到
	return -1;
}

void ContactDel(Contact* con)
{
	printf("请输入想要删除的姓名\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int find = Find_name(con, name);
	//进行判断
	if (find < 0)
	{
		//没有找到
		printf("您想要删除的联系人姓名不存在!\n");
		return;
	}
	else
		//找到了 
	{
		SLErase(con, find);
		printf("删除成功!\n");
	}

}

 7.通讯录的修改

//通讯录修改
void ContactMon(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入想要修改的姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		//没有找到
		printf("想要修改的姓名不存在!\n");
		return;
	}
	else
	{
		//想要修改的内容存在
		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].addr);
	}
}

 代码测试:

 8.通讯录的查找

在实现查找,可以使用前面现成的名字查找,方法与上面相似


//通讯录查找
void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入想要查找的姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		//没有找到
		printf("想要查找的姓名不存在!\n");
		return;
	}
	else
	{
		//找到 打印
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
			printf("%-4s %-4s %-4d %-4s %-4s\n",
				con->arr[find].name,
				con->arr[find].gender,
				con->arr[find].age,
				con->arr[find].tel,
				con->arr[find].addr
			);
	}
}

9.在test中制作简易菜单

这就是我们通讯录的大致框架,当然了还有许多可以添加的地方,我们的查找可以是姓名,性别,年龄,电话,地址,都可以,在这里我们可以在test中制作一些菜单等,方便我们使用,使用do while循环,switch语句

void menu()
{
	printf("****************简易通讯录**************\n");
	printf("******1.添加联系人******2.删除联系人****\n");
	printf("******3.修改联系人******4.查找联系人****\n");
	printf("******5.展示联系人******0.退出**********\n");
	printf("****************************************\n");

}


int main()
{
	Contact con;
	Contactinit(&con);//初始化
	int input = -1;
	
	do
	{
		menu();
		printf("请输入你的操作数\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			ContactAdd(&con);
			break;
		case 2:
			ContactDel(&con);
			break;
		case 3:
			ContactMon(&con);
			break;
		case 4:
			ContactFind(&con);
			break;
		case 5:
			ContactShow(&con);
			break;
		case 0:
			printf("退出程序中...");
			break;
		default:
			printf("输入操作数有误,请重新输入\n");
			break;
		}
		
	} while (input);
	ContactDestroy(&con);//通讯录销毁
	return 0;
}

接下来我们就可以测试整体代码了!

10.通讯录整体代码 

SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include "Contact.h"


//定义顺序表结构
typedef  PI SLDataType;//方便替换
typedef struct SeqList
{
	SLDataType* arr;
	int size;
	int capacity;
}SL;

//顺序表初始化
void SLinit(SL* ps);

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

//顺序表的头插和尾插
void SLPushBack(SL* ps, SLDataType x);//尾插
void SLPushFront(SL* ps, SLDataType x);//头插

//顺序表打印
void SLPrint(SL s);

//顺序表的头删和尾删
void SLPopBack(SL* ps);//尾删
void SLPopFront(SL* ps);//头删

//指定位置添加
void SLInsert(SL* ps, int pos, SLDataType x);

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


//顺序表的查找
int SLFind(SL* ps, SLDataType x);

SeqList.c 

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"

//顺序表初始化
void SLinit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}


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


void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		//增加容量
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);
		}
		//申请空间成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}
//顺序表的尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	//1.判断空间是否足够
	SLCheckCapacity(ps);
	//尾插
	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];//arr[1]=arr[0] 
	}
	ps->arr[0] = x;
	ps->size++;
}

顺序表打印
//void SLPrint(SL s)
//{
//	for (int i = 0; i < s.size; i++)
//	{
//		printf("%d ", s.arr[i]);
//	}
//	printf("\n");
//}

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);//判断指针是否为空
	assert(ps->arr);//判断数组是否为空
	ps->size--;
}


//头删
void SLPopFront(SL* ps)
{
	assert(ps);//判断指针是否为空
	assert(ps->arr);//判断数组是否为空
	for (int i = 0; i<ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i+1];//arr[0]=arr[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-1; 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.h 

#pragma once

#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 15
#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];
}PI;

//使用顺序表的增删查改,使用通讯录就是对顺序表进行操作
typedef struct SeqList Contact;

//方法声明

//通讯录初始化
void Contactinit(Contact* con);

//通讯录销毁
void ContactDestroy(Contact* con);

//通讯录添加数据
void ContactAdd(Contact* con);

//通讯录删除
void ContactDel(Contact* con);

//通讯录修改
void ContactMon(Contact* con);

//通讯录查找
void ContactFind(Contact* con);

//展示通讯录
void ContactShow(Contact* con);

Contact.c

#define _CRT_SECURE_NO_WARNINGS 1

#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)
{
	//输入要添加的数据
	PI pi;
	printf("请输入想要添加的姓名:\n");
	scanf("%s", pi.name);

	printf("请输入想要添加的性别:\n");
	scanf("%s", pi.gender);

	printf("请输入想要添加的年龄:\n");
	scanf("%d", &pi.age);

	printf("请输入想要添加的电话:\n");
	scanf("%s", pi.tel);

	printf("请输入想要添加的地址:\n");
	scanf("%s", pi.addr);
	//在顺序表中有头插,尾插,指定插入都可以使用
	SLPushBack(con, pi);
}

//通讯录删除
//判断删除内容是否纯在
int Find_name(Contact* con, char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->arr->name, name) == 0)
		{
			//找到了,返回下标
			return i;
		}
	}
	//没有找到
	return -1;
}

void ContactDel(Contact* con)
{
	printf("请输入想要删除的姓名\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int find = Find_name(con, name);
	//进行判断
	if (find < 0)
	{
		//没有找到
		printf("您想要删除的联系人姓名不存在!\n");
		return;
	}
	else
		//找到了 
	{
		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("%-4s %-4s %-4d %-4s %-4s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
		);
	}
}

//通讯录修改
void ContactMon(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入想要修改的姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		//没有找到
		printf("想要修改的姓名不存在!\n");
		return;
	}
	else
	{
		//想要修改的内容存在
		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].addr);
	}
}

//通讯录查找
void ContactFind(Contact* con)
{
	char name[NAME_MAX];
	printf("请输入想要查找的姓名:\n");
	scanf("%s", name);
	int find = Find_name(con, name);
	if (find < 0)
	{
		//没有找到
		printf("想要查找的姓名不存在!\n");
		return;
	}
	else
	{
		//找到 打印
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
			printf("%-4s %-4s %-4d %-4s %-4s\n",
				con->arr[find].name,
				con->arr[find].gender,
				con->arr[find].age,
				con->arr[find].tel,
				con->arr[find].addr
			);
	}
}

test.c 

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"

//SLtest()
//{
//	SL sl;
//	SLinit(&sl);
//	SLPushBack(&sl, 1);
//	SLPushBack(&sl, 2);
//	SLPushBack(&sl, 3);
//	SLPushBack(&sl, 4);
//	//SLPrint(sl);
//	/*SLPushFront(&sl, 5);
//	SLPrint(sl);*/
//	/*SLPopBack(&sl);
//	SLPrint(sl);*/
//	/*SLPopFront(&sl);
//	SLPrint(sl);*/
//	/*SLInsert(&sl, 3, 5);
//	SLPrint(sl);
//	SLErase(&sl, 3);
//	SLPrint(sl);*/
//	int find = SLFind(&sl, 3);
//	if (find > 0)
//	{
//		printf("找到了,下标为%d\n", find);
//	}
//	else
//	{
//		printf("没有找到\n");
//	}
//	SLDestroy(&sl);
//}

//void Contact01()
//{
//	Contact con;//创建通讯录对象
//	Contactinit(&con);
//	ContactAdd(&con);
//	ContactAdd(&con);
//	//ContactDel(&con);
//	//ContactMon(&con);
//	//ContactFind(&con);
//	ContactShow(&con);
//	ContactDestroy(&con);
//}
//
//int main()
//{
//	//SLtest();
//	Contact01();
//	return 0;
//}

void menu()
{
	printf("****************简易通讯录**************\n");
	printf("******1.添加联系人******2.删除联系人****\n");
	printf("******3.修改联系人******4.查找联系人****\n");
	printf("******5.展示联系人******0.退出**********\n");
	printf("****************************************\n");

}


int main()
{
	Contact con;
	Contactinit(&con);//初始化
	int input = -1;
	
	do
	{
		menu();
		printf("请输入你的操作数\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			ContactAdd(&con);
			break;
		case 2:
			ContactDel(&con);
			break;
		case 3:
			ContactMon(&con);
			break;
		case 4:
			ContactFind(&con);
			break;
		case 5:
			ContactShow(&con);
			break;
		case 0:
			printf("退出程序中...");
			break;
		default:
			printf("输入操作数有误,请重新输入\n");
			break;
		}
		
	} while (input);
	ContactDestroy(&con);//通讯录销毁
	return 0;
}

结语

通过对顺序表的实现,我们也学会了在顺序表的基础上实现通讯录,通讯使用的功能其实就是底层顺序表的增删查改功能,当然这段代码还有许多可以增加的地方,也会需要改进的地方,运用到了结构体,指针,动态内存的知识,有疑惑的友友可以看一下我的其他博客,有对结构体等知识的下详细介绍,希望对大家有一些帮助,如果哪里有错误请及时与我联系改正! 

  • 26
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
好的,以下是用 Python 数据结构顺序实现通讯录编辑代码: ```python class Contact: def __init__(self, name, phone): self.name = name self.phone = phone class ContactList: def __init__(self): self.contacts = [] def add_contact(self, name, phone): contact = Contact(name, phone) self.contacts.append(contact) def remove_contact(self, name): for contact in self.contacts: if contact.name == name: self.contacts.remove(contact) return def update_contact(self, name, phone): for contact in self.contacts: if contact.name == name: contact.phone = phone return def search_contact(self, name): for contact in self.contacts: if contact.name == name: return contact.phone def display_contacts(self): for contact in self.contacts: print(f"{contact.name}: {contact.phone}") contact_list = ContactList() while True: print("***************************") print("欢迎使用通讯录") print("1. 添加联系人") print("2. 删除联系人") print("3. 修改联系人") print("4. 查找联系人") print("5. 显示所有联系人") print("0. 退出程序") print("***************************") choice = int(input("请输入对应操作的数字:")) if choice == 0: break elif choice == 1: name = input("请输入联系人姓名:") phone = input("请输入联系人电话:") contact_list.add_contact(name, phone) print("联系人添加成功!") elif choice == 2: name = input("请输入要删除的联系人姓名:") contact_list.remove_contact(name) print("联系人删除成功!") elif choice == 3: name = input("请输入要修改的联系人姓名:") phone = input("请输入修改后的电话号码:") contact_list.update_contact(name, phone) print("联系人修改成功!") elif choice == 4: name = input("请输入要查找的联系人姓名:") phone = contact_list.search_contact(name) if phone: print(f"{name}的电话号码是:{phone}") else: print("联系人不存在!") elif choice == 5: contact_list.display_contacts() else: print("无效的选择,请重新输入!") ``` 这个程序中,我们定义了两个类:`Contact` 和 `ContactList`。`Contact` 类示一个联系人,包括姓名和电话号码;`ContactList` 类示一个通讯录,包含了添加联系人、删除联系人、修改联系人、查找联系人和显示所有联系人等操作。 在程序运行时,我们不断循环,根据用户输入的选择执行相应的操作。用户可以通过输入数字来选择不同的操作。每个操作都会调用 `ContactList` 中对应的方法来实现功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值