通过以上3节内容,让我们来实现一下用单链表的方式来实现通讯录
以下是我的代码
仅供大家参考!
1.SList.h
//SList.h
#include "Contact.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef struct personInfo SLTDataType;
typedef struct SListNode
{
struct personInfo a;
struct SListNode* next;
}SLTNode;
void SLTPrint(SLTNode* phead);
//尾插
void SLPushBack(SLTNode** pphead, SLTDataType x);
// 单链表查找
SLTNode* STFind(SLTNode* phead, SLTDataType x);
// 删除pos位置的值
void SLErase(SLTNode** pphead, SLTNode* pos);
//单链表销毁
void SListDesTroy(SLTNode** pphead);
2. SList.c
#include "SList.h"
//void SLTPrint(SLTNode* phead)
//{
// SLTNode* cur=phead;
// while(cur!=NULL)
// {
// printf("%d->",cur->a);
// cur=cur->next;
// }
// printf("NULL\n");
//
//}
//创建一个新的动态内存
SLTNode* BuyLTNode(SLTDataType x)
{
SLTNode * newnode=(SLTNode*)malloc(sizeof(SLTNode));
if(newnode==NULL)
{
perror("malloc fail");
return NULL;
}
newnode->a=x;
newnode->next=NULL;//初始化
return newnode;
}
//尾插
//第一个尾插需要二级指针,接下来就不用二级指针
//第一次是改变结构的指针plist
//第二次是改变结构体尾结点
void SLPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode *newnode= BuyLTNode(x);
//是否为空链表
if(*pphead==NULL) {
*pphead = newnode;//改变结构的指针plist
return;
}
else
{
SLTNode *tail=*pphead;
while(tail->next!=NULL)//找到链表最后一位,当tail->为空时,就把新开辟的链表节点接上去
tail=tail->next;
tail->next=newnode;//改变结构体尾结点
//就是把newnode存放的新结点地址给tail->next,然后在存放在之前最后一个结点的struct SListNode* next;中,这样next指向的地址不是NULL,而是新加的结点的位置
//不能用tail=newnode,因为tail和newnode是局部变量,当这函数结束后就释放了
}
}
//头删
void SLPopFront(SLTNode** pphead)
{
//空链表
assert(*pphead);
// //一个结点
// if((*pphead)->next==NULL)
// {
// free(*pphead);
// *pphead=NULL;
// }
// //多个结点
// else
// {
// SLTNode *del=*pphead;
// //*pphead=del->nest;
// *pphead=(*pphead)->next;
// free(del);
// }
SLTNode* del = *pphead;
*pphead = (*pphead)->next;
free(del);
}
// 删除pos位置的值
void SLErase(SLTNode** pphead, SLTNode* pos)
{
assert(pphead);
assert(pos);
//如果只有一个结点
if(pos==*pphead)
SLPopFront(pphead);
else
{
SLTNode *p1=*pphead;
while(p1->next!=pos)
p1=p1->next;
p1->next=pos->next;
free(pos);
}
}
//单链表销毁
void SListDesTroy(SLTNode** pphead)
{
assert(pphead && *pphead );
SLTNode *pcur=*pphead;
while(pcur)
{
SLTNode *next=pcur->next;
free(pcur);
pcur=next;
}
*pphead=NULL;
}
3. Contact.h
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#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];
}PeoInfo;
//要用到顺序表相关的方法,对通讯录的操作实际就是对链表进行操作
//给链表改个名字,叫做通讯录
typedef struct SListNode contact;
//初始化通讯录
void InitContact(contact** con);
//添加通讯录数据
void AddContact(contact** con);
//删除通讯录数据
void DelContact(contact** con);
//展⽰通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//销毁通讯录数据
void DestroyContact(contact** con);
4.Contact.c
#include "Contact.h"
#include "SList.h"
#include <string.h>
void AddContact(contact** con) {
SLTDataType 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.addr);
SLPushBack(con, info);
printf("插⼊成功!\n");
}
contact* FindByName(contact* con, char name[]) {
contact* cur = con;
while (cur)
{
if (strcmp(cur->a.name, name) == 0) {
return cur;
}
cur = cur->next;
}
return NULL;
}
void DelContact(contact** con) {
char name[NAME_MAX];
printf("请输⼊要删除的⽤⼾姓名:\n");
scanf("%s", name);
contact* pos = FindByName(*con, name);
if (pos == NULL) {
printf("要删除的⽤⼾不存在,删除失败!\n");
return;
}
SLErase(con, pos);
printf("删除成功!\n");
}
void ShowContact(contact* con) {
printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "联系电话","地址");
contact* cur = con;
while (cur)
{
printf("%s %s %d %s %s\n",
cur->a.name,
cur->a.gender,
cur->a.age,
cur->a.tel,
cur->a.addr);
cur = cur->next;
}
}
void FindContact(contact* con) {
char name[NAME_MAX];
printf("请输⼊要查找的⽤⼾姓名:\n");
scanf("%s", name);
contact* pos = FindByName(con, name);
if (pos == NULL) {
printf("要查找的⽤⼾不存在,查找失败!\n");
return;
}
printf("查找成功!\n");
printf("%-10s %-4s %-4d %15s %-20s\n",
pos->a.name,
pos->a.gender,
pos->a.age,
pos->a.tel,
pos->a.addr);
}
void ModifyContact(contact* con) {
char name[NAME_MAX];
printf("请输⼊要修改的⽤⼾名称:\n");
scanf("%s", name);
contact* pos = FindByName(con, name);
if (pos == NULL) {
printf("要查找的⽤⼾不存在,修改失败!\n");
return;
}
printf("请输⼊要修改的姓名:\n");
scanf("%s", pos->a.name);
printf("请输⼊要修改的性别:\n");
scanf("%s", pos->a.gender);
printf("请输⼊要修改的年龄:\n");
scanf("%d", &pos->a.age);
printf("请输⼊要修改的联系电话:\n");
scanf("%s", pos->a.tel);
printf("请输⼊要修改的地址:\n");
scanf("%s", pos->a.addr);
printf("修改成功!\n");
}
void DestroyContact(contact** con) {
SListDesTroy(con);
}
5. Text.c
#include "SList.h"
void menu()
{
printf("**************通讯录*****************\n");
printf("******1.增加联系人 2.删除联系人******\n");
printf("******3.修改联系人 4.查找联系人******\n");
printf("******5.展示联系人 0. 退出 ******\n");
printf("************************************\n");
}
int main()
{
int select=0;
contact *con=NULL;
do{
menu();
printf("请选择您的操作:\n");
scanf("%d",&select);
switch (select) {
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
ModifyContact(con);
break;
case 4:
FindContact(con);
break;
case 5:
ShowContact(con);
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新选择您的操作!\n");
break;
}
}while(select!=0);
DestroyContact(&con);
return 0;
}