当前位置: 首页 > news >正文

【C语言数据结构】03.双链表

前言

  • 本节主要进行C语言数据结构双链表的学习。

目录

  • 前言
  • 1.双链表介绍
  • 2.单循环链表实现


1.双链表介绍

  • 单链表中,每个结点包含下一个结点的地址,但没有其先前结点的任何记录,所以单链表只能在一个方向上遍历。
  • 这就需要寻找另一种数据结构来克服单链表的这一缺点,这种结构就是双链表
  • 双向链表也是采用的链式存储结构,它与单链表的区别就是每个数据结点中多了一个指向前驱元素的指针域。所以从双向链表的任意一个结点开始都可以很方便的访问其前驱元素和后继元素。
  • 由于双链表的每个结点都包含其先前结点的地址,因此可以通过使用存储在每个结点的前一部分内的先前地址来找到关于前一结点的所有细节。
  • 因此,双链表与单向链表相比有以下优势:因每个节点都记录了上一个节点,所有插入删除不需要移动元素,可以原地插入删除,可以双向遍历
  • 需要注意的是,操作时涉及到node>next->pre的情况,所以要考虑到node是否为最后一个元素,即node->next==NULL的情况,不然会内存访问出错,造成段错误
    在这里插入图片描述

2.单循环链表实现

  • 实现内容与前章相同,1.初始化;2.插入节点:头插法、尾插法;3.删除节点;4.遍历链表。
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

typedef struct Node//定义数据结构,包含数据域域next域
{
    int data;//data域
    struct Node* pre;//pre指针域
    struct Node* next;//next指针域
}Node;

Node* initList()//初始化头节点
{
    Node* list=(Node*)malloc(sizeof(Node));//开辟空间,新建节点
    list->data=0;//链表默认个数为0
    list->pre=NULL;
    list->next=NULL;//链表为空,故头节点next域为空
    return list;
}

void headInsert(Node* list,int data)//头插法
{
    Node* node = (Node*)malloc(sizeof(Node));//开辟空间,新建节点
    node->data = data;//data给到新建节点的数据域
    node->pre = list;//pre指向头节点
    node->next = list->next;//新建节点的next指向的是原先链表的第一个节点,也就是头节点指向的节点
    if(list->data!=0)   list->next->pre=node;//不为空时,原第一个节点的pre前一个节点变成了新节点node
    list->next = node;//头节点指向新建节点
    list->data++;//插入链表使data域节点数加一
}

void tailInsert(Node* list,int data)//尾插法
{
    list->data++;//插入链表使data域节点数加一
    Node* node = (Node*)malloc(sizeof(Node));//开辟空间,新建节点
    node->data = data;//data给到新建节点的数据域
    node->next = NULL;//新建节点指向list
    while(list->next!=NULL)//寻找最后一个节点
    {
        list=list->next;
    }
    node->pre = list;
    list->next=node;//最后一个节点指向新建节点
}

bool delete(Node* list,int data)//删除
{
    Node* node=list->next;//保存第一个节点开始,从它开始遍历
    while(node!=NULL)//遍历,可使用头节点data进行for循环遍历
    {
        if(node->data==data)//找到data
        {
            node->pre->next=node->next;//将前一个节点的next指向要要删除节点的下一个节点
            if(node->next!=NULL)   node->next->pre=node->pre;//不是最后一个节点,则将下一个节点的pre指向要要删除节点的前一个节点
            free(node);//释放要铲除节点的堆内存空间
            break;//退出循环
        }
        node = node->next;//未找到data则往后继续遍历
    }
    if(node!=NULL)//未遍历到头,说明删除成功
    {
    list->data--;
    return true;
    }
    else return false;//能遍历到头,说明未找到data,删除失败报错
}

void printList(Node* list)//遍历操作
{
    Node* node=list->next;//循环链表的第一个节点给到新建节点node,即头节点的下一个
    while(node)
    {
        printf("%d->",node->data);
        node=node->next;        
    }
    printf("NULL\n");
}

int main()
{
    Node* list= initList();//初始化头节点,创捷链表节点
    headInsert(list,5);
    headInsert(list,4);
    headInsert(list,3);
    headInsert(list,2);
    headInsert(list,1);
    tailInsert(list,6);
    tailInsert(list,7);
    tailInsert(list,8);
    tailInsert(list,9);
    tailInsert(list,10);
    printList(list);
    printf("%d\n",delete(list,1));
    printf("%d\n",delete(list,11));
    printf("%d\n",delete(list,6));
    printf("%d\n",delete(list,6));
    printf("%d\n",delete(list,10));
    printList(list);
    system("pause");
}

在这里插入图片描述

参考资料:
链接1: UP从0到1带你手撕数据结构全集(C语言版)
链接2: 双链表详解(C语言版)

相关文章:

  • 非零基础自学Java (老师:韩顺平) 第23章 反射(reflection) 23.2 反射机制
  • (一)Java算法:二分查找
  • [前缀和]Tokitsukaze and Strange Inequality Codeforces1678C
  • Stl中map、set 容器(数据结构:AVL树、红黑树)--C++
  • Chapter20: Machine Learning for In Silico ADMET Prediction
  • Ubuntu下安装Miniconda
  • No1.搭建基本的密码模式请求token(授权服务端)
  • 代码随想录二叉树——从中序与后序遍历序列构造二叉树
  • 【2023泰凌微笔试题】~ 题目及参考答案
  • 采用Python中Tkinter模块的Treeview 组件显示xml文件
  • synchronized的实现原理与应用
  • 网上商城之支付
  • 一次搞懂Java如何调用Kotlin的高级特性
  • MyBatis各种SQL操作及执行添加功能获取自增的主键
  • 【学习笔记】模拟赛题解
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • Docker: 容器互访的三种方式
  • docker-consul
  • ES6--对象的扩展
  • Java 23种设计模式 之单例模式 7种实现方式
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • k个最大的数及变种小结
  • pdf文件如何在线转换为jpg图片
  • python学习笔记-类对象的信息
  • Redis的resp协议
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 从伪并行的 Python 多线程说起
  • 第2章 网络文档
  • 近期前端发展计划
  • 面试总结JavaScript篇
  • 日剧·日综资源集合(建议收藏)
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 通过几道题目学习二叉搜索树
  • 正则学习笔记
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 如何正确理解,内页权重高于首页?
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (1) caustics\
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (利用IDEA+Maven)定制属于自己的jar包
  • (原創) 物件導向與老子思想 (OO)
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • .Net 代码性能 - (1)
  • .NET基础篇——反射的奥妙
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • ??myeclipse+tomcat
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘
  • @requestBody写与不写的情况