链表操作常见技巧浅析

STM32H743的ADC还能这么玩?定时器触发+DMA搬运,构建低CPU占用的数据流 本文深入探讨了STM32H743微控制器中ADC的高效使用方法,通过定时器触发和DMA搬运技术实现低CPU占用的数据流采集。详细解析了硬件架构、CubeMX配置步骤及高级优化技巧,包括双缓冲技术和多ADC同步采样,适用于电机控制、音频采集等高性能应用场景。 阅读详情

链表操作是程序设计中最常见的一类操作。在我们项目或面试中经常会用到,我们可以大致总结下链表操作的常见技巧。其实也没有什么难点,主要是操作列表时,注意异常边界值的考虑。一般在修改链表时,会用到辅助链表指针,其目的在我看来主要有2个作用:一是将当前结点保存起来,好让此时结点的指针指向下一结点(这里可以类似看做一个游标,向前或向后的结点移动。二是利用辅助链表指针的位置来实现特定的目的)。我们主要看到这里数据域则为该结点保存的值,而指针域可以看作一个游标,通过它来指向下一个结点(pList->next),也可以指向下一个结点的结点(pList->next->next),。。。。。。这样就可以遍历整个链表了。


下面是某一类常见的链表操作,代码都比较简练,熟悉了操作步骤,写这些代码应该是不难的!

#include <stdio.h>

#include <string.h>
#include <stdlib.h>

struct ListNode
{
    int data;    //---------------数据域
    ListNode *next; //--------------指针域
};

unsigned int getListLength(ListNode *pList)
{
    if (pList == NULL)
    {
        return 0;
    }
    unsigned len = 0;
    ListNode *pCur = pList;
    while (pCur != NULL)
    {
        len++;
        pCur = pCur->next;
    }

    return len;
}

ListNode *createList(int n)
{
    if (n <= 0)
    {
        return NULL;
    }
    ListNode *pCurrent = NULL;
    ListNode *pHead = NULL;
    for(int i = 0; i < n; i++)
    {
        pCurrent = (ListNode*)malloc(sizeof(struct ListNode));
        pCurrent->data = i + 1;
        pCurrent->next = pHead;
        pHead = pCurrent;
    }

    return pHead;

}

void traverseList(ListNode *pList) //遍历链表
{
    while (pList != NULL)
    {
        printf("%d\n", pList->data);
        pList = pList->next;
    }
}

void freeList(ListNode *pList)
{
    while(pList != NULL)
    {
        ListNode *pTemp = pList;
        pList = pList->next;
        free(pTemp);
    }
}


ListNode *reverseList(ListNode *pList)
{
    if (pList == NULL || pList->next == NULL)
    {
        return pList;
    }
    ListNode *pHead = NULL;
    ListNode *pCur = pList;
    while (pCur != NULL)
    {
        ListNode *pTemp = pCur;
        pCur = pCur->next;
        pTemp->next = pHead;
        pHead = pTemp;
    }
    return pHead;
}


ListNode *getRightKthNode(ListNode *pList, int k)
{
    if (k <=0 || pList == NULL)
    {
        return NULL;
    }

    ListNode *pAhead = pList;
    ListNode *pBehind = pList;
    while (k > 1 && pAhead != NULL)
    {
        pAhead = pAhead->next;
        k--;
    }
    if (k > 1 || pAhead == NULL)
    {
        return NULL;
    }

    while (pAhead->next != NULL)
    {
        pBehind = pBehind->next;
        pAhead = pAhead->next;
    }

    return pBehind;

}

ListNode *getMiddleNode(ListNode *pList)
{
    if (pList == NULL || pList->next == NULL)
    {
        return pList;
    }
    ListNode *pAhead = pList;
    ListNode *pBehind = pList;
    while (pAhead->next != NULL)
    {
        pBehind = pBehind->next;
        pAhead = pAhead->next;
        if (pAhead->next != NULL)
        {
            pAhead = pAhead->next;
        }
    }
    return pBehind;
}

void reversePrintList(const ListNode *pList)
{
    if (pList == NULL)
    {
        return;
    }
    else
    {
       reversePrintList(pList->next);
       printf("%d\n", pList->data);
    }


}

void reversePrintStr(const char *str)
{
    if(*str == '\0')
    {
        return;
    }
    else
    {
        reversePrintStr(str+1);
        printf("%c", *str);
    }


}


int main()

{
    ListNode *pList = NULL;
    pList = createList(10);
    printf("********reversePrintList***********\n");
    reversePrintList(pList);
    printf("********getListLength***********\n");
    printf("%d\n", getListLength(pList));
    printf("********traverseList***********\n");
    traverseList(pList);
    printf("********reverseList***********\n");
    pList = reverseList(pList);
    traverseList(pList);
    printf("*********getRightKthNode**********\n");
    ListNode *pHead = getRightKthNode(pList, 6);
    printf("%d\n", pHead->data);
    printf("********getMiddleNode***********\n");
    pHead = getMiddleNode(pList);
    printf("%d\n", pHead->data);



    freeList(pList);


    reversePrintStr("abcde");

    return 0;

}

打印结果如下:



====================补充==========================================

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct node
{
    int data; //数据域
    struct node *next; //指针域
} SList;

SList * createList(int n) //创建单链表
{
    SList *pHead = NULL;
    for (int i = 0; i < n; i++)
    {
        SList *pNode = (SList*)malloc(sizeof(SList));
        pNode->data = i + 1;
        pNode->next = pHead;
        pHead = pNode;
    }

    return pHead;
}

void printList(SList *pList) //遍历单链表
{
    while(pList != NULL)
    {
        fprintf(stdout, "%d\n", pList->data);
        pList = pList->next;
    }
    printf("******************\n");
}

SList *addNodeToTail(SList *pList, int data) //结点加入链表尾
{
    SList *pHead = pList;

    SList *pNode = (SList*)malloc(sizeof(SList));
    pNode->data = data;
    pNode->next = NULL;

    if(pHead == NULL)
    {
        pHead = pNode;
        return pHead;
    }

    while (pHead->next != NULL)
    {
        pHead = pHead->next;
    }

    pHead->next = pNode;

    return pList;
}


SList *deleteNode(SList *pList, int data) //删除指定元素的值
{
    if (pList == NULL)
    {
        return pList;
    }

    SList *pHead = pList;
    SList *preHead = NULL;

    while(pHead != NULL)
    {
        if (pHead->data == data)
        {
            SList *deNode = pHead;
            pHead = pHead->next;
            if (NULL != preHead)
            {
                preHead->next = pHead;
            }
            else
            {
                pList = pHead;
            }
            free(deNode);
        }
        else
        {
            preHead = pHead;
            pHead = pHead->next;
        }
    }
    return pList;
}




int main()
{
    SList *pList = createList(5);
    printList(pList);

    pList = deleteNode(pList, 5);
    printList(pList);

    pList = addNodeToTail(pList, 1);
    printList(pList);

    pList = deleteNode(pList, 1);
    printList(pList);
    return 0;
}


Python爬虫实战:5分钟搞定政府网站公开数据抓取(附完整代码) 本文详细介绍了如何使用Python爬虫快速抓取政府网站公开数据,包括环境配置、网站结构分析、请求头构建、数据处理与存储等关键步骤。通过实战案例和完整代码,帮助开发者高效获取结构化数据,适用于数据分析、市场研究等场景。 阅读详情

相关推荐

当FPGA遇上Codesys:用Verilog实现ModbusTCP协议栈的3种方法(Xilinx/Vivado实测)

本文详细介绍了在Xilinx FPGA上使用Verilog实现Modbus TCP协议栈的三种方法,并与Codesys环境无缝集成。从基础架构设计到纯Verilog实现、基于AXI总线的混合方案,再到与Codesys的集成方法,为开发者提供了完整的工业自动化通信解决方案。通过实测数据对比,帮助开发者选择最优实现方案。

weixin_29172963的博客 522

经典链表问题:解析链表中的关键挑战

链表是常见的数据结构之一,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。链表的灵活性使得它在很多问题中都能发挥重要作用。 然而,链表问题也有其特殊性和挑战性。相较于数组,链表的访问和操作更为复杂,因为链表中的每个元素并不是按照顺序存储的。这一特性导致了在解决链表问题时需要采取特定的方法和技巧。 本文将从经典链表问题的角度出发,解析在解决链表问题时所面临的关键挑战。我们将深入探讨链表的基本特性及其对问题求解的影响,介绍一些常见的链表问题,并提供相应的解决策略和优化方法。

st200112266的博客 832

告别Nginx原始日志!VictoriaLogs+Grafana构建企业级应用日志分析平台实战

描述:做为一个合格的运维工程师,在面对企业安全运维管理中,日志审计是一项非常重要的工作。授人以鱼不如授人以渔,各位运友们可参照作者的方案设计,在自己的项目中根据实际情况调整落地,例如,不在仅仅采集 NGINX 应用日志,而是采集 Apache、Tomcat、SpringBoot 等多种应用服务器的日志,又如,不再仅仅采集网络设备、安全审计审计日志,而是 Windows、Linux 等多种操作系统的审计日志等,大家可充分发挥想象、实践能力,也欢迎大家在知识星球中分享自己的方案设计,一起交流学习。

全栈工程师修炼指南-IT知识分享 2477

全面理解链表数据结构:各种节点操作、做题技巧,易错点分析与题目清单(C++代码示例,不断更新)

我们都知道,单向链表这种数据结构都是由一个个节点组成的,那单向链表节点这种结构体都由什么组成呢?当然是由一个节点的值,与节点的一个next指针组成,以及构建节点的构造函数组成。其中节点的next指针,指向了该链表的下一个节点的元素位置。所以,当我们创建单向链表节点的这个结构体的时候,需要指定以下元素节点的值节点的next指针节点的构造函数(用于初始化一个新的节点,不然如何创建一个新的节点(链表)呢?int val;// 节点的值 ListNode * next;

weixin_49503250的博客 2385

W5500+STM32F103C8T6进行TCP通信(modbus)

一路生花一、w5500资料二、modbus通信三、从机代码四、总结五、参考 一、w5500资料 w5500的资料就放在下面了,单纯的客户端和其他模式上面有教程 https://www.aliyundrive.com/s/enPnnZgNtpE 二、modbus通信 Modbus RTU通信时使用的数据帧结构如下图,而Moubus TCP通信的数据帧和这个稍微不一样,没有crc检验,因为tcp本就是一种可靠传输协议 这里是Modbus TCP数据帧 公共功能码定义 三、从机代码

junseven164的博客 5777

Godot 4.x 实现 JRPG 回合制战斗系统:架构、状态机与实战优化

游戏开发中,状态机是管理复杂逻辑流转的核心设计模式,尤其在回合制战斗这类事件驱动的场景中。其原理是通过定义有限的状态和明确的转移条件,来控制系统在不同阶段的行为,从而实现清晰、可维护的流程控制。这项技术的价值在于能够将杂乱的条件判断代码结构化,降低模块间的耦合度,提升代码的可读性和可扩展性。在游戏开发领域,状态机广泛应用于角色AI、UI流程、战斗系统等场景。本文以Godot引擎为例,深入探讨如何运用节点与信号驱动架构,构建一个健壮的JRPG(日式角色扮演游戏)回合制战斗系统。内容涵盖从核心的**状态机**设

weixin_33749242的博客 499

链表常用技巧和操作总结

链表作为一种基础的数据结构,在算法中有着广泛的应用。掌握链表的常用操作和技巧,不仅能够帮助我们解决具体问题,还能在实际的编程中提升效率和代码质量。头插法:用于栈的实现和一些数据流反转操作。尾插法:适用于队列的实现和批量数据导入的场景。快慢指针找中间节点:在分割链表、回文链表检测、查找链表中点等问题中常用。逆序链表:常用于栈的反转和数据流反转等应用。合并有序链表:广泛应用于归并排序、数据流合并等问题中。判断链表是否有环:常用于循环链表检测,避免程序出现无限循环等问题。

Y_1215的博客 1367

《基于Yolo算法的火灾检测系统设计与实现》开题报告

在消防安全领域,火灾对生命财产安全构成严重威胁。传统的火灾检测手段存在诸多不足,如误报率高、检测范围有限、响应速度慢等。基于 Yolo 算法的火灾检测系统能够利用深度学习技术,实现对火灾的高效、精准检测,具有重要的现实意义。         从社会安全角度看,该系统可以广泛应用于各类公共场所、工业厂房和居民住宅,实时监测火灾隐患,及时发出警报,为人员疏散和消防救援争取宝贵时间,有效降低火灾造成的人员伤亡和财产损失,保障社会公共安全。

m0_69704149的博客 1384

c语言程序设计报告链表,C语言难点总结(二)----链表

所谓带有头节点的链表是指第一个节点中只有指针域有意义,数据域没有意义,其他的节点数据域存储相应的数据信息,指针域建立链接关系,它的原理示意图如下,注意最后一个节点的指针要置为NULL:链表的产生弥补了数组的诸多缺点,比如,数组在添加新元素时,如果添加的位置是数组的首部或者数组中间,那么,程序员不得不设计算法移动数组的相关元素,而且往往涉及的相关元素很多;再比如从数组中删除一个元素,如果删除的不是尾...

weixin_42393342的博客 424

【实战指南】RF-DETR多场景部署:从工业质检到自动驾驶的SOTA模型应用

本文深入解析了SOTA目标检测模型RF-DETR在工业质检与自动驾驶等多场景下的实战部署指南。该模型基于Transformer架构,在COCO数据集上实现了实时检测与高精度的突破,并凭借其强大的泛化能力,在RF100-VL等复杂数据集上表现出色。文章提供了从快速Demo、工业缺陷检测微调、车载自适应部署到多硬件平台性能优化的完整解决方案,帮助开发者高效应用这一先进模型。

weixin_29070861的博客 475

开源鸿蒙具身机器人(ROS2框架):从内核驱动到智能算法的完整实践

本指导文档旨在为开发者提供完整的开源鸿蒙(OpenHarmony)具身机器人开发解决方案,涵盖从底层驱动到上层ROS2应用的全栈开发流程。文档结合OpenHarmony内核驱动移植技术和ROS2机器人操作系统,为具身机器人开发提供详细的技术指导。具身机器人(Embodied Robot)是指具有物理实体、能够感知环境并与之交互的智能机器人系统。感知-决策-执行闭环多模态传感器融合(视觉、听觉、触觉、力觉)实时环境感知与理解智能决策与规划精确运动控制执行具身智能特性物理世界交互能力。

m0_67505153的博客 1268

巧学数据结构——链表

本文深入探讨链表数据结构及其实现。首先解析了链表的本质特征,包括节点组成、存储方式和主要类型(单链表、双链表、循环链表)。重点演示了单链表的实现过程,涵盖节点定义、创建、遍历、插入、删除等核心操作,并详细讲解了两种反转链表的算法(递归法和迭代法)。随后介绍了快慢指针技术在链表问题中的应用,包括查找中间节点、倒数第k个节点以及合并有序链表。最后阐述了双链表的实现原理及其优劣势分析,特别强调了双链表在双向遍历和高效删除方面的优势。全文通过大量代码示例和算法图解,系统性地讲解了链表的关键概念和实用技巧。

q17735269514的博客 2314

SCADA|KingSCADA通过组合框选择修改变量的值

《SCADA项目中组合框控件的使用方法》 本文详细介绍了SCADA系统中组合框(下拉框)控件的应用方法。通过具体示例演示如何实现:当选择"雷工笔记"时变量值为100,选择"雷工杂谈"时为200,选择"小李食代"时为300的功能。主要实现步骤包括:1)创建项目并添加组合框控件;2)设置Items选项及对应数值;3)创建内存变量;4)使用GetCurrentIndex()和GetItemData()方法;5)在选项变化事件中编写脚本。该控件在SCADA

做有价值的事,积累有价值的笔记! 864

【优选算法 | 链表】链表操作技巧:常见算法

链表是一种灵活的数据结构,广泛用于需要频繁插入和删除的场景。掌握链表的常见操作技巧,如插入、删除、翻转和合并等,能帮助开发者更高效地解决实际问题。接下来,我们将探讨一些常见的链表算法及其应用。

专注于 C/C++ 后端开发,涵盖基础语法、Linux系统与网络、MySQL数据库、常见算法及项目经验。 2211

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【算法学习】链表篇:链表的常用技巧和操作总结

【算法学习】链表篇:一篇带你搞懂链表的常用技巧和常用操作!!

2301_80220607的博客 4159

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Java栈、队列、链表常见算法浅析

数据是基础,算法是灵魂 本文出自门心叼龙的博客,属于原创类容,转载请注明出处。https://blog.youkuaiyun.com/geduo_83/article/details/86549973 这篇文章我们只谈算法的具体实现思考过程,并没有相关代码实现,代码的实现过程请参见我的另外一篇文章:Java数据结构与算法中级篇之栈、队列、链表 源码下载地址:https://download.csdn...

门心叼龙的专栏 5342

OV9734 DATASHEET,完整规格书

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

【Java算法】链表常用技巧和操作总结

在编程世界中,链表是一种非常重要的数据结构,它具有很多独特的优势和用途。今天,就让我们一起来总结一下链表的常用技巧和操作。链表的基本概念链表是一种线性数据结构,由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。链表的特点是可以动态地增长和收缩,不需要预先分配固定的存储空间。链表的常用技巧1.常画图--->直观形象,便于理解2.引入虚拟头结点处理边界情况方便操作链表3.不要吝啬空间,大胆定义变量(大胆定义变量)4.双指针。

2302_79806056的博客 1479

链表算法中常用操作和技巧

画图可以让一些抽象的文字语言更加形象生动画图!!!

2301_81831423的博客 1039

c++ 链表的创建与链表常见操作

C++链表的常见操作

weixin_46585382的博客 8934

JS 常见的链表操作

JS 常见的链表操作 单链表反转 链表中环的检测 相关问题 两个有序的链表合并 删除链表倒数第 n 个结点 求链表的中间结点 1. 单链表反转 // 判断对象是否为空 function isEmptyObject(obj) { for (var name in obj) { return false; } return true; } function Re...

林夏天的博客 2305

链表常见操作

链表常见类型 每一种新数据结构的出现都是为了解决原有数据结构的不足。链表的出现正是为了补充数组只能连续存储的不足。这种离散存储的方式自然携带了动态存储的特性。 单链表 单链表 是链表中最为常见的链表形式,链表中只有一个指向下一结点的指针。链表中的最后一个结点通常指向 NULL,表示链表的结束。 //Definition for singly-linked list. struct ListNod...

码农在途的博客 670

LeetCode链表(链表操作,反转链表,奇偶链表,排序链表)

本篇文章更注重于链表自身的特点。链表是一种通过指针串联在一起的线性结构。链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素中的引用字段链接在一起。链表的入口节点称为链表的头结点也就是head。(1)单链表每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。(2)双链表每一个节点有两个指针域。

ji_meng的博客 1820

【优选算法】(实战剖析链表核心操作技巧)

本文深入剖析链表的核心操作技巧,从底层原理到实战应用,系统讲解链表算法思想。文章首先介绍链表的存储原理与结构特点,包括节点组成、非连续内存分配和指针关联方式。针对链表操作中的常见痛点,如指针混乱和边界处理困难,重点拆解哨兵节点、快慢指针、三指针反转等核心技巧。通过LeetCode经典题目《两数相加》的实战案例,详细演示链表遍历、进位处理和结果构造的完整流程,提供可直接复用的C++代码模板与深度解析,帮助读者彻底打通链表操作逻辑,构建从理论到实践的完整知识体系。

承于所学,探技术之渊;以代码求政,寻成长之道。 1万+

链表 —— 常用技巧与操作总结详解

链表 —— 常用技巧与操作总结详解

祯的博客 1141

链表常见操作(三)链表长度与翻转

链表长度与翻转 谨以此纪念我在某尼划水的时光! /手动滑稽 继续熟悉链表吧, 接下来介绍使用频率最高的两个操作, 获取链表长度和翻转链表. 真的很简单, 但是使用频率非常高! 获取链表长度 首先, 很多人可能认为, 获取链表长度的复杂度是O(n), 代价很高. 其实不然, 我们用这个不等式作为复杂度的标尺: O(1) < O(logn)...

zhaoyangyingmu的博客 990

java单链表的实现及常见操作

java单链表的实现及常见操作 首先简单介绍一下链表: 链表是一种最基本的数据结构,是一种线性表,是一种物理存储单元上不连续、非顺序的存储结构,但是逻辑上相连。 不需要连续的内存空间,这点和数组相反。链表分为单链表,双向链表以及循环链表之类的,这里仅讨论单链表,别问为什么,因为其他的我还没学到,hhhh~ ok,直接看代码: public class LinkedList { priva...

橙子君的博客 2254
上一篇: 线性表之链式表示
下一篇: 几个经典算法研究
CodingGeek
博客等级 码龄18年 15粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值