聊聊双向循环链表的C实现

从链表大数加法到高精度计算:数据结构优化与工程实践 在计算机科学中,高精度计算是处理超出编程语言原生整数类型范围数值的基础技术,其核心原理是通过自定义数据结构模拟数学运算。链表作为经典的数据结构,常被用于实现大数运算,通过节点存储多位数字(如以10000为基底)来优化内存与计算效率。这种技术方案在金融计算、密码学、科学模拟等需要精确数值处理的场景中具有重要价值。本文以链表实现任意长整数加法为例,深入探讨了基底选择、双向链表设计、字符串转换等关键实现细节,并分析了从学生作业到工业级工具所需跨越的内存管理、错误处理与性能优化等工程化鸿沟。 阅读详情

双向循环链表C代码实现

#include <stdio.h>
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"

#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OK 1

#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */

//定义结点
typedef struct Node{
    ElemType data;
    struct Node *prior;
    struct Node *next;
}Node;

typedef struct Node * LinkList;

//6.1 双向循环链表初始化
Status creatLinkList(LinkList *L){
    
    *L = (LinkList)malloc(sizeof(Node));
    if (*L == NULL) {
        return ERROR;
    }
    
    (*L)->next = (*L);
    (*L)->prior = (*L);
    
    //新增数据
    LinkList p = *L;
    for(int i=0; i < 10;i++){
        
        //1.创建1个临时的结点
        LinkList temp = (LinkList)malloc(sizeof(Node));
        temp->data = i;
        
        //2.为新增的结点建立双向链表关系
        //① temp 是p的后继
        p->next = temp;
        //② temp 的前驱是p
        temp->prior = p;
        //③ temp的后继是*L
        temp->next = (*L);
        //④ p 的前驱是新建的temp
        p->prior = temp;
        //⑤ p 要记录最后的结点的位置,方便下一次插入
        p = p->next;
        
    }
    
    return OK;
   
}

//6.2 双向循环链表插入元素
/*当插入位置超过链表长度则插入到链表末尾*/
Status LinkListInsert(LinkList *L, int index, ElemType e){
   
    //1. 创建指针p,指向双向链表头
    LinkList p = (*L);
    int i = 1;
    
    //2.双向循环链表为空,则返回error
    if(*L == NULL) return ERROR;
   
    //3.找到插入前一个位置上的结点p
    while (i < index && p->next != *L) {
        p = p->next;
        i++;
    }
    
    //4.如果i>index 则返回error
    if (i > index)  return ERROR;
    
    //5.创建新结点temp
    LinkList temp = (LinkList)malloc(sizeof(Node));
    
    //6.temp 结点为空,则返回error
    if (temp == NULL) return ERROR;
    
    //7.将生成的新结点temp数据域赋值e.
    temp->data = e;
    
    //8.将结点temp 的前驱结点为p;
    temp->prior = p;
    //9.temp的后继结点指向p->next;
    temp->next = p->next;
    //10.p的后继结点为新结点temp;
    p->next = temp;
    
    //如果temp 结点不是最后一个结点
    if (*L != temp->next) {
        
        //11.temp节点的下一个结点的前驱为temp 结点
        temp->next->prior = temp;
    }else{

        (*L)->prior = temp;
        
    }
    
    return OK;
}


//6.3 遍历双向循环链表
Status Display(LinkList L){
    
    if (L == NULL) {
        printf("打印的双向循环链表为空!\n\n");
        return ERROR;
    }
    printf("双向循环链表内容:  ");
    
    LinkList p = L->next;
    while (p != L) {

        printf("%d  ",p->data);
        p = p->next;
    }
    printf("\n\n");
    return OK;
}

//6.4 双向循环链表删除结点
Status LinkListDelete(LinkList *L,int index,ElemType *e){
    
    int i = 1;
    LinkList temp = (*L)->next;
    
    if (*L == NULL) {
        return  ERROR;
    }
    
    //①.如果删除到只剩下首元结点了,则直接将*L置空;
    if(temp->next == *L){
        free(*L);
        (*L) = NULL;
        return OK;
    }
    
    //1.找到要删除的结点
    while (i < index) {
        temp = temp->next;
        i++;
    }

    //2.给e赋值要删除结点的数据域
    *e = temp->data;
    
    //3.修改被删除结点的前驱结点的后继指针 图1️⃣
    temp->prior->next = temp->next;
    //4.修改被删除结点的后继结点的前驱指针 图2️⃣
    temp->next->prior = temp->prior;
    //5. 删除结点temp
    free(temp);
    
    return OK;
    
}

int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    
    LinkList L;
    Status iStatus;
    ElemType temp,item;
    
    iStatus = creatLinkList(&L);
    printf("双向循环链表初始化是否成功(1->YES)/ (0->NO):  %d\n\n",iStatus);
    Display(L);
    
    printf("输入要插入的位置和数据用空格隔开:");
    scanf("%d %d",&temp,&item);
    iStatus = LinkListInsert(&L,temp,item);
    Display(L);

    printf("输入要删除位置:");
    scanf("%d",&temp);
    iStatus = LinkListDelete(&L, temp, &item);
    printf("删除链表位置为%d,结点数据域为:%d\n",temp,item);
    Display(L);

    
    return 0;
}
国民技术N32G45X低功耗问题之更改全局变量和栈在RAM中的地址 最近项目中用的MCU是国民技术的N32G45X,MCU的资源很丰富,RAM也很大,配套的库和例程也比较全,用起来还是不错的,但是在调试低功耗的时候还是费了不少劲。 首先由于项目低功耗需要,只能选择停机模式2(STOP2)。根据数据手册的描述,在此模式下外部低速时钟开启, RTC运行, R-SRAM保持,所有I/O状态保持,独立看门狗处于关闭状态,25℃的条件下电流为10个微安。 用的这款MCU的RAM是144KB,分为SRAM(128KB)和R-SRAM( Retention SRAM – 16KB),如果 阅读详情

相关推荐

[软考]系统架构设计师 备考经验分享(一) - 备考计划篇

前言 上周末刚刚结束了软考架构师的考试,自我感觉考的还可以,大概率是过了。 两次参加软考,一次中级嵌入式,一次高级架构师,都是备考不到两个月时间,尤其是架构师这次考试内容和本职工作有不小的差别,并且需要同时备考三个科目,在高强度地备考中感觉是摸索出到了一点软考的技巧与经验。 打算趁还记得,赶紧写几篇文章做下梳理总结,算是给将来自己考系分、高项或者其他考试做个记录,也希望能够帮到正在备考的大家。 先把第一步,个人的备考计划分享给大家。 自身情况分析 首先,请大家一定先明确三个问题,这三个问题会直接影响到你的

_ 6404

双向带头循环链表:C语言数据结构实现与LRU缓存应用

链表作为基础数据结构,通过节点和指针实现动态内存管理,克服了数组固定大小的限制。双向链表在单向链表基础上增加了前驱指针,支持双向遍历,提升了操作灵活性。其核心价值在于高效处理频繁的插入和删除操作,时间复杂度可达O(1)。在工程实践中,双向链表常用于实现LRU缓存淘汰算法、文本编辑器缓冲区、撤销/重做功能等场景。本文聚焦于双向带头循环链表这一优化变体,它通过引入哨兵节点(头节点)并首尾相连成环,统一了所有节点的操作逻辑,彻底消除了边界条件判断,使代码更简洁健壮。文中将结合LRU缓存实现和内存管理实战,深入剖析

weixin_34054931的博客 374

3D Slicer中文教程(三)—数据加载及保存方式

1.打开数据与保存数据 (1)打开数据 ——可以将数据拖拽到3D Slicer应用窗口或者从菜单栏工具栏打开。 ——多种方式加载大量数据。 有关DICOM数据,请参阅DICOM模块文档。 对于几乎所有其他(包括场景),您可以使用添加数据对话框。 有关支持的数据格式的列表,请参阅此列表。 请注意,仅部分支持列出的某些格式。 ——对于一些更复杂的格式(特别是DWI),建议首先使用DICOM到n...

weixin_33676492的博客 5536

双向链表和单链表区别

2、单向链表:单个结点创建非常方便,普通的线性内存通常在创建的时候就需要设定数据的大小,结点的访问方便,可以通过循环或者递归的方法访问到任意数据。2、单向链表:结点的删除非常方便,不需要像线性结构那样移动剩下的数据,但是平均的访问效率低于线性表。2、单向链表:是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。1、双向链表:也叫双链表,是链表的一种,每个数据结点中都有两个指针,分别指向直接后继和直接前驱。1、双向链表:增加删除节点复杂,需要多分配一个指针存储空间。

m0_73247666的博客 4812

Halcon 3D点云匹配实战:从预处理到模板创建的完整流程(附代码)

本文详细介绍了Halcon在3D点云匹配中的实战应用,涵盖从预处理到模板创建的完整流程。通过代码示例和实用技巧,帮助开发者掌握点云采样、降噪、三角化等关键技术,并优化匹配参数以提高精度和效率。适用于工业检测、机器人引导等领域。

weixin_33670786的博客 433

银河麒麟v10-arm版离线安装Portainer

银河麒麟v10-arm版离线安装Portainer

q_hsolucky的博客 3051

单向链表与双向链表区别

单向链表: 由两部分组成:数据域和指针域,每个结点都有一个指针,每个节点指针的指向都是指向自身结点的下一个结点,最后一个结点的head指向为null,对单链表的操作只能从一端开始,如果需要查找链表中的某一个结点,则需要从头开始进行遍历。 双向链表: 对于双向链表来说,它的每个节点要指向“直接前驱”和“直接后继”,所以节点类需要含有两个指针域。指向直接前驱的指针使用pre表示,指向后继的指针使用next表示。双向链表是在单向链表基础上的一个改进,每个节点指向其直接前驱和直接后继节点。因此,从双向链表的任

大伟伟的博客 8266

手把手教你用组态王KingSCADA 3.53读取S7-1200 PLC数据(保姆级图文教程)

本文提供了一份详细的组态王KingSCADA 3.53读取S7-1200 PLC数据的实战教程,涵盖从硬件连接到软件配置、变量映射到故障排查的全流程。特别针对初学者常见问题提供解决方案,帮助工程师快速实现稳定通信,提升工业自动化系统效率。

weixin_26876073的博客 674

找出链表的第一个公共结点 java_结构与算法(03):单向链表和双向链表

一、链表简介1、链表概念链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点组成,节点可以在运行时动态生成,节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。2、基础特点内存存储逻辑结构特点描述物理存储上是无序且不连续的;链表是由多个节点以链式结构组成;逻辑层面上看形成一个有序的链路结构;链表结构解决...

weixin_39768444的博客 300

2023年金蝶云星辰初级顾问认证参考试题(1)

最新积累的考试真题,答案只供参考(49分T~T),欢迎大佬们更正,私聊我修改,有新的试题也可以私聊我,日后会完善题库!大家一起努力,预祝大家顺利通过!1.【简单】生产环节中,客户老板希望掌握材料的超发或漏发情况,,以便分析用料情况,对材料浪费进行管控,可以查看什么报表?⒉[中等】客户主营电气柜的生产销售,商品为非标品需定制,又因交期效短,需要边生产边补料,以下哪个功能最适合该客户场景?15.【简单】在给商品设置科目关联时,分别按照单个商品,商品类别,所有商品设置了对应客户,()优先级最高。

MLX00的博客 7974

Spring Security 珍藏版快速入门

文章目录一、前期配置二、Spring Security 测试三、案例:自定义页面(XML配置用户信息)三、案例:自定义页面(数据库存储用户信息) 一、前期配置 (1)pom.xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${s

南淮北安的博客 633

单链表,双链表,循环链表的区别

单向链表(单链表) 单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向表中的下一个节点,而最后一个节点则 指向一个空值NULL。 单向链表只可向一个方向遍历。查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。也可以提前把一个节点的位置另外保存起来,然后直接访问。 双向链表,(双链表) 双向链表中不

code changes world! 9879

816华为OD机试真题 新系统 - 电池充电时间计算 (Java/Py/C/C++/Js/Go)

816华为OD机试真题 新系统 - 电池充电时间计算 (Java/Py/C/C++/Js/Go)

算法大师! 472

C语言单向链表、双向链表和循环链表有什么区别?

C语言单向链表、双向链表和循环链表有什么区别?

致力于分享在各类技术领域的学习与实践经验,涵盖编程、虚拟化、开源工具、网络安全等。 868

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

初阶数据结构之双向链表详解

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表,因此,本节的双向链表也是双向循环链表。在List.h中定义链表结点,data的类型设为DataType,方便以后使用其他类型的数据。}ListNode;

2302_80837091的博客 1587

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

深入浅出双向链表与Linux内核链表 附数组链表核心区别解析

本文详细讲解了双向链表和双向循环链表的基本概念、核心操作及其实现方法。内容包括节点的创建与销毁、头插法和尾插法、查找与替换等基本操作,并介绍了Linux内核链表的巧妙设计。最后对比了数组和链表的区别,强调双向链表通过双指针实现双向遍历的灵活性。通过通俗的语言和详细注释的代码示例,帮助不同水平的学习者理解链表的核心原理和应用场景,为数据结构学习提供了实用指导。

2302_80623234的博客 755

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

带头双向循环链表实战:从哨兵位设计到C语言完整实现

链表是最基础也最常考的数据结构之一,而带头双向循环链表将头节点、双向指针与首尾相接三个特性融为一体,实现了所有操作在节点指针层面的高度统一。它通过哨兵位消除了大量边界判断,让空表与非空表共用同一套逻辑;借助前驱指针使删除任意节点的时间复杂度降为O(1);利用循环结构让尾插和头插无需遍历即可完成。这一结构在Linux内核的list_head、C++ STL的std::list以及LRU缓存淘汰等工程场景中都有广泛应用,是理解指针操作和抽象设计思路的绝佳载体。本文以C语言为例,从结构体定义到增删改查逐层拆解,配

weixin_32932149的博客 147

04_C语言数据结构与算法之线性数据结构:链表 —— 非连续内存的灵活王者

/ 单链表节点定义(以存储嵌入式传感器数据为例)// 数据域:存储传感器采集的16位数值// 指针域:指向下一个节点} ListNode;// 双向链表节点定义(以存储嵌入式任务信息为例)// 数据域:任务ID// 数据域:任务优先级// 指针域:指向前驱节点// 指针域:指向后继节点链表的核心价值,在于挣脱了连续内存的束缚,以指针为纽带,实现了数据的灵活存储与操作。

C语言无原生OOP特性,却能借结构体+函数指针实现封装、继承、多态,落地工厂等设计模式。博客中以标准C语法实操教学,融入跨平台兼容设计,助开发者掌握C语言OOP核心与工程实践技巧。 878

算法:leetcode_146_LRU 缓存

本文详细介绍了LRU(最近最少使用)缓存的设计与实现。通过双向循环链表和哈希表的结合,实现了O(1)时间复杂度的get和put操作。核心实现包括:1)使用双向链表维护访问顺序;2)利用哈希表实现快速查找;3)定义disconnect和pushFront方法维护链表结构;4)处理容量满时的淘汰策略。

bugMaker_0621的博客 1245

循环链表实战指南:从轮询调度到约瑟夫问题的工程化应用

在程序设计中,数据结构的选择往往决定业务实现的复杂度与稳定性。循环链表作为一种首尾相连的线性结构,其核心价值在于天然支持“绕圈”访问与动态增删,非常适合表达轮转、复用与淘汰类场景。从操作系统的时间片轮询调度,到游戏房间的玩家轮流答题,再到连接池的公平分配,循环链表都能以极简的指针移动替代繁琐的数组搬移。同时,约瑟夫问题作为经典算法模型,也体现了在环上持续删除节点的工程技巧。本文结合真实项目经验,梳理了循环链表的技术原理、适用边界的判断标准、双向链表与单向链表的选择依据,以及调试过程中容易踩中的陷阱,帮助开发

weixin_33806859的博客 178

双向链表详解:从结构设计到插入删除的工程实践

数据结构是嵌入式开发和系统编程的基石,而链表作为其中灵活的动态存储结构,在实际项目中有着广泛应用。单链表因只能单向遍历,在需要频繁回退或删除指定节点的场景中效率低下,而双向链表通过增加前驱指针,实现了向前与向后遍历均为O(1)的高效操作,以空间换时间解决回溯痛点。理解其节点结构、指针配对原则与带头循环的设计,是掌握增删改查实现和避免断链野指针的关键。在浏览器历史记录、多级菜单导航、缓存淘汰等真实应用中,双向链表都扮演着核心角色。选择何种线性结构,需根据访问模式与性能需求权衡,本文以双向链表为主线,深入解析其

weixin_28740299的博客 241

C语言链表完全指南:从定义、操作到内存调试与工程实践

数据结构是编程的核心基础,而链表作为C语言中最典型的动态数据结构,通过指针将不连续的内存节点按逻辑顺序串联,完美解决了数组扩容代价高、中间插入删除低效的痛点。理解链表的关键在于掌握节点与指针的关系、内存分配与释放的时机,以及边界条件的正确处理。从单链表的创建、插入、删除、反转,到双向链表、循环链表、虚拟头节点等进阶形态,链表广泛应用于操作系统调度、内存管理、缓存淘汰等真实系统场景。本文以C语言为背景,结合调试经验与工程实践,系统梳理链表的核心原理、高频操作与常见陷阱,帮助你彻底掌握链表的设计思路与内存管理技

weixin_34101914的博客 80

从零手写C++ STL list:双向链表、迭代器与内存管理深度解析

数据结构与算法是程序设计的基石,而链表作为最基础的动态数据结构之一,其工程化实现远比教科书中的示例复杂。C++标准模板库(STL)中的list容器,正是将双向链表、迭代器抽象与内存管理融为一体的工业级组件。理解其底层原理,不仅有助于应对面试中关于容器实现的高频问题,更能指导开发者在实际项目中做出正确的技术选型。本文从链表的概念与基本指针操作出发,逐步剖析为何STL选择带头双向循环结构,并深入探讨迭代器设计、深拷贝与异常安全等关键机制,最后结合应用场景分析list与vector在性能与缓存友好性上的取舍,帮助

weixin_31528001的博客 229

<C语言数据结构三>C语言带你玩转“单向链表”

链表是C语言中比较常用的一种数据结构,相对与上几篇文章的队列结构来说,链表是在一种物理存储单元上非连续、非顺序的存储结构。链表中的每个节点都是通过链表中的指针链接次序实现的;一般来说每个节点都会包含以下两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 链表又会分成很多个类型:单线链表,单向循环链表,双向链表,双向循环链表等; 这篇文章我们主要聊聊单向链表,单向链表又分为以下两种类型:链表的数据定义 链表的创建 链表的插入:头插和尾插 链表的删除:根据数据内容或者节点序号 链表的销毁

weixin_43504224的博客 1327

聊聊运维应该了解的一些内核知识

二、进程 先来聊聊Linux内核开发,内核开发和普通应用开发有两个地方不一样: 自己要管理内存,普通应用跑在内核之上,内核可以帮你管理内存,但是你自己就是内核,你必须自己做好内核管理,要不很容易就内核溢出了。 没有库文件,普通应用程序有很多库文件可以调用,内核开发则没有,内核开发就是标准的C。 由此看见,做内核开发还是要对内核有深刻的理解才可以,请注意,这里的内核开发指的是内核核心功能的开发。 我们再来看看进程,进程简单的讲,就是运行中的程序,我个人理解,进程是一种生命形式,就像一个人的生命,从呱呱坠地开始

sunshineywz的博客 370

C语言链表实战:从节点定义到核心操作与工程应用

数据结构是编程的核心基石,而链表作为最常见的动态数据结构之一,通过指针将分散的内存节点串联起来,实现了高效的元素插入与删除操作。理解链表的工作原理,不仅有助于掌握内存管理的本质,还能为操作系统内核、内存池、LRU缓存等真实场景提供基础支撑。本文从链表的基础概念出发,详细讲解节点的结构体定义、头指针与头结点的区别,并逐步实现初始化、头插、尾插、指定位置插入、删除、遍历及链表逆序等核心操作,同时剖析常见崩溃与内存泄漏问题,帮助读者避开工程实践中的典型陷阱。通过对比数组与链表的适用场景,以及介绍循环链表、双向链表

weixin_33502772的博客 163
上一篇: 双向链表C代码实现
下一篇: 线性表练习题
Riseboy
博客等级 码龄10年 5粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值