深入理解C语言链表:数据结构的基石

在C语言的编程宇宙中,链表就像是一座稳固的基石,支撑着众多复杂程序的构建。它以独特的魅力和强大的功能,在解决各类编程难题时发挥着至关重要的作用。今天,就让我们一同深入探索链表的奥秘。

目录

一、链表初相识

二、链表的结构定义

三、链表的基本操作大揭秘

(一)创建新节点

(二)插入节点

头部插入

尾部插入

(三)删除节点

(四)遍历链表

四、链表的优势与应用场景

(一)优势

(二)应用场景



一、链表初相识

链表是一种线性数据结构,与内存中连续存储数据的数组截然不同,链表的元素在内存中的存储位置是离散的。它由一系列节点(Node)串连而成,每个节点都包含两个关键部分:

数据域:用于存储实际的数据,可以是整数、字符,甚至是复杂的结构体等各种数据类型。

指针域:存储着下一个节点在内存中的地址通过指针将各个节点按顺序连接起来,形成一条“链”。链表的最后一个节点的指针通常指向NULL,作为链表结束的标志。

二、链表的结构定义

在C语言中,借助结构体(struct)来定义链表节点,示例如下:

c

// 定义链表节点结构

struct Node {

    int data; // 数据域,这里存储整数

    struct Node* next; // 指针域,指向下一个节点

};

在这个定义中, struct Node 代表链表节点的类型。 data 成员用于存放具体的数据(这里设定为 int 类型); next 是一个指针,指向 struct Node 类型的对象,即下一个链表节点,如此构建起链表的链式结构。

三、链表的基本操作大揭秘

(一)创建新节点

创建新节点是链表操作的基础,每当要向链表添加新元素时,都需先创建一个新节点。


 

c

// 创建新节点的函数

struct Node* createNode(int value) {

    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

    if (newNode == NULL) {

        // 内存分配失败,通常是系统内存不足的情况

        fprintf(stderr, "内存分配失败\n");

        return NULL;

    }

    newNode->data = value;

    newNode->next = NULL;

    return newNode;

}



此函数中,首先使用 malloc 函数为新节点分配内存空间。若内存分配成功,将传入的值赋给新节点的数据域 data ,并将指针域 next 初始化为 NULL ,表示该新节点暂时是链表的最后一个节点。若内存分配失败,打印错误信息并返回 NULL 。

(二)插入节点

插入节点是常用操作,可在链表不同位置插入,常见的有头部插入尾部插入

头部插入

c

// 在链表头部插入节点的函数

struct Node* insertAtHead(struct Node* head, int value) {

    struct Node* newNode = createNode(value);

    if (newNode != NULL) {

        newNode->next = head;

        head = newNode;

    }

    return head;

}

头部插入时,先创建新节点 newNode 。然后让新节点的 next 指针指向当前头节点 head ,将新节点连接到原链表头部。最后,更新 head 为新节点,使其成为链表的头节点。

尾部插入


 

c

// 在链表尾部插入节点的函数

struct Node* insertAtTail(struct Node* head, int value) {

    struct Node* newNode = createNode(value);

    if (newNode == NULL) {

        return head;

    }

    if (head == NULL) {

        head = newNode;

    } else {

        struct Node* current = head;

        while (current->next != NULL) {

            current = current->next;

        }

        current->next = newNode;

    }

    return head;

}



尾部插入时,若链表为空( head 为 NULL ),直接将新节点赋值给 head ,新节点成为链表唯一节点。若链表不为空,通过循环遍历找到链表最后一个节点(即 current->next 为 NULL 的节点),然后将最后一个节点的 next 指针指向新节点,完成添加。

(三)删除节点

删除节点操作相对复杂,需先找到要删除节点的前一个节点,再修改其指针,绕过要删除的节点。


 

c

// 删除指定值节点的函数

struct Node* deleteNode(struct Node* head, int value) {

    if (head == NULL) {

        return head;

    }

    if (head->data == value) {

        struct Node* temp = head;

        head = head->next;

        free(temp);

        return head;

    }

    struct Node* current = head;

    while (current->next != NULL && current->next->data != value) {

        current = current->next;

    }

    if (current->next != NULL) {

        struct Node* temp = current->next;

        current->next = current->next->next;

        free(temp);

    }

    return head;

}



首先判断链表是否为空,若为空则直接返回 head 。若头节点数据是要删除的值,用临时指针 temp 保存头节点,更新 head 为头节点的下一个节点,释放 temp 指向的头节点内存,返回新的 head 。若要删除的节点不是头节点,通过循环找到其前一个节点 current 。若找到要删除的节点,用临时指针 temp 保存,将 current 的 next 指针指向要删除节点的下一个节点,绕过该节点,最后释放 temp 指向节点的内存。

(四)遍历链表

遍历链表是访问每个节点数据的过程,通常用循环结构实现。

c

// 遍历链表并打印节点数据的函数

void traverseList(struct Node* head) {

    struct Node* current = head;

    while (current != NULL) {

        printf("%d -> ", current->data);

        current = current->next;

    }

    printf("NULL\n");

}

此函数中,定义指针 current 并初始化为 head ,通过 while 循环,只要 current 不为 NULL ,就打印当前节点数据,并将 current 移到下一个节点。当 current 为 NULL 时,说明遍历到链表末尾,打印“NULL”表示结束。

四、链表的优势与应用场景

(一)优势

动态内存分配:链表无需预先知晓数据数量,可根据实际需求随时动态分配和释放内存。而数组声明时就需确定大小,灵活性不足。

高效的插入和删除:在已知插入或删除位置的情况下,链表插入和删除节点的时间复杂度为O(1),数组进行相同操作可能需移动大量元素,时间复杂度较高。

(二)应用场景

操作系统进程调度:操作系统管理多个进程时,链表可维护进程的就绪队列、阻塞队列等,便于进程的插入、删除和调度。

哈希表冲突解决:哈希表发生冲突时,常使用链表解决,将哈希值相同的元素存储在链表中。

图的邻接表存储:在图的存储结构中,邻接表常用链表表示每个顶点的邻接顶点,方便呈现图的复杂结构。

链表作为C语言编程中不可或缺的数据结构,熟练掌握其操作,对提升编程能力和解决实际问题意义重大。希望通过本文,大家能对链表有更深刻的理解与掌握,在编程之路上更进一步。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从头开始开发基于虹软SDK的人脸识别考勤系统(python+RTSP开源)(二)

今天咱们继续昨天的话题,今天的重点是看思路和代码了。废话不多说,直接上干货。 先说一句,为了省事,直接一个文件完成所有功能,可能在代码可读性上差一些,比较眼花缭乱哈哈。整个文件含空行代码共1931行&a…

报表控件stimulsoft操作:使用 Angular 应用程序的报告查看器组件

Stimulsoft Ultimate (原Stimulsoft Reports.Ultimate)是用于创建报表和仪表板的通用工具集。该产品包括用于WinForms、ASP.NET、.NET Core、JavaScript、WPF、PHP、Java和其他环境的完整工具集。无需比较产品功能,Stimulsoft Ultimate包含了…

【网络编程】WSAAsyncSelect 模型

十、基于I/O模型的网络开发 接着上次的博客继续分享:select模型 10.8 异步选择模型WSAAsyncSelect 10.8.1 基本概念 WSAAsyncSelect模型是Windows socket的一个异步I/O 模型,利用这个模型,应用程序 可在一个套接字上接收以Windows 消息为基…

从0开始的操作系统手搓教程43——实现一个简单的shell

目录 添加 read 系统调用,获取键盘输入 :sys_read putchar和clear 上班:实现一个简单的shell 测试上电 我们下面来实现一个简单的shell 添加 read 系统调用,获取键盘输入 :sys_read /* Read count bytes from the file pointed to by fi…

鸿蒙应用开发—数据持久化之SQLite

文章目录 SQLite简介创建数据库添加数据查询数据更新数据删除数据升级数据库使用事务参考 SQLite简介 SQLite是一个轻量级关系数据库,占用资源很少,只有几百KB的大小,无需服务器支撑,是一个零配置、事务性的SQL数据库引擎。 相对…

应急响应--流量分析

(一)Cobalt Strike流量特征分析 1.HTTP特征 源码特征: 在流量中,通过http协议的url路径,在checksum8解密算法计算后,32位的后门得到的结果是92,64位的后门得到的结果是93,该特征符…

初始化E9环境,安装Sqlserver数据库

title: 初始化E9环境,安装Sqlserver数据库 date: 2025-03-10 19:27:19 tags: E9SqlServer初始化E9环境,安装Sqlserver数据库 安装E9本地环境安装Sql server 数据库1、检查SQL Server服务是否开启2、检查SQL Server网络网络配置是否开启创建一个ecology数据库点击初始化数据库…

自然语言处理:无监督朴素贝叶斯模型

介绍 大家好,博主又来和大家分享自然语言处理领域的知识了,今天给大家介绍的是无监督朴素贝叶斯模型。 在自然语言处理这个充满挑战又极具魅力的领域,如何从海量的文本数据中挖掘有价值的信息,一直是研究者们不断探索的课题。无…

API调试工具的无解困境:白名单、动态IP与平台设计问题

引言 你是否曾经在开发中遇到过这样的尴尬情形:你打开了平台的API调试工具,准备一番操作,结果却发现根本无法连接到平台?别急,问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具,…

VSCode 2025最新前端开发必备插件推荐汇总(提效指南)

🌟前言: 如果你是一名前端开发工程师,合适的开发工具能大大提高工作效率。Visual Studio Code (VSCode) 凭借其轻量级、高扩展性的特点,已成为众多前端开发者在win系电脑的首选IDE。 名人说:博观而约取,厚积而薄发。—…

小程序事件系统 —— 33 事件传参 - data-*自定义数据

事件传参:在触发事件时,将一些数据作为参数传递给事件处理函数的过程,就是事件传参; 在微信小程序中,我们经常会在组件上添加一些自定义数据,然后在事件处理函数中获取这些自定义数据,从而完成…

初阶数据结构(C语言实现)——4.2队列

目录 2.队列2.1队列的概念及结构2.2队列的实现2.2.1 初始化队列2.2.2 销毁队列2.2.3 队尾入队列2.2.4 队头出队列2.2.5获取队列头部元素2.2.6 获取队列队尾元素2.2.7获取队列中有效元素个数2.2.8 检测队列是否为空,如果为空返回非零结果,如果非空返回0 3…

linux 命令 cat

cat 是 Linux 中用于查看、创建和合并文件的常用命令,全称 concatenate(连接)。其核心功能是将文件内容输出到终端或重定向到其他文件/命令中。以下是详细用法及场景示例: 基本语法 cat [选项] [文件1] [文件2] ... 选项…

TON基金会确认冠名赞助2025香港Web3嘉年华,并将于4月8日重磅呈现“TON生态日”

近日,由万向区块链实验室与HashKey Group联合推出的Web3年度盛典——2025香港Web3嘉年华正式宣布,TON基金会确认成为本届嘉年华的冠名赞助商,并将于4月8日在主会场特别举办“TON生态日”专题Side Event,集中展现TON生态的最新技术…

【Java代码审计 | 第七篇】文件上传漏洞成因及防范

未经许可,不得转载。 文章目录 文件上传漏洞漏洞成因未验证文件类型和扩展名未限制文件上传路径 防范验证文件类型和扩展名验证文件内容限制文件上传路径使用安全的文件上传库 标准代码 文件上传漏洞 文件上传漏洞是指攻击者通过上传恶意文件(如可执行脚…

【无人机路径规划】基于麻雀搜索算法(SSA)的无人机路径规划(Matlab)

效果一览 代码获取私信博主基于麻雀搜索算法(SSA)的无人机路径规划(Matlab) 一、算法背景与核心思想 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种受麻雀群体觅食行为启发的元启发式算法&#xff0…

狮子座大数据分析(python爬虫版)

十二星座爱情性格 - 星座屋 首先找到一个星座网站,作为基础内容,来获取信息 网页爬取与信息提取 我们首先利用爬虫技术(如 Python 中的 requests 与 BeautifulSoup 库)获取页面内容。该页面(xzw.com/astro/leo/&…

DeepSeek教我写词典爬虫获取单词的音标和拼写

Python在爬虫领域展现出了卓越的功能性,不仅能够高效地抓取目标数据,还能便捷地将数据存储至本地。在众多Python爬虫应用中,词典数据的爬取尤为常见。接下来,我们将以dict.cn为例,详细演示如何编写一个用于爬取词典数据…

AI智能导航站HTML5自适应源码帝国cms7.5模板

源码名称:AI导航站HTML5自适应源码帝国cms7.5模板 开发环境:帝国cms 7.5 安装环境:phpmysql var code "4d33ef8e-9e38-43b9-b37b-38f75944ecc9" 带软件采集,可以挂着自动采集发布,无需人工操作&#xff0…

【贪心算法】将数组和减半的最小操作数

1.题目解析 2208. 将数组和减半的最少操作次数 - 力扣(LeetCode) 2.讲解算法原理 使用当前数组中最大的数将它减半,,直到数组和减小到一半为止,从而快速达到目的 重点是找到最大数,可以采用大根堆快速达到…