关于单链表的详细了解请见博主的另一篇博客,本文旨在对单链表进行应用,采用C语言编写。
一、驱动层
1.1 SList.h
cpp
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
#include<string.h>
typedef peoInfo SLTDataType;
typedef struct SlistNode
{
SLTDataType data;
struct SlistNode* next;
}SLTNode;
//链表销毁
void SLTDestory(SLTNode** pphead);
// 尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
// 头删
void SLTPopFront(SLTNode** pphead);
// 删除指定位置的节点
void SLTDelete(SLTNode** pphead, SLTNode* pos);
1.2 SList.c
cpp
#include"SList.h"
//为避免重复无意义的操作,封装函数实现
SLTNode* SLTBuyNode(SLTDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if (newnode == NULL)
{
perror("malloc");
exit(1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
// 尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = SLTBuyNode(x);
//判断是否为空节点
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
//找尾节点
SLTNode* ptail = *pphead;
while (ptail->next)
{
ptail = ptail->next;
}
ptail->next = newnode;
}
}
//头删
void SLTPopFront(SLTNode** pphead)
{
assert(pphead);
assert(*pphead);
//链表只有一个节点
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
SLTNode* phead = *pphead;
*pphead = (*pphead)->next;
free(phead);
}
}
// 删除指定位置的节点
void SLTDelete(SLTNode** pphead, SLTNode* pos)
{
assert(pphead && *pphead);
assert(pos);
SLTNode* prev = *pphead;
if (*pphead == pos) //如果是头节点
{
SLTPopFront(pphead);
}
else
{
//寻找前一个节点
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
}
//链表销毁
void SLTDestory(SLTNode** pphead)
{
assert(pphead);
SLTNode* pcur = *pphead;
while (pcur)
{
SLTNode* temp = pcur->next;
free(pcur);
pcur = temp;
}
*pphead = NULL;
}
二、调用层
2.1 Contact.h
cpp
#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100
//用户数据
typedef struct PersonInfo
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}peoInfo;
typedef struct SlistNode Contact;
//添加通讯录数据
void ContactAdd(Contact** con);
//删除通讯录数据
void ContactDel(Contact** con);
//展示通讯录数据
void ContactShow(Contact* con);
//查找通讯录数据
void ContactFind(Contact* con);
//修改通讯录数据
void ContactModify(Contact** con);
//销毁通讯录数据
void ContactDestroy(Contact** con);
2.2 Contact.c
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"
#include<string.h>
Contact* FindByname(Contact* con, char* cmp)
{
Contact* pcur = con;
while (pcur)
{
if (strcmp(pcur->data.name,cmp) == 0)
{
return pcur;
break;
}
pcur = pcur->next;
}
return NULL;
}
//添加通讯录数据
void ContactAdd(Contact** con)
{
peoInfo 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);
SLTPushBack(con, info);
}
//删除通讯录数据
void ContactDel(Contact** con)
{
char name[NAME_MAX];
printf("请输入要删除的联系人姓名\n");
scanf("%s", name);
Contact* ret = FindByname(*con, name);
if (ret != NULL)
{
SLTDelete(con, ret);
printf("删除成功!\n");
}
else
{
printf("数据不存在!\n");
return;
}
}
//展示通讯录数据
void ContactShow(Contact* con)
{
Contact* pcur = con;
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
while (pcur)
{
printf("%s ", pcur->data.name);
printf("%s ", pcur->data.sex);
printf("%d ", pcur->data.age);
printf("%s ", pcur->data.tel);
printf("%s ", pcur->data.addr);
printf("\n");
pcur = pcur->next;
}
}
//查找通讯录数据
void ContactFind(Contact* con)
{
assert(con);
char name[NAME_MAX];
printf("请输入要查找的联系人姓名\n");
scanf("%s", name);
Contact* ret = FindByname(con, name);
if (ret != NULL)
{
printf("查找成功!\n");
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%s ", ret->data.name);
printf("%s ", ret->data.sex);
printf("%d ", ret->data.age);
printf("%s ", ret->data.tel);
printf("%s ", ret->data.addr);
printf("\n");
}
else
{
printf("数据不存在!\n");
return;
}
}
//修改通讯录数据
void ContactModify(Contact** con)
{
char name[NAME_MAX];
printf("请输入要修改的联系人姓名\n");
scanf("%s", name);
Contact* ret = FindByname(*con, name);
if (ret != NULL)
{
printf("请输入新的联系人姓名\n");
scanf("%s", ret->data.name);
printf("请输入新的联系人性别\n");
scanf("%s", ret->data.sex);
printf("请输入新的联系人年龄\n");
scanf("%d", &(ret->data.age));
printf("请输入新的联系人电话\n");
scanf("%s", ret->data.tel);
printf("请输入新的联系人住址\n");
scanf("%s", ret->data.addr);
printf("修改成功!\n");
}
else
{
printf("数据不存在!\n");
return;
}
}
//销毁通讯录数据
void ContactDestroy(Contact** con)
{
SLTDestory(con);
}
三、主函数
3.1 main.c
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"SList.h"
#include"Contact.h"
void menu()
{
printf("******************通讯录******************\n");
printf("*******1.增加联系人 2.删除联系人********\n");
printf("*******3.修改联系人 4.查找联系人********\n");
printf("*******5.展示联系人 0. 退出 *********\n");
printf("******************************************\n");
}
int main()
{
int a = -1;
SLTNode* con = NULL;
do {
menu();
printf("请选择您的操作:\n");
scanf("%d", &a);
switch (a)
{
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("退出通讯录....\n");
break;
default:
printf("输入错误,请重新选择您的操作!\n");
break;
}
} while (a != 0);
ContactDestroy(&con);
return 0;
}