用单链表实现通讯录(c语言)

 本文中的代码都在Visual Studio(版本为2022)软件中运行,在使用scanf函数记得在第一行写下面的代码:

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

//定义结构体中各类型变量的大小
#define NAME_MAX 20                
#define GENDER_MAX 5
#define PHONE_MAX 11
#define ADDRESS_MAX 100

//存放联系人信息的结构体
struct PersonalInformation
{
	char name[NAME_MAX];
	char gender[GENDER_MAX];
	int age;
	char phone[PHONE_MAX];
	char address[ADDRESS_MAX];
};

typedef struct PersonalInformation SLTDataType;        //为 struct PersonalInformation起一个别名PI

//存放节点的结构体
struct SingleLinkedListNode
{
	SLTDataType data;  //存放个人信息
	struct SingleLinkedListNode* next;  //存放下一个节点的地址
};

typedef struct SingleLinkedListNode SLTNode;         //为struct SingleLinkedListNode SLTNode起一个别名SLTNode

//添加联系人的信息
void AddContact(SLTNode** pphead)   //pphead存放的是一级指针的地址,*pphead是一级指针存放的地址,**pphead是一级指针存放的地址中的值
{
	assert(pphead);       //判断二级指针是否为空

	SLTNode* temp = (SLTNode*)malloc(sizeof(SLTNode));  //创建指向节点的指针变量
	if (temp == NULL)
	{
		perror("申请空间失败");
		exit(1);
	}
	SLTNode* newNode = temp;
	printf("请输入联系人的名字:");
	scanf("%s", newNode->data.name);
	printf("请输入联系人的性别:");
	scanf("%s", newNode->data.gender);
	printf("请输入联系人的年龄:");
	scanf("%d", &newNode->data.age);
	printf("请输入联系人的电话号码:");
	scanf("%s", newNode->data.phone);
	printf("请输入联系人的地址:");
	scanf("%s", newNode->data.address);
	newNode->next = NULL;

	if (*pphead == NULL)    //创建的节点为第一个节点
	{
		*pphead = newNode;
		printf("添加成功\n");
		return;
	}

	SLTNode* pcur = *pphead;	 //创建的节点不是第一个节点
	while (pcur->next != NULL)
	{
		pcur = pcur->next;
	}
	pcur->next = newNode;
	printf("添加成功\n");

}

//在进行删除和修改之前,通过名字查找
int ByNameSearch(SLTNode* phead)
{
	char name[NAME_MAX] = "";
	printf("请输入你要查找或修改的名字:");
	scanf("%s", name);
	SLTNode* pcur = phead;
	int count = 0;  //执行while循环中代码的次数,方便后续进行删除和修改操作。
	//若pcur指向第n个节点,则count的值为n - 1;
	while (pcur != NULL)
	{
		if (strcmp(pcur->data.name, name) == 0)
		{
			return count;
		}
		pcur = pcur->next;
		count++;
	}
	return -1;
}

//删除联系人的信息
void DeleteContact(SLTNode** pphead)
{
	assert(pphead);
	if (*pphead == NULL)
	{
		printf("通讯录中没有联系人的信息,无法删除");
		return;
	}

	int num = ByNameSearch(*pphead);  //根据返回值判断通讯录中是否有要删除的联系人的信息
	if (num == -1)
	{
		printf("没有此人的联系信息,无法删除\n");
	}
	else
	{
		if (num == 0)        //要删除的节点为第一个节点(联系人的信息)
		{
			if ((*pphead)->next != NULL)         //通讯录中有1个以上的节点(联系人的信息)
			{
				SLTNode* temp = *pphead;
				(*pphead) = (*pphead)->next;
				free(temp);						//用free函数,释放由malloc函数申请的空间(malloc函数申请的空间需要手动释放)
				temp = NULL;					//将指针temp置为NULL,避免指针temp成为野指针
				printf("删除成功\n");
				return;
			}
			else
			{
				free(*pphead);					//通讯录中只有一个节点(联系人的信息)
				*pphead = NULL;
				printf("删除成功\n");
				printf("通讯录中已无联系人的信息\n");
				return;
			}
		}
		else							//要删除的节点不是第一个节点(联系人的信息)
		{
			SLTNode* pcur = *pphead;    //定义指针变量用于找到并删除节点
			SLTNode* prev = *pphead;	//定义指针变量用于将要删除节点之前的节点和之后的节点连接起来
			while (num != 0)
			{
				prev = pcur;
				pcur = pcur->next;
				num--;
			}
			if (pcur->next == NULL)   //要删除的节点是尾节点
			{
				prev->next = NULL;
				printf("删除成功\n");
				free(pcur);
				pcur = NULL;
				return;
			}
			else                      //要删除的节点不是尾节点
			{
				prev->next = pcur->next;
				printf("删除成功\n");
				free(pcur);
				pcur = NULL;
				return;
			}
		}
	}
}

//查找联系人的信息
void SearchContact(SLTNode** pphead)
{
	assert(pphead);
	if (*pphead == NULL)
	{
		printf("通讯录中已无信息,无法查询");
		return;
	}
	char phone[PHONE_MAX] = "";
	printf("请输入你要查询的联系人的电话号码:");
	scanf("%s", phone);
	SLTNode* pcur = *pphead;
	while (pcur != NULL)
	{
		if (strcmp(pcur->data.phone, phone) == 0)
		{
			printf("%-7s %-7s %-7s %-20s %-30s\n", "姓名", "性别", "年龄", "电话号码", "地址");
			printf("%-8s", pcur->data.name);
			printf("%-8s", pcur->data.gender);
			printf("%-8d", pcur->data.age);
			printf("%-21s", pcur->data.phone);
			printf("%-30s\n", pcur->data.address);
			return;
		}
		pcur = pcur->next;
	}
	printf("没有此电话号码的联系人,无法查找\n");

}

//修改联系人的信息
void ModifyContact(SLTNode** pphead)
{
	assert(pphead);
	if (*pphead == NULL)
	{
		printf("通讯录中已无信息,无法修改");
		return;
	}

	char phone[PHONE_MAX] = "";
	printf("请输入你要修改的联系人的电话号码:");
	scanf("%s", phone);
	SLTNode* pcur = *pphead;
	while (pcur != NULL)
	{
		if (strcmp(pcur->data.phone, phone) == 0)
		{
			printf("请输入修改后的姓名:");
			scanf("%s", pcur->data.name);
			printf("请输入修改后的性别:");
			scanf("%s", pcur->data.gender);
			printf("请输入修改后的年龄:");
			scanf("%d", &pcur->data.age);
			printf("请输入修改后的电话号码:");
			scanf("%s", pcur->data.phone);
			printf("请输入修改后的地址:");
			scanf("%s\n", pcur->data.address);
			printf("修改成功\n");
			return;
		}
		pcur = pcur->next;
	}
	printf("没有此电话号码的联系人,无法修改\n");

}

//展示联系人的信息
void DisplayContact(SLTNode** pphead)
{
	assert(pphead);
	if (*pphead == NULL)
	{
		printf("通讯录中已无信息,无法展示\n");
	}
	else
	{
		printf("%-7s %-7s %-7s %-20s %-30s\n", "姓名", "性别", "年龄", "电话号码", "地址");
		SLTNode* pcur = *pphead;
		while (pcur != NULL)
		{
			//调整展示通讯录信息的格式
			printf("%-8s", pcur->data.name);
			printf("%-8s", pcur->data.gender);
			printf("%-8d", pcur->data.age);
			printf("%-21s", pcur->data.phone);
			printf("%-30s\n", pcur->data.address);
			pcur = pcur->next;
		}
	}

}

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

int main()
{
	SLTNode* contact = NULL;
	int option = -1;
	do
	{
		menu();
		printf("请输入你要选择的数字:");
		scanf("%d", &option);
		switch (option)
		{
		case 1:
			AddContact(&contact);       //添加联系人的信息
			break;
		case 2:
			DeleteContact(&contact);    //删除联系人的信息
			break;
		case 3:
			SearchContact(&contact);     //查找联系人的信息
			break;
		case 4:
			ModifyContact(&contact);     //修改联系人的信息
			break;
		case 5:
			DisplayContact(&contact);    //展示联系人的信息
			break;
		case 0:
			printf("退出成功");
			break;
		default:
			printf("输入错误,请重新选择\n");
		}
	} while (option != 0);      //option为0时,循环才终止

	return 0;
}

个人总结:

①创建存放联系人信息的结构体。
②创建节点结构体,成员为存放联系人信息的结构体和指向下一个节点结构体的结构体指针。
③通讯录中的功能有添加联系人、删除联系人信息、查找联系人信息、修改联系人信息、展示联系人信息,故可用菜单、switch语句和一个整型变量来判断执行哪个函数(实现某一功能)再用上do while循环就能实现对选择功能的循环,直到选择的数字为0时退出循环

④编写实现各种功能的函数

⑤测试运行

注意:在实现某一功能后,应先调试,然后再编写代码。

AI实战-学生生活方式模式数据集分析预测实例(含24个源代码+69.54 KB完整的数据集) 代码手工整理,无语法错误,可运行。 包括:24个代码,共149.89 KB;数据大小:1个文件共69.54 KB。 使用到的模块: pandas os matplotlib.pyplot seaborn plotly.express warnings sklearn.model_selection.StratifiedShuffleSplit sklearn.pipeline.Pipeline sklearn.compose.ColumnTransformer sklearn.impute.SimpleImputer sklearn.preprocessing.OrdinalEncoder numpy sklearn.model_selection.cross_val_score sklearn.linear_model.LinearRegression sklearn.metrics.mean_squared_error sklearn.tree.DecisionTreeRegressor sklearn.ensemble.RandomForestRegressor sklearn.model_selection.train_test_split sklearn.preprocessing.PowerTransformer imblearn.pipeline.Pipeline imblearn.over_sampling.SMOTE sklearn.ensemble.AdaBoostClassifier sklearn.metrics.accuracy_score sklearn.metrics.precision_score sklearn.metrics.recall_score sklearn.metrics.f1_score optuna scipy.stats torch torch.nn torchvision.transforms torchvision.models torch.optim cv2 glob glob.glob torch.utils.data.DataLoader torch.utils.data.Dataset random.shuffle torch.utils.data.random_split torchsummary.summary matplotlib.ticker pyspark.sql.SparkSession pyspark.sql.functions.count pyspark.sql.functions.max pyspark.sql.functions.min pyspark.sql.functions.avg pyspark.sql.functions.stddev_samp pyspark.sql.functions.skewness pyspark.sql.functions.kurtosis pyspark.sql.functions pyspark.ml.feature.Tokenizer pyspark.ml.feature.VectorAssembler sklearn.preprocessing.LabelEncoder keras.models.Sequential keras.layers.Dense keras.utils.to_categorical ptitprince statsmodels.distributions.empirical_distribution.ECDF statsmodels.stats.outliers_influence.variance_inflation_factor ppscore sklearn.feature_selection.mutual_info_classif sklearn.decomposition.PCA sklearn.model_selection.StratifiedKFold sklearn.tree.DecisionTreeClassifier sklearn.metrics.balanced_accuracy_score sklearn.metrics.confusion_matrix mlxtend.plotting.plot_confusion_matrix scipy.stats.pearsonr scipy.stats.f_oneway sklearn.feature_selection.mutual_info_regression sklearn.feature_selecti
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值