一、准备知识
主要的就是单链表相关的知识,我们在之前已经实现过了基于顺序表的通讯录,这里我们新学习了单链表,我们用单链表实现一下通讯录项目 需要的内容:单链表,指针,循环,结构体等知识
二、写之前的思路
我们需要一个单链表文件,在这里我给它们分别命名为project.h和project.c,然后是通讯录文件tel.h和tel.c,最后就是测试文件test.c 单链表文件我们就不必多说了,上篇博文中有,这里我们直接将上篇博文中的内容复制粘贴过来了,主要来实现通讯录
project.h
代码语言:javascript复制#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "tel.h"
typedef PeoInfo SLTDataType;
typedef struct SListNode
{
SLTDataType* data; //节点数据
struct SListNode* next; //指针保存下?个节点的地址
}SLTNode;
//打印
void SLTPrint(SLTNode* phead);
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);
//尾删
void SLTPopBack(SLTNode** pphead);
//头删
void SLTPopFront(SLTNode** pphead);
//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);
//在指定位置之后插?数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos);
//销毁链表
void SListDesTroy(SLTNode** pphead);
//创建节点
SLTNode* SLTBuyNode(SLTDataType x);
project.c
代码语言:javascript复制#include "project.h"
//打印
void SLTPrint(SLTNode* phead)
{
assert(phead);
SLTNode* pur = phead;
while (pur)
{
printf("%s ", pur->data->name);
printf("%s ", pur->data->sex);
printf("%d ", pur->data->age);
printf("%s ", pur->data->tel);
printf("%s ", pur->data->addr);
printf("n");
pur = pur->next;
}
}
//创建节点
SLTNode* SLTBuyNode(SLTDataType x)
{
SLTNode* newcode = (SLTNode*)malloc(sizeof(SLTNode));
if (newcode == NULL)
{
perror("malloc fail");
exit(1);
}
*newcode->data = x;
newcode->next = NULL;
return newcode;
}
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* new = SLTBuyNode(x);
if (*pphead == NULL)
{
*pphead = new;
}
else
{
SLTNode* pur = *pphead;
while (pur->next)
{
pur = pur->next;
}
pur->next = new;
}
}
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* new = SLTBuyNode(x);
new->next = *pphead;
*pphead = new;
}
void SLTPopBack(SLTNode** pphead)
{
assert(pphead && *pphead);
SLTNode* pur = *pphead;
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
SLTNode* prev = *pphead;
SLTNode* ptail = *pphead;
while (ptail->next)
{
prev = ptail;
ptail = ptail->next;
}
prev->next = NULL;
ptail = NULL;
free(ptail);
}
}
//头删
void SLTPopFront(SLTNode** pphead)
{
assert(pphead && *pphead);
SLTNode* node = (*pphead)->next;
(*pphead)->next = NULL;
free(*pphead);
*pphead = node;
}
//指定位置前插
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
assert(pphead && *pphead);
assert(pos);
SLTNode* pur = *pphead;
SLTNode* new = SLTBuyNode(x);
if (*pphead == pos)
{
SLTPushFront(pphead, x);
}
else
{
while (pur->next != pos)
{
pur = pur->next;
}
new->next = pos;
pur->next = new;
}
}
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
assert(*pphead);
if (*pphead == pos)
{
SLTNode* prev = *pphead;
*pphead = (*pphead)->next;
free(prev);
}
else
{
SLTNode* pur = *pphead;
while (pur->next != pos)
{
pur = pur->next;
}
SLTNode* pucr = pos->next;
pur->next = pucr;
pos->next = NULL;
free(pos);
}
}
//在指定位置后插入节点
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
SLTNode* new = SLTBuyNode(x);
SLTNode* pur = pos->next;
pos->next = new;
new->next = pur;
}
//删除pos后边这个节点
void SLTEraseAfter(SLTNode* pos)
{
SLTNode* pur = pos->next;
SLTNode* pucr = pur->next;
pos->next = pucr;
pur->next = NULL;
free(pur);
}
//销毁链表
void SListDesTroy(SLTNode** pphead)
{
SLTNode* pur = *pphead;
while ((*pphead)->next != NULL)
{
pur = *pphead;
*pphead = (*pphead)->next;
pur->next = NULL;
free(pur);
}
free(*pphead);
}
tel.h
代码语言:javascript复制#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100
//前置声明
typedef struct SListNode contact;
//用户数据
typedef struct PersonInfo
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}PeoInfo;
//初始化通讯录
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);
tel.c
代码语言:javascript复制#include "tel.h"
#include "project.h"
//初始化通讯录
void InitContact(contact** con)
{
*con = (contact*)malloc(sizeof(contact));
if (*con == NULL)
return;
(*con)->data = NULL;
(*con)->next = NULL;
}
//添加通讯录数据
void AddContact(contact** con)
{
PeoInfo* i = (PeoInfo*)malloc(sizeof(PeoInfo));//定义一个通讯录用户
if (i == NULL)
{
return;
}
printf("请输入联系人姓名:n");
scanf("%s", i->name);
printf("请输入联系人性别:n");
scanf("%s", i->sex);
printf("请输入联系人年龄:n");
scanf("%d", &i->age);
printf("请输入联系人电话:n");
scanf("%s", i->tel);
printf("请输入联系人地址:n");
scanf("%s", i->addr);
printf("添加成功!n");
contact* newcode = (contact*)malloc(sizeof(contact));
if (newcode == NULL)
{
perror("malloc fail");
exit(1);
}
contact* pur = *con;
while (pur->next)
{
pur = pur->next;
}
newcode->data = i;
pur->next = newcode;
newcode->next = NULL;
}
//删除通讯录数据
void DelContact(contact** con)
{
contact* n = (*con)->next;
contact* prev = NULL;
char name[NAME_MAX];
printf("请输入你要删除的联系人:n");
scanf("%s", name);
if (strcmp(n->data->name, name) == 0 && n)
{
*con = n->next;
free(n);
return;
}
while (strcmp(n->data->name, name) && n)
{
prev = n;
n = n->next;
}
if (n == NULL)
{
printf("不存在这个数据n");
}
else
{
if (prev == NULL) // 如果要删除的是头节点
{
*con = n->next; // 更新头指针
}
else
{
prev->next = n->next;
free(n->data);
free(n);
printf("删除成功!n");
}
}
}
//展示所有通讯录数据
void ShowContact(contact* con)
{
assert(con);
contact* pur = con->next;
while (pur != NULL)
{
printf("%5s %5s %5s %5s %5sn", "姓名","性别","年龄","电话","地址");
printf("%5s ", pur->data->name);
printf("%5s ", pur->data->sex);
printf("] ", pur->data->age);
printf("%5s ", pur->data->tel);
printf("%5s ", pur->data->addr);
printf("n");
pur = pur->next;
}
}
//查找通讯录数据
void FindContact(contact* con)
{
char name[NAME_MAX];
printf("请输入要查找人的姓名:n");
scanf("%s", name);
contact* n = con->next;
while (strcmp(n->data->name, name) && n)
{
n = n->next;
}
if (n == NULL)
{
printf("此用户不存在!n");
return;
}
printf("被查找到人的信息:n");
printf("%5s %5s %5s %5s %5sn", "姓名","性别","年龄","电话","地址");
printf("%5s ", n->data->name);
printf("%5s ", n->data->sex);
printf("] ", n->data->age);
printf("%5s ", n->data->tel);
printf("%5s ", n->data->addr);
printf("n");
}
//修改通讯录数据
void ModifyContact(contact** con)
{
char name[NAME_MAX];
printf("请输入你要修改对象的原姓名:n");
scanf("%s", name);
contact* n = (*con)->next;
while (strcmp(n->data->name, name) && n)
{
n = n->next;
}
if (n == NULL)
{
printf("此用户不存在!n");
return;
}
printf("请输入你要修改对象的姓名:n");
scanf("%s", n->data->name);
printf("请输入你要修改对象的性别:n");
scanf("%s", n->data->sex);
printf("请输入你要修改对象的年龄:n");
scanf("%d", &n->data->age);
printf("请输入你要修改对象的电话:n");
scanf("%s", n->data->tel);
printf("请输入你要修改对象的地址:n");
scanf("%s", n->data->addr);
printf("修改成功!n");
}
//
//销毁通讯录数据
void DestroyContact(contact** con)
{
SListDesTroy(con);
}
test.c
代码语言:javascript复制#include "tel.h"
void test1()
{
contact* s1;
InitContact(&s1);
AddContact(&s1);
ShowContact(s1);
AddContact(&s1);
ShowContact(s1);
/*AddContact(&s1);
ShowContact(s1);
DelContact(&s1);
ShowContact(s1);*/
//FindContact(s1);
ModifyContact(&s1);
ShowContact(s1);
DestroyContact(&s1);
}
int main()
{
test1();
return 0;
}
调试结果
今天的分享就到这里了~