单链表实现通讯录(增删查改)

news2024/11/15 14:10:05

前言

之前写了很多次通讯录,一次比一次复杂,从静态到动态,再到文件操作,再到顺序表,今天要好好复习一下单链表,于是乎干脆用单链表再写一遍。

首先我们之前已经用单链表写过他的增删查改了,于是乎,我们应该在此基础之上进行修改,而不是从头开始写,先把之前的增删查改拿出来

<<<<<<<<<——王子公主请看——>>>>>>>>>>>

SLT.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"contact.h"
typedef PeoInfo SLTDataType;
typedef struct SListNode
{
    SLTDataType val;
    struct SListNode* next;
}SLTNode;

//打印数据内容
//void SLTPrint(SLTNode* phead);
//创建对应类型变量
 SLTNode* creat(SLTDataType  x);
//头部插入删除/尾部插入删除
void SLTPushBack(SLTNode** pphead, SLTDataType x);
void SLTPushFront(SLTNode** pphead, SLTDataType x);
void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);

查找
//SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
//在指定位置之前插入数据
void SLTInsertFront(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 SLTDesTroy(SLTNode** pphead);

SLT.c

#include"SLT.h"
//SLTNode* creat(SLTDataType  x)
//{
//    SLTNode* p = malloc(sizeof(SLTNode));
//    p->val = x;
//    p->next = NULL;
//    return p;
//}
SLTNode* creat(SLTDataType  x)
{
    SLTNode* p = malloc(sizeof(SLTNode));
    p->val = x;
    p->next = NULL;
    return p;
}
//void SLTPrint(SLTNode* phead)
//{
//    while (phead)
//    {
//        printf("%d  ", phead->val);
//        phead = phead->next;
//    }
//    puts("");
//}

//尾部插入
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
    assert(pphead);
        if (*pphead == NULL)
        *pphead = creat(x);
        else
        {
            while ((*pphead)->next)
            {
                *pphead = (*pphead)->next;
            }
            (*pphead)->next = creat(x);
        }
}
//头部插入
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
    assert(pphead);
    if (*pphead == NULL)
        if (*pphead == NULL)
            *pphead = creat(x);
        else
        {
            SLTNode* new = (*pphead);
            *pphead = creat(x);
            (*pphead)->next = new;
        }
}
//尾部删除
void SLTPopBack(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);
    if (((*pphead)->next) == NULL)
        *pphead= NULL;
    else
    {
        while ((*pphead)->next->next)
        {
            (*pphead) = (*pphead)->next;
        }
        free((*pphead)->next);
        (*pphead)->next = NULL;
    }
}
//头部删除
void SLTPopFront(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);
    SLTNode* new = (*pphead)->next;
    free(*pphead);
    *pphead = new;
}
//查找
//SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
//{
//    while (phead&&phead->val != x)
//        phead = phead->next;
//    if (phead == NULL)
//    {
//        printf("你要找的内容不存在\n");
//        return 0;
//    }
//    return phead;
//}
//在指定位置之前插入数据
void SLTInsertFront(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
    assert(pphead);
    assert(*pphead);
    assert(pos);
    if ((*pphead) == pos)
    {
        *pphead = creat(x);
        (*pphead)->next = pos;
    }
    else
    {
        while ((*pphead)->next != pos)
        {
            *pphead = (*pphead)->next;
        }
        SLTNode* new = (*pphead)->next;//不对劲!!!!!!
        (*pphead)->next = creat(x);
        (*pphead)->next->next = pos;
    }
}
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
    assert(pphead);
    assert(*pphead);
    if (*pphead == pos)
    {
        free(pos);
        *pphead = NULL;
    }
    else
    {
        while ((*pphead)->next != pos)
            *pphead = (*pphead)->next;
        (*pphead)->next = (*pphead)->next->next;
        free(pos);
        pos = NULL;
    }
}
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
    assert(pos);
    SLTNode* new = pos->next;
    pos->next = creat(x);
    pos->next->next = new;
}
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos)
{
    assert(pos);
    SLTNode* new = pos->next;
    pos->next = pos->next->next;
    free(new);
}

//销毁链表

void SLTDesTroy(SLTNode** pphead)
{
    assert(pphead);
    while (*pphead != NULL)
    {
        SLTNode* p = (*pphead)->next;
        free(*pphead);
        *pphead = p;
    }
}

 contact.h

#pragma once
#define NAME_MAX 100
#define SEX_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
struct SListNode;
//前置声明
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;
typedef PeoInfo SLTDataType;
//创建对应数据类型
contact* creatt(void);
//初始化通讯录
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);

contact.c

#include"SLT.h"

SLTNode* creatt(void)
{
    SLTDataType a;
    printf("输入名字\n");
    gets(a.name);
    printf("输入地址\n");
    gets(a.addr);
    printf("输入性别\n");
    gets(a.sex);
    printf("输入电话\n");
    gets(a.tel);
    printf("输入年龄\n");
    scanf("%d", &a.age);
    getchar();
    SLTNode*p= creat(a);
    return p;
};
//初始化通讯录
void InitContact(contact** con)
{
  /*  FILE*p=fopen("contact", "rb");*/
        *con = (contact*)malloc(sizeof(contact));
     /*   contact* new = con;
        if (p != NULL)
           do
            {
                contact* ps = (contact*)(sizeof(contact));
                if (fread(ps, sizeof(contact), 1, p))
                    new->next = ps;
            }*/
}
//添加通讯录数据
void AddContact(contact** con)
{
    *con = creatt();
}
//删除通讯录数据
void DelContact(contact** con)
{
    SLTPopBack(con);
}
//展示通讯录数据
void ShowContact(contact* con)
{
    printf("姓名\t地址\t性别\t电话\t年龄\n");
    while (con)
    {
        printf("%s  \t", con->val.name);
        printf("%s  \t", con->val.addr);
        printf("%s  \t", con->val.sex);
        printf("%s  \t", con->val.tel);
        printf("%d  ", con->val.age);
        puts("");
        con = con->next;
    }
   
}
//查找通讯录数据
void FindContact(contact* con)
{
    printf("输入你要找的人名\n");
    char arr[20];
    gets(arr);
    if (con == NULL)
        printf("通讯录空了\n");
    else
    {
        while (con&&strcmp(con->val.name, arr))
        {
            con = con->next;
        }
        if (con != NULL)
        {
            printf("姓名\t地址\t性别\t电话\t年龄\n");
            printf("%s  \t", con->val.name);
            printf("%s  \t", con->val.addr);
            printf("%s  \t", con->val.sex);
            printf("%s  \t", con->val.tel);
            printf("%d  ", con->val.age);
            puts("");
        }
        else
            printf("没找到\n");
    }
}
//修改通讯录数据
void ModifyContact(contact** con)
{
    printf("输入你修改的人名\n");
    char arr[20];
    gets(arr);
    if (*con == NULL)
        printf("通讯录空了\n");
    else
    {
        while (*con&&strcmp((*con)->val.name, arr))
        {
            *con = (*con)->next;
        }
        if (*con == NULL)
            printf("没找到这个人\n");
        else
        {
            (*con) = creatt();
            printf("修改成功\n");
        }

    }
}
//销毁通讯录数据
void DestroyContact(contact** con)
{
    SLTDesTroy(con);
}

main函数


#include"SLT.h"
int main()
{
    contact* p=NULL;
    InitContact(&p);
    AddContact(&p);
    //删除通讯录数据
     //DelContact(&p);
    //展示通讯录数据
     ShowContact(p);
    //查找通讯录数据
     FindContact(p);
    //修改通讯录数据
     ModifyContact(&p);
    //销毁通讯录数据
     DestroyContact(&p);
}

好啦,之前写过详细的通讯录解析,所以这个就直接上答案了。

感谢观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IS-IS:04 DIS

IS-IS 协议只支持两种网络类型&#xff0c;即广播网络和点到点网络。与 OSPF 协议相同&#xff0c; IS-IS 协议在广播网络中会将网络视为一个伪节点 &#xff08; Pesudonde&#xff0c;简称 PSN&#xff09;&#xff0c;并选举出一台DIS &#xff08;Designated IS&#xff09…

【学习】傅里叶变换分析与理解

傅里叶级数的本质是将一个周期的信号分解成无限多分开的&#xff08;离散的&#xff09;正弦波&#xff0c;但是宇宙似乎并不是周期的。 理解频域、空域&#xff08;时域&#xff09; 时域&#xff08;空域&#xff09;是从时间方向看过去的得到的图像&#xff0c;而频域是从频…

laravel框架项目对接小程序实战经验回顾

一.对接小程序总结 1.状态转换带来的问题&#xff0c;如下 问题原因&#xff1a;由于status 传参赋值层级较多&#xff0c;导致后续查询是数组但是传参是字符串&#xff0c; 解决方案&#xff1a;互斥的地方赋值为空数组&#xff0c;有状态冲突的地方unset掉不需要的参数 2参…

4核16G幻兽帕鲁服务器优惠价格表,阿里云和腾讯云报价

幻兽帕鲁服务器价格多少钱&#xff1f;4核16G服务器Palworld官方推荐配置&#xff0c;阿里云4核16G服务器32元1个月、96元3个月&#xff0c;腾讯云幻兽帕鲁服务器服务器4核16G14M带宽66元一个月、277元3个月&#xff0c;8核32G22M配置115元1个月、345元3个月&#xff0c;16核64…

双非本科准备秋招(9.2)——力扣哈希

1、383. 赎金信 跟昨天的题大同小异&#xff0c;因为只有26个字母&#xff0c;所以可以建个有26个坑位的数组。 做完昨天的题目&#xff0c;这个题没啥新意。 class Solution {public boolean canConstruct(String ransomNote, String magazine) {int[] hashTable new int[…

shell脚本5 函数 数组

函数 试题1 查看版本 如果想更方便&#xff0c;可以建立一个专门存函数的文件 将func.sh里面的命令都移到func文件夹里面&#xff0c;在脚本里面执行文件夹更方便 输入echo $?反馈的结果都是0&#xff0c;都认为是正确的 无法使用$?去检验是否正确&#xff0c;所以要在后面增…

python 基础知识点(蓝桥杯python科目个人复习计划27)

今日复习内容&#xff1a;基础算法中的递归 1.介绍 递归&#xff1a;通过自我调用来解决问题的函数递归通常把一个复杂的大问题层层转化为一个与原问题相似的规模较小的问题来解决 递归要注意&#xff1a;&#xff08;1&#xff09;递归出口&#xff1b;&#xff08;2&#x…

使用 Redis 的 List 数据结构实现分页查询的思路

假设有一个存储数据的 List&#xff0c;每个元素代表一个记录&#xff0c;例如 recordsList。 按页存储数据&#xff1a; 每页存储一定数量的记录。例如&#xff0c;第一页存储索引 0 到 N-1 的记录&#xff0c;第二页存储索引 N 到 2N-1 的记录&#xff0c;以此类推。 分页查…

单片机介绍

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

IDEA开发使用 thymeleaf 模板$表达式报红波浪线解决方案

系列文章目录 文章目录 系列文章目录后端存值前端取值thymeleaf 后端存值 RequestMapping("/testModelAndView")//使用ModelAndView时返回的方法类型必须是ModelAndViewpublic ModelAndView testModelAndView() {//创建ModelAndView对象ModelAndView mav new Model…

# Redis 分布式锁如何自动续期

Redis 分布式锁如何自动续期 何为分布式 分布式&#xff0c;从狭义上理解&#xff0c;也与集群差不多&#xff0c;但是它的组织比较松散&#xff0c;不像集群&#xff0c;有一定组织性&#xff0c;一台服务器宕了&#xff0c;其他的服务器可以顶上来。分布式的每一个节点&…

2024年【N1叉车司机】考试内容及N1叉车司机复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 N1叉车司机考试内容是安全生产模拟考试一点通生成的&#xff0c;N1叉车司机证模拟考试题库是根据N1叉车司机最新版教材汇编出N1叉车司机仿真模拟考试。2024年【N1叉车司机】考试内容及N1叉车司机复审考试 1、【多选题…

SpringSecurity笔记

SpringSecurity 本笔记来自三更草堂&#xff1a;https://www.bilibili.com/video/BV1mm4y1X7Hc/?spm_id_from333.337.search-card.all.click&#xff0c;仅供个人学习使用 简介 Spring Security是Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;…

【Django开发】前后端分离美多商城项目:项目准备和搭建(附代码,文档)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论django商城项目开发相关知识。本项目利用Django框架开发一套前后端不分离的商城项目&#xff08;4.0版本&#xff09;含代码和文档。功能包括前后端不分离&#xff0c;方便SEO。采用Django Jinja2模板引擎 Vue.js实现…

【硬件产品经理】避免硬件产品失败 | 技术维度

目录 简介 技术维度一&#xff1a;低估产品开发 技术维度二&#xff1a;低估规模生产的复杂性 技术维度三&#xff1a;测试不足 技术维度四&#xff1a;产品太复杂 技术维度五&#xff1a;对客户承诺太高 推荐内容 简介 这节内容主要从技术维度来谈谈避免硬件产品失败这…

Spring Security关键之5张数据表与7张表 !!!

一、什么是认证和授权&#xff1a; 认证&#xff1a;系统提供的用于识别用户身份的功能&#xff0c;通常提供用户名和密码进行登录其实就是在进行认证&#xff0c;认证的目的是让系统知道你是谁。授权&#xff1a;用户认证成功后&#xff0c;需要为用户授权&#xff0c;其实就…

arcgis 批量删除字段

一、打开ArcToolbox-数据管理工具-字段-删除字段。 二、在输入表中选择要删除字段的要素&#xff0c;在删除字段栏中选择要删除的字段&#xff0c;点击确认即可。

SpringCloud-高级篇(十八)

前面我们已经实现了多级缓存架构&#xff0c;大大提高了查询商品的性能&#xff0c;缓存在提高性能的同时&#xff0c;也带来了一致性的问题&#xff0c;比如说数据库发生了修改&#xff0c;这个时候&#xff0c;如果缓存依然是旧的数据&#xff0c;两者就产生了不一致&#xf…

演练纪实|同创永益助力大型农商行圆满完成2023年度灾备切换演练

为进一步强化银行灾备自动化运行提高系统风险应急能力、提升自动化运维平台的稳定性和可靠性、保障业务连续性&#xff0c;12月16日&#xff0c;某农商银行联合同创永益开展灾备自动化运维平台项目切换演练&#xff0c;同创永益开发交付中心北方交付二组同事参与本次演练。 本次…

在线制作gif动图怎么做?一个方法轻松制作gif动画

有时候一张普通的图片无法表达出我们的意思&#xff0c;但是视频又比较长看起来太过复杂。这时候&#xff0c;大家就可以使用gif动图了&#xff0c;不需要下载软件使用gif生成器&#xff08;https://www.gif.cn/&#xff09;-GIF中文网&#xff0c;轻松一键就能快速完成gif在线…