广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言数据结构之单链表与双链表的增删改查操作实现
  • 364
分享到

C语言数据结构之单链表与双链表的增删改查操作实现

2024-04-02 19:04:59 364人浏览 安东尼
摘要

目录前言单链表的增删改查定义结构体以及初始化增加结点删除结点查找修改结点移除结点最终效果双链表的基本操作初始化建表遍历双链表指定位置插入结点指定位置删除结点查找结点位置最终效果结语前

前言

上篇博客分享了创建链表传入二级指针的细节,那么今天就分享几个C语言课程实践设计吧。这些程序设计搞懂了的话相当于链表的基础知识牢牢掌握了,那么再应对复杂的链表类的题也就能慢慢钻研了。学习是一个积累的过程,想要游刃有余就得勤学苦练!

单链表的增删改查

(1)项目需求

构造带有头结点的单链表数据结构,实现初始化、清空和销毁操作,在两端插入元素和删除元素操作并在链表中查找操作,在指定位置插入和删除元素操作,移除元素操作

(2)解决思路
①  定义节点类型,定义单链表类型,构造创建新节点的函数。

②  初始化、清空和销毁操作:初始化操作负责将参数指向的单链表类型变量初始 化为空链表。清空操作的作用是将一个链表清空。销毁操作负责销毁一个链表。

③  在两端插入元素和删除元素操作:包括从链表头部插入和删除元素,从链表尾 部插入和删除元素。

④  在链表中查找操作 : 查找操作用于在参数指向的链表中,查找首个值等于待插入 参数的元素。并返回结点的首地址,返回的地址可供使用者修改结点信息。

⑤  在指定位置插入和删除元素操作:插入和删除元素都涉及到前后位置指针的指 向问题,有多种解决方案。以插入元素为例,将元素插入指定位置、指定位置 之 4前和指定位置之后等。

⑥  移除元素:用于删除链表中所有满足某个条件的元素。删除单向链表中的结点 需要修改前驱结点的指针域,链表的首元结点没有前驱结点,需要考虑如何处理。

定义结构体以及初始化

typedef struct LinkList //typedef是重命名的含义,此时LinkList * 和 List 含义一致,都是指向结点的指针
{
    int data;//数据域
    LinkList* next;//指针域
}*List; //指向结点的指针
//初始化链表
void init_List(List &L)
{
    //初始化后链表第一个结点就是头结点
    L = (List)malloc(sizeof(LinkList));//为链表分配空间
    L->data = 0;//数据域为零
    L->next = NULL;//指针指向空
}
 
//清空链表
void clear_List(List &L)
{
    if (L->next != NULL)//如果头结点连着的第一个结点不为NULL
    {
        L->next = NULL;//置为NULL,此时链表只有头结点,相当于清空链表
    }
    printf("清空链表成功");
}
//销毁链表
void destory_List(List &L)
{
    if (L != NULL)//当头结点不为空时
    {
        free(L);//删除头结点地址
        L = NULL;//将指针指向NULL,彻底销毁链表
    }
    printf("销毁链表成功");
}

增加结点

1、头插

//头插法
void headAdd_List(List &L)
{
    List ptr = L->next;//ptr指针初始化指向首元结点,也就是除了头结点的第一个结点
    int value = 0;//用来赋值为插入结点的data属性
    printf("输入头插的结点值:"); 
    scanf("%d", &value);
    List s = (List)malloc(sizeof(LinkList));//s 为待插入结点
    s->data = value;//将value赋值给s data属性
    s->next = ptr;//s 指向 ptr,即指向头结点的下一个结点
    L->next = s;//L头结点指向s,那么现在s结点就插入
}

2、 尾插

//尾插法
void tailAdd_List(List &L)
{
    int value = 0;//用来赋值为插入结点的data属性
    printf("输入尾插的结点值:");
    scanf("%d", &value);
    List s = (List)malloc(sizeof(LinkList));//s 为待插入结点
    s->data = value;//将value赋值给s data属性
    List ptr = L->next;//ptr指针初始化指向首元结点,也就是除了头结点的第一个结点
    if (ptr == NULL)//此时链表为空
    {
        s->next = L->next;
        L->next = s;
    }
    else {
        List pre = NULL;//创建pre指针
        while (ptr)//当ptr不为NULL时
        {
            pre = ptr;//将pre指向ptr
            ptr = ptr->next;//ptr指向他的下一个结点
        }//循环结束时,pre指向链表最后一个结点,ptr指向最后一个结点的下一个结点
        s->next = ptr;//待插入s结点指向ptr
        pre->next = s;//将s结点插入到链表最后,尾插完成
    }
}

3、指定位置插入

//插入操作
void insert_List(List &L,int n,int data)
{
    List ptr = L->next;
    List pre = NULL;
    List s = (List)malloc(sizeof(LinkList));//s 为待插入结点
    s->data = data;//将形参列表的data数据赋值给s的data属性
    s->next = NULL;
    if (n<1)
    {
        printf("插入位置错误!");
    }
    else if (n == 1)
    {
        printf("调用头插法,请重写输入元素值:");
        headAdd_List(L);//如果插入第一个位置,调用头插法
    }
    else 
    {
        for (int i = 1; i < n; i++)
        {
            pre = ptr;
            ptr = ptr->next;
        }//循环结束后,ptr指向待插入的位置,pre指向待插入位置的前一个位置
        s->next = ptr;//插入s结点
        pre->next = s;
    }
}

删除结点

1、头删

void headDelete_List(List &L)
{
    printf("执行头删:\n");
    List ptr = L->next;//ptr指针初始化指向首元结点,也就是除了头结点的第一个结点
    L->next = ptr->next;//直接让头结点指向首元结点的下一个结点,跳过首元结点就是删除
    delete ptr;//将首元结点地址删除
    ptr = NULL;//指针指向空,防止空指针异常
}

2、尾删

//尾删
void tailDelete_List(List& L)
{
    printf("执行尾删:\n");
    List ptr = L;//ptr指针指向头结点
    List pre = NULL;//创建结点pre
    while (ptr->next)//当ptr的下一个结点不为NULL时
    {
        pre = ptr;//将pre指向ptr
        ptr = ptr->next;//ptr指向他的下一个结点
    }//循环结束时,pre指向链表最后一个结点的前一个结点,ptr指向链表最后一个结点
    pre->next = NULL;//将pre的next指针置为空,删除掉
    free(ptr);//释放删除掉的ptr指针
}

3、指定位置删除 

void delete_List(List & L, int n)
{
    List ptr = L->next;
    List pre = NULL;
    if (n<1)
    {
        printf("删除位置有误!");
    }
    else if (n == 1)
    {
        headDelete_List(L);//调用头删
    }
    else
    {
        for (int i = 1; i < n ;i++)
        {
            pre = ptr;
            ptr = ptr->next;
        }//循环结束后,ptr指向待插入的位置,pre指向待插入位置的前一个位置
        pre->next = ptr->next;//删除该位置的结点
        delete ptr;//删除ptr地址
        ptr = NULL;//防止空指针异常
    }
   
}

查找修改结点

List find_List(int data,List &L)
{
    int i = 1;
    List ptr = L->next;
    while (ptr)//当结点不为空时
    {
        if (ptr->data == data)
        {
            printf("该元素在链表的位置为第 %d个\n",i);
            return ptr;//找到就返回地址
        }
        i++;
        ptr = ptr->next;//继续遍历
    }
    printf("链表中没有该元素\n");
    return NULL;
}

移除结点

//移除元素
void cancel_List(List &L,int n)
{
    List ptr = L->next;
    List pre = L;
    while (ptr)//ptr不空时
    {
        if (ptr->data == n)//如果和传进来的n相等
        {
            pre->next = ptr->next;//删除改结点
            delete ptr;//删除地址
            ptr = pre;//重新指向前一个结点
        }
        else {
            pre = ptr;//如果ptr不和n相等,让pre往后走
            ptr = ptr->next;//ptr向后遍历
        }
    }
}

最终效果

双链表的基本操作

初始化建表

typedef int ElemType;//将整型数据重命名为int
typedef int Status;//整型重命名为Status
 
//双链表的数据结构定义
typedef struct Dounode {
    ElemType data;               //数据域
    struct DouNode* head;        //前驱指针
    struct DouNode* next;        //后继指针
}DousList, * LinkList;// 结点指针
//双链表的创建
void CreateDouList(LinkList &L, int n)
{
    LinkList  ptr;
    int i;
    L = (LinkList)malloc(sizeof(DousList));    //为头结点申请空间
    L->next = NULL;
    L->head = NULL;
    L->data = n;//L->data记录结点的个数
    ptr = L;
    for (i = 0; i < n; i++)
    {
        int value = 0;
        scanf("%d",&value);
        LinkList me = (LinkList)malloc(sizeof(DouNode));
        me->data = value;    //节点数据域
        me->next = NULL;
        me->head = NULL;
        ptr->next = me;     
        me->head = ptr;
        ptr = ptr->next;     //尾插法建表
    }
}

遍历双链表

//双链表的遍历
void DisPlayList(LinkList L)
{
    printf("当前链表数据为:\n");
    LinkList ptr= L->next;
    while (ptr)
    {
        printf("%d ",ptr->data);
        ptr = ptr->next;
    }
    printf("\n");
}

指定位置插入结点

void InsertNode(LinkList &L, int n, ElemType data)
{
    LinkList pre=NULL;
    LinkList ptr = L->next;
    LinkList me = (LinkList)malloc(sizeof(DouNode));
    me->head = NULL;
    me->next = NULL;
    me->data = data;
    if (n<1 || n>L->data)
    {
        printf("插入位置有误!");
        return ;
    }
    else if (n == 1)
    {
        ptr->head = me;
        me->next = ptr;
        L->next = me;
        me->head = L;
        L->data++;
    }
    else
    {
        for (int i = 1; i < n; i++)
        {
            pre = ptr;
            ptr = ptr->next;
        }
        ptr->head = me;
        me->next = ptr;
        pre->next = me;
        me->head = pre;
        L->data++;
    }
    
}

指定位置删除结点

Status DeleteNode(LinkList& L, int n, ElemType* v)
{
    LinkList ptr = L->next;
    if (n<1 || n>L->data)
    {
        printf("删除位置有误!");
        return -1;
    }
    else 
    {
        for (int i = 1; i < n; i++)
        {
            ptr = ptr->next;
        }
        v= &ptr->data;
        ptr->head->next = ptr->next;
        ptr->next->head = ptr->head;
       
 
    }
    L->data--;
    return *v;
}

查找结点位置

void FindNode(LinkList L, ElemType data)
{
    int i = 0;
    LinkList ptr = L;
    while (ptr) {
        i++;
        ptr=ptr->next;
        if (ptr->data == data) {
            printf("该元素在链表中的位置为:%d\n",i);
        }
    }
}

最终效果

结语

链表的操作看着复杂其实也不复杂,和数组的区别就是需要动态分配内存空间,然后遍历有点小复杂罢了,多加练习就好了。

以上就是C语言数据结构之单链表与双链表的增删改查操作实现的详细内容,更多关于C语言 单链表 双链表的资料请关注编程网其它相关文章!

--结束END--

本文标题: C语言数据结构之单链表与双链表的增删改查操作实现

本文链接: https://www.lsjlt.com/news/153772.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言数据结构之单链表与双链表的增删改查操作实现
    目录前言单链表的增删改查定义结构体以及初始化增加结点删除结点查找修改结点移除结点最终效果双链表的基本操作初始化建表遍历双链表指定位置插入结点指定位置删除结点查找结点位置最终效果结语前...
    99+
    2022-11-13
  • 【数据结构】—— 单链表的增删改查
    ❤️一名热爱Java的大一学生,希望与各位大佬共同学习进步❤️ 🧑个人主页:@周小末天天开心 各位大佬的点赞👍 收藏⭐ 关注✅,是本人学习的最大动力 感谢! 📕该篇文章收录专栏—...
    99+
    2023-09-04
    java 开发语言 数据结构
  • C语言数据结构之单链表的实现
    目录一.为什么使用链表二.链表的概念三.链表的实现3.1 创建链表前须知3.2 定义结构体3.3 申请一个节点3.4 链表的头插3.5 链表的尾插3.6 链表的尾删3.7 链表的头删...
    99+
    2022-11-13
  • C语言数据结构之单链表操作详解
    目录1、插入操作2、删除操作3、查找操作4、修改操作5、完整代码1、插入操作 (1)创建一个新的要插入的结点 (2)将新结点的 next 指针指向插入位置后的结点 (3)将插入位置前...
    99+
    2022-11-13
  • C语言中如何实现单向链表的增删查改操作
    这篇文章主要介绍了C语言中如何实现单向链表的增删查改操作,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言链表是线性表的链式存储结构,它可以以O(1)的时间复杂度进行插入或者...
    99+
    2023-06-25
  • C语言数据结构与算法之单链表
    目录基本概念读取数据元素获取第i个结点的数据元素插入数据元素 初始化链表打印链表顺序表查空顺序表的删除 删除第i个结点及其数据元素情况1:当删除的是第一个元素情况2:除第一个结点外完...
    99+
    2022-11-12
  • C语言中单链表的基本操作指南(增删改查)
    目录1.链表概述2.链表的基本使用2.0 准备工作2.1 创建节点(结构体)2.2 全局定义链表头尾指针 方便调用2.3 创建链表,实现在链表中增加一个数据(尾添加)————增2.4...
    99+
    2022-11-12
  • C语言数据结构之单链表怎么实现
    本文小编为大家详细介绍“C语言数据结构之单链表怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言数据结构之单链表怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一.为什么使用链表在学习链表以前,...
    99+
    2023-07-02
  • Java数据结构之链表的增删查改详解
    目录一、链表的概念和结构1.1 链表的概念1.2 链表的分类二、单向不带头非循环链表2.1 创建节点类型2.2 头插法2.3 尾插法2.4 获取链表长度2.5 任意位置插入2.6 查...
    99+
    2022-11-12
  • C语言数据结构之单链表的查找和建立
    目录单链表的查找按位查找按值查找单链表的建立尾插法头插法建立单链表单链表的查找 其实在单链表的插入和删除中,我们已经使用过单链表的查找方法,因为插入和删除的前提都是先找到对应的结点,...
    99+
    2022-11-13
  • C++数据结构之单链表的实现
    目录一、单链表的定义二、单链表的基本操作的实现1.初始化2.取值3.查找4.插入5.删除三、完整代码四、测试一下代码一、单链表的定义 线性表的链式存储又称为单链表,它是指通过一组任意...
    99+
    2022-11-13
  • Java实现单链表增删改查的操作方法
    这篇文章主要介绍了Java实现单链表增删改查的操作方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、新建学生节点类Stu_Node节点包含:学号:int num;姓名:S...
    99+
    2023-06-14
  • java数据结构中单链表与双向链表的实现方法
    这篇文章主要介绍“java数据结构中单链表与双向链表的实现方法”,在日常操作中,相信很多人在java数据结构中单链表与双向链表的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java数据结构中单链表与...
    99+
    2023-06-20
  • C语言中单链表的基本操作(创建、销毁、增删查改等)
    目录链表分类单链表的介绍单链表的基本操作创建打印尾插头插尾删头删查找任意位置插入任意位置删除销毁完整代码总结链表分类 链表主要有下面三种分类方法: 单向或者双向带头或者不带头循环或者...
    99+
    2023-02-05
    C语言单链表 单链表的创建 单链表的销毁 单链表的增删查改
  • C语言数据结构实例讲解单链表的实现
    目录1、单链表2、单链表的实现头文件函数的实现(1)打印链表(2)动态申请结点(3)尾插(4)头插(5)尾删(6)头删(7)查找(8)在pos之前插入(9)删除pos(10)在pos...
    99+
    2022-11-13
  • C语言实现通用数据结构之通用链表
    本文实例为大家分享了c语言实现通用数据结构之通用链表的具体代码,供大家参考,具体内容如下 忽然想起来,大概在两年之前学习C语言的时候,曾经用C语言写过一些通用的数据结构。主要也就实现...
    99+
    2022-11-12
  • 数据结构C语言链表的实现介绍
    目录前言函数1. 链表初始化2. 计算链表长度3. 打印链表4.计算链表长度5. 删除链表中指定位置节点6. 向链表中指定位置插入节点7. 全代码+运行效果前言 需要用到的函数库 ...
    99+
    2022-11-12
  • Go语言数据结构之单链表的实例详解
    目录任意类型的数据域实例01快慢指针实例02反转链表实例03实例04交换节点实例05任意类型的数据域 之前的链表定义数据域都是整型int,如果需要不同类型的数据就要用到 interf...
    99+
    2022-11-11
  • C语言数据结构中单向环形链表怎么实现
    这篇“C语言数据结构中单向环形链表怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言数据结构中单向环形链表怎么实现...
    99+
    2023-06-29
  • C语言数据结构中双向带头循环链表怎么实现
    这篇文章主要讲解了“C语言数据结构中双向带头循环链表怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言数据结构中双向带头循环链表怎么实现”吧!一、概念来画张图总体回顾下:在我们学习...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作