数据结构—单链表实现通讯录

通过以上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;
}
相关推荐
pianmian11 小时前
python数据结构基础(7)
数据结构·算法
好奇龙猫3 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
sp_fyf_20244 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
ChoSeitaku4 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程4 小时前
双向链表专题
数据结构
香菜大丸4 小时前
链表的归并排序
数据结构·算法·链表
jrrz08284 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time4 小时前
golang学习2
算法
@小博的博客4 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生5 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法