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

C语言:链表

链表

  • 介绍
    • 单向链表
    • 节点结构
    • 创建节点
    • 插入节点
    • 删除节点
    • 遍历链表
    • 尾部插入
    • 查找节点
    • 链表反转
    • 示例程序
      • 程序1
      • 程序2

介绍

链表是一种常见的数据结构,用于存储一系列线性数据。与数组不同,链表中的元素在内存中不必是连续存放的,而是通过指针将每个元素(节点)链接在一起。链表有很多种类型,例如单向链表、双向链表和循环链表。这里我们主要介绍单向链表。

单向链表

单向链表由一系列节点组成,每个节点包含两个部分:

  1. 数据部分:存储节点的实际内容。
  2. 指针部分:存储指向下一个节点的指针。

节点结构

在 C 语言中,我们可以通过定义一个结构体来表示链表的节点:

struct Node {int data;          // 数据部分struct Node* next; // 指针部分
};

创建节点

可以通过动态内存分配函数 malloc 来创建新节点:

#include <stdio.h>
#include <stdlib.h>// 定义节点结构
struct Node {int data;struct Node* next;
};// 创建新节点
struct Node* createNode(int data) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));if (!newNode) {printf("内存分配失败\n");exit(1);}newNode->data = data;newNode->next = NULL;return newNode;
}

插入节点

我们可以在链表的头部或尾部插入节点。以头部插入为例:

// 头部插入
void insertAtHead(struct Node** head, int data) {struct Node* newNode = createNode(data);newNode->next = *head;*head = newNode;
}

删除节点

删除链表中的节点也很常见。假设我们要删除值为 key 的节点:

void deleteNode(struct Node** head, int key) {struct Node* temp = *head;struct Node* prev = NULL;// 如果头节点本身就是要删除的节点if (temp != NULL && temp->data == key) {*head = temp->next;free(temp); // 释放内存return;}// 搜索要删除的节点while (temp != NULL && temp->data != key) {prev = temp;temp = temp->next;}// 如果没找到要删除的节点if (temp == NULL) return;// 断开链接并释放内存prev->next = temp->next;free(temp);
}

遍历链表

遍历链表可以通过循环来实现:

void printList(struct Node* head) {struct Node* current = head;while (current != NULL) {printf("%d -> ", current->data);current = current->next;}printf("NULL\n");
}

尾部插入

尾部插入与头部插入类似,我们需要找到链表的最后一个节点,然后将新节点添加到末尾。

// 尾部插入
void insertAtTail(struct Node** head, int data) {struct Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;return;}struct Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}

查找节点

查找链表中的某个节点,返回其位置或者指针:

struct Node* searchNode(struct Node* head, int key) {struct Node* current = head;while (current != NULL) {if (current->data == key) {return current;}current = current->next;}return NULL; // 未找到
}

链表反转

反转链表是一个经典的问题,可以通过迭代的方式实现:

void reverseList(struct Node** head) {struct Node* prev = NULL;struct Node* current = *head;struct Node* next = NULL;while (current != NULL) {next = current->next; // 暂存下一个节点current->next = prev; // 反转当前节点的指针prev = current;       // 移动 prev 指针current = next;       // 移动 current 指针}*head = prev;
}

示例程序

程序1

#include <stdio.h>
#include <stdlib.h>struct Node {int data;struct Node* next;
};struct Node* createNode(int data) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));if (!newNode) {printf("内存分配失败\n");exit(1);}newNode->data = data;newNode->next = NULL;return newNode;
}void insertAtHead(struct Node** head, int data) {struct Node* newNode = createNode(data);newNode->next = *head;*head = newNode;
}void deleteNode(struct Node** head, int key) {struct Node* temp = *head;struct Node* prev = NULL;if (temp != NULL && temp->data == key) {*head = temp->next;free(temp);return;}while (temp != NULL && temp->data != key) {prev = temp;temp = temp->next;}if (temp == NULL) return;prev->next = temp->next;free(temp);
}void printList(struct Node* head) {struct Node* current = head;while (current != NULL) {printf("%d -> ", current->data);current = current->next;}printf("NULL\n");
}int main() {struct Node* head = NULL;insertAtHead(&head, 1);insertAtHead(&head, 2);insertAtHead(&head, 3);printf("Created Linked List: ");printList(head);deleteNode(&head, 2);printf("Linked List after deletion of 2: ");printList(head);return 0;
}

输出结果:
在这里插入图片描述

程序2

#include <stdio.h>
#include <stdlib.h>// 定义节点结构
struct Node {int data;struct Node* next;
};// 创建新节点
struct Node* createNode(int data) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));if (!newNode) {printf("内存分配失败\n");exit(1);}newNode->data = data;newNode->next = NULL;return newNode;
}// 头部插入
void insertAtHead(struct Node** head, int data) {struct Node* newNode = createNode(data);newNode->next = *head;*head = newNode;
}// 尾部插入
void insertAtTail(struct Node** head, int data) {struct Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;return;}struct Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}// 删除节点
void deleteNode(struct Node** head, int key) {struct Node* temp = *head;struct Node* prev = NULL;if (temp != NULL && temp->data == key) {*head = temp->next;free(temp);return;}while (temp != NULL && temp->data != key) {prev = temp;temp = temp->next;}if (temp == NULL) return;prev->next = temp->next;free(temp);
}// 查找节点
struct Node* searchNode(struct Node* head, int key) {struct Node* current = head;while (current != NULL) {if (current->data == key) {return current;}current = current->next;}return NULL;
}// 反转链表
void reverseList(struct Node** head) {struct Node* prev = NULL;struct Node* current = *head;struct Node* next = NULL;while (current != NULL) {next = current->next;current->next = prev;prev = current;current = next;}*head = prev;
}// 打印链表
void printList(struct Node* head) {struct Node* current = head;while (current != NULL) {printf("%d -> ", current->data);current = current->next;}printf("NULL\n");
}int main() {struct Node* head = NULL;insertAtHead(&head, 1);insertAtHead(&head, 2);insertAtHead(&head, 3);printf("初始链表: ");printList(head);// 测试尾部插入insertAtTail(&head, 4);printf("尾部插入 4 后的链表: ");printList(head);// 测试删除节点deleteNode(&head, 2);printf("删除节点 2 后的链表: ");printList(head);// 测试查找节点struct Node* foundNode = searchNode(head, 3);if (foundNode) {printf("找到节点 3\n");} else {printf("未找到节点 3\n");}// 测试反转链表reverseList(&head);printf("反转后的链表: ");printList(head);return 0;
}

输出结果:
在这里插入图片描述

相关文章:

C语言:链表

链表 介绍单向链表节点结构创建节点插入节点删除节点遍历链表尾部插入查找节点链表反转示例程序程序1程序2 介绍 链表是一种常见的数据结构&#xff0c;用于存储一系列线性数据。与数组不同&#xff0c;链表中的元素在内存中不必是连续存放的&#xff0c;而是通过指针将每个元…...

【git使用二】gitee远程仓库创建与本地git命令用法

目录 gitee介绍 管理者注册gitee账号 管理者在gitee网站上创建远程仓库 每个开发者安装git与基本配置 1.git的下载和安装 2.配置SSH公钥 3.开发者信息配置 git命令用法 gitee介绍 Gitee&#xff08;又称码云&#xff09;是一个基于Git的代码托管服务&#xff0c;由开源…...

明星百科大全PHP网站源码

源码介绍 明星百科大全网站源码&#xff0c;国内外明星娱乐音乐、新闻八卦、写真照片、相关影视作品等等的明星百科网站源码。 源码截图 源码下载 明星百科大全PHP网站源码...

白酒:茅台镇白酒的品鉴会与文化交流活动

茅台镇&#xff0c;这个位于中国贵州省的小镇&#xff0c;因其与众不同的自然环境和杰出的酿酒工艺而成为世界著名的白酒产区。云仓酒庄豪迈白酒作为茅台镇的品牌&#xff0c;积极参与各种品鉴会和文化交流活动&#xff0c;向世界展示了中国白酒的魅力和文化底蕴。 近年来&…...

python中列表结构在点云数据处理中用法

1、前言 Python中的列表&#xff08;list&#xff09;是一种可变的序列类型&#xff0c;用于存储集合数据。列表用途非常广泛&#xff0c;包括但不限于以下几个方面&#xff1a; 存储集合数据&#xff1a;列表用于存储一系列有序的元素&#xff0c;这些元素可以是任何数据类型&…...

土耳其(小亚细亚)历史上的各个阶段

一个国家的历史书写方式有两种&#xff0c;其一是按本国主体民族的渊源&#xff0c;其二是本国国土内发生的都属于本国史。一般来说&#xff0c;这两种方式相当程度上是重合的&#xff0c;但也有例外&#xff0c;比如本文要讲述的土耳其。 土耳其的国土并不辽阔&#xff0c;其…...

Windows下基于Frida查看内存基址和修改寄存器

使用Frida能够方便地获取到DLL基址&#xff0c;还能修改寄存器值。首先要通过任务管理器获得进程的PID&#xff0c;然后写Python脚本把Frida附加到这个PID进程&#xff0c;根据IDA分析出来的函数地址&#xff0c;HOOK到目标函数&#xff0c;修改寄存器的值&#xff0c;最终实现…...

2024中国网络安全产品用户调查报告(发布版)

自2020年始&#xff0c;人类进入了21世纪的第二个十年&#xff0c;全球进入了百年未有之大变局&#xff0c;新十年的开始即被新冠疫情逆转了全球化发展的历程&#xff0c;而至2022年3月俄乌战争又突然爆发&#xff0c;紧接着2023年7月“巴以冲突"皱起&#xff0c;世界快速…...

手写图片懒加载

参考来自前辈 Aidan路修远i 的文章面试官&#xff1a;请你手写一下&#xff01;懒加载 - 掘金 (juejin.cn) Hello.vue <template><div><!-- src里面为空&#xff0c;data-original里面写图片真正的url(此处省略) --><img src"" data-origina…...

大型语言模型(LLMs)的后门攻击和防御技术

大型语言模型&#xff08;LLMs&#xff09;通过训练在大量文本语料库上&#xff0c;展示了在多种自然语言处理&#xff08;NLP&#xff09;应用中取得最先进性能的能力。与基础语言模型相比&#xff0c;LLMs在少样本学习和零样本学习场景中取得了显著的性能提升&#xff0c;这得…...

力扣2594.修车的最少时间

力扣2594.修车的最少时间 二分答案 class Solution {public:long long repairCars(vector<int>& ranks, int cars) {ranges::sort(ranks);auto check [&](long long x) -> bool{long long res 0;for(auto v : ranks){long long k sqrt(x/v);res k;if(r…...

攻防演练之-成功的钓鱼邮件溯源

书接上文&#xff0c;《网络安全攻防演练风云》专栏之攻防演练之-网络安全产品大巡礼二&#xff0c;这里。 演练第一天并没有太大的波澜&#xff0c;白天的时间过得很快。夜色降临&#xff0c;攻防演练中心内的灯光依旧明亮。对于网络安全团队来说&#xff0c;夜晚和白天并没有…...

Gi标签管理

文章目录 前言理解标签创建标签操作标签总结 前言 理解标签 标签&#xff0c;可以理解为对某次commit的一次标识&#xff0c;相当于起起了一个别名。 例如&#xff0c;在项目发布某个版本时候&#xff0c;针对最后一次commit起一个v1.0这样的标签来标识里程碑的意义。 这有什…...

2024福建等保测评公司有哪些?分别叫做什么名字?

2024福建等保测评公司有哪些&#xff1f;分别叫做什么名字&#xff1f; 【回答】&#xff1a;2024年具有资质的福建等保测评公司有6家&#xff0c;其名称以及地址如下&#xff1a; 1、福建省网络与信息安全测评中心&#xff0c;福州市鼓楼区东街8号利达大厦A座8层&#xff1b…...

王先宏老师厉害了,活页笔记版古琴曲谱拆箱图

王先宏老师走心了&#xff0c;活页笔记版古琴曲谱拆箱图&#xff0c;简直是史上最好的古琴学习利器&#xff01;送的防滑垫还带铝合金夹层的&#xff0c;养弦膏都是市面上没有的的。 这些古琴谱上的笔记就是老师课堂上用的&#xff0c;直接拿来就可以跟着弹&#xff0c;不用您…...

TalkingData 是一家专注于提供数据统计和分析解决方案的独立第三方数据智能服务平台

TalkingData 是一家专注于提供数据统计和分析解决方案的独立第三方数据智能服务平台。通过搜索结果&#xff0c;我们可以了解到 TalkingData 的一些关键特性和市场情况&#xff0c;并将其与同类型产品进行比较。 TalkingData 产品特性 数据统计与分析&#xff1a;提供专业的数…...

Springboot的小型超市商品展销系统-计算机毕业设计源码01635

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…...

UV胶开裂主要因素有哪些?如何避免?

UV胶开裂主要因素有哪些&#xff1f;如何避免&#xff1f; UV胶开裂的原因可能包括多个方面&#xff1a; 固化不足&#xff1a;UV胶的固化需要足够的紫外线照射。如果照射时间不够&#xff0c;或者紫外线光源的强度不足&#xff0c;胶水可能没有完全固化&#xff0c;从而导致开…...

LogicFlow 学习笔记——3. LogicFlow 基础 节点 Node

节点 Node LogicFlow 内置了一些基础节点&#xff0c;开发者在实际应用场景中&#xff0c;可以基于这些基础节点&#xff0c;定义符合自己业务逻辑的节点。 认识基础节点 LogicFlow是基于svg做的流程图编辑框架&#xff0c;所以我们的节点和连线都是svg基本形状&#xff0c;…...

VMware清理拖拽缓存

磁盘空间越用越小&#xff0c;如何快速解决磁盘空间的问题&#xff0c;甩掉烦恼 安装VM tools之后可以通过拖拽的方式把文件拉入虚拟机之中。但每一次拖拽&#xff0c;其实都是现在cache文件夹里面生成一个同样的文件&#xff0c;并使用cp拷贝的方式将其拷贝到拖拽放置的目录中…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...