链式存储结构通过使用指针将分散的存储单元链接起来,每个元素由数据部分和指针部分组成。

链式表的定义和特点

链式表的每个节点包含两个部分:

  1. 数据域:存储数据元素。
  2. 指针域:存储下一个节点的内存地址。

链式表的头指针指向第一个节点,最后一个节点的指针域为NULL,表示链表结束。链式表的特点是插入和删除操作比较方便,不需要移动大量元素,但随机访问效率较低。

示例代码:链式表的实现及取值操作(C语言)

#include <stdio.h>
#include <stdlib.h>// 定义链式表节点结构
typedef struct Node {int data;             // 数据域struct Node *next;    // 指针域,指向下一个节点
} Node;// 创建新节点
Node* create_node(int value) {Node *new_node = (Node*)malloc(sizeof(Node));  // 分配内存if (new_node == NULL) {printf("内存分配失败\n");exit(1);  // 分配失败则退出程序}new_node->data = value;  // 设置节点数据new_node->next = NULL;   // 初始化指针为NULLreturn new_node;  // 返回新节点的指针
}// 在链表尾部插入节点
void append(Node **head, int value) {Node *new_node = create_node(value);  // 创建新节点if (*head == NULL) {  // 如果链表为空*head = new_node;  // 新节点成为头节点return;}Node *current = *head;  // 从头节点开始遍历while (current->next != NULL) {  // 找到链表的最后一个节点current = current->next;}current->next = new_node;  // 将新节点链接到链表末尾
}// 获取指定位置的元素值
int get_value(Node *head, int pos, int *value) {if (head == NULL) {  // 如果链表为空printf("链表为空\n");return 0;  // 返回0表示失败}Node *current = head;int index = 0;while (current != NULL) {  // 遍历链表if (index == pos) {  // 找到指定位置*value = current->data;  // 获取节点数据return 1;  // 返回1表示成功}current = current->next;  // 移动到下一个节点index++;}printf("位置超出范围\n");  // 如果遍历完链表也没找到指定位置return 0;  // 返回0表示失败
}// 打印链表
void print_list(Node *head) {Node *current = head;printf("链表内容:");while (current != NULL) {printf("%d ", current->data);current = current->next;}printf("\n");
}// 释放链表内存
void free_list(Node *head) {Node *current = head;while (current != NULL) {Node *temp = current;current = current->next;free(temp);}
}int main() {Node *head = NULL;  // 初始化链表为空append(&head, 10);  // 向链表尾部添加元素10append(&head, 20);  // 向链表尾部添加元素20append(&head, 30);  // 向链表尾部添加元素30print_list(head);  // 打印链表内容int value;if (get_value(head, 1, &value)) {  // 获取索引1的元素值printf("索引1的元素值:%d\n", value);}free_list(head);  // 释放链表内存return 0;
}

代码各模块注释

定义链式表节点结构

typedef struct Node {int data;             // 数据域struct Node *next;    // 指针域,指向下一个节点
} Node;
  • 定义了一个名为 Node 的结构体类型,表示链式表的节点。
  • int data; 用于存储节点的数据。
  • struct Node *next; 是一个指向 Node 类型的指针,用于存储下一个节点的内存地址。

创建新节点

Node* create_node(int value) {Node *new_node = (Node*)malloc(sizeof(Node));  // 分配内存if (new_node == NULL) {printf("内存分配失败\n");exit(1);  // 分配失败则退出程序}new_node->data = value;  // 设置节点数据new_node->next = NULL;   // 初始化指针为NULLreturn new_node;  // 返回新节点的指针
}
  • Node *new_node = (Node*)malloc(sizeof(Node)); 使用 malloc 函数动态分配内存,为新节点分配大小为 sizeof(Node) 的内存空间。
  • if (new_node == NULL) { ... } 检查内存分配是否成功。如果失败,打印错误信息并退出程序。
  • new_node->data = value; 将传入的 value 值赋给新节点的数据域。
  • new_node->next = NULL; 将新节点的指针域初始化为 NULL,表示该节点目前没有指向下一个节点。
  • return new_node; 返回新创建的节点的指针。

在链表尾部插入节点

void append(Node **head, int value) {Node *new_node = create_node(value);  // 创建新节点if (*head == NULL) {  // 如果链表为空*head = new_node;  // 新节点成为头节点return;}Node *current = *head;  // 从头节点开始遍历while (current->next != NULL) {  // 找到链表的最后一个节点current = current->next;}current->next = new_node;  // 将新节点链接到链表末尾
}
  • Node *new_node = create_node(value); 调用 create_node 函数创建一个新节点。
  • if (*head == NULL) { ... } 检查链表是否为空。如果链表为空(头指针为 NULL),将新节点设置为头节点。
  • Node *current = *head; 定义一个指针 current,初始化为链表的头节点,用于遍历链表。
  • while (current->next != NULL) { ... } 遍历链表,直到找到最后一个节点(其 next 指针为 NULL)。
  • current->next = new_node; 将最后一个节点的 next 指针指向新节点,将新节点添加到链表末尾。

获取指定位置的元素值

int get_value(Node *head, int pos, int *value) {if (head == NULL) {  // 如果链表为空printf("链表为空\n");return 0;  // 返回0表示失败}Node *current = head;int index = 0;while (current != NULL) {  // 遍历链表if (index == pos) {  // 找到指定位置*value = current->data;  // 获取节点数据return 1;  // 返回1表示成功}current = current->next;  // 移动到下一个节点index++;}printf("位置超出范围\n");  // 如果遍历完链表也没找到指定位置return 0;  // 返回0表示失败
}
  • if (head == NULL) { ... } 检查链表是否为空。如果为空,打印错误信息并返回0表示失败。
  • Node *current = head; 定义一个指针 current,初始化为链表的头节点,用于遍历链表。
  • int index = 0; 用于记录当前遍历到的节点位置。
  • while (current != NULL) { ... } 遍历链表,直到 currentNULL(链表结束)。
  • if (index == pos) { ... } 检查当前节点的位置是否为目标位置 pos。如果是,将当前节点的数据赋值给 *value,并返回1表示成功。
  • current = current->next; 移动 current 指针到下一个节点。
  • index++; 增加位置计数器。
  • 如果遍历完整个链表都没有找到目标位置,打印错误信息并返回0表示失败。

打印链表

void print_list(Node *head) {Node *current = head;printf("链表内容:");while (current != NULL) {printf("%d ", current->data);current = current->next;}printf("\n");
}
  • Node *current = head; 定义一个指针 current,初始化为链表的头节点,用于遍历链表。
  • printf("链表内容:"); 打印提示信息。
  • while (current != NULL) { ... } 遍历链表,直到 currentNULL
  • printf("%d ", current->data); 打印当前节点的数据。
  • current = current->next; 移动 current 指针到下一个节点。
  • printf("\n"); 打印换行符,换行。

释放链表内存

void free_list(Node *head) {Node *current = head;while (current != NULL) {Node *temp = current;current = current->next;free(temp);}
}
  • Node *current = head; 定义一个指针 current,初始化为链表的头节点,用于遍历链表。
  • while (current != NULL) { ... } 遍历链表,直到 currentNULL
  • Node *temp = current; 保存当前节点的指针到 temp
  • current = current->next; 移动 current 指针到下一个节点。
  • free(temp); 释放 temp 指向的节点内存。

主函数

int main() {Node *head = NULL;  // 初始化链表为空append(&head, 10);  // 向链表尾部添加元素10append(&head, 20);  // 向链表尾部添加元素20append(&head, 30);  // 向链表尾部添加元素30print_list(head);  // 打印链表内容int value;if (get_value(head, 1, &value)) {  // 获取索引1的元素值printf("索引1的元素值:%d\n", value);}free_list(head);  // 释放链表内存return 0;
}
  • Node *head = NULL; 声明一个指向 Node 的指针 head,并初始化为 NULL,表示链表为空。
  • append(&head, 10); 调用 append 函数向链表尾部添加元素10。
  • append(&head, 20); 向链表尾部添加元素20。
  • append(&head, 30); 向链表尾部添加元素30。
  • print_list(head); 调用 print_list 函数打印链表的内容。
  • int value; 声明一个整型变量 value,用于存储获取的元素值。
  • if (get_value(head, 1, &value)) { ... } 调用 get_value 函数尝试获取索引1处的元素值。如果成功,打印该值。
  • free_list(head); 调用 free_list 函数释放链表占用的内存。
  • return 0; 返回0,表示程序正常结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89752.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89752.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/89752.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

达梦数据库DMHS介绍及安装部署

目录 概述 安装规划 安装步骤 上传安装包 更改权限 执行安装命令 源端和目的端处理 开启归档 开启逻辑日志 创建测试表 生成测试数据 配置目的端文件 配置源端文件 启动目的端 启动源端 装载数据 源端开启cpt模块 数据同步验证 随机数据验证 概述 达梦数据实时同…

BERT 模型详解:结构、原理解析

前言 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;已经成为理解类任务的标配模型。相比 GPT 更擅长文本生成&#xff0c;BERT 则在语言理解任务上展现出卓越的能力。本文…

一、bfv_basics

目录 一、加密参数 EncryptionParameters类1. 三个重要的参数2. 参数的作用3. 同态加密方案4. 多项式模数的度 poly_modulus_degree (n)5. 密文模数 coeff_modulus (q)6. 明文模数 plain_modulus (t&#xff0c;这是 BFV 方案才有的&#xff0c;CKKS 没有) 二、上下文 SEALCont…

AI大模型LangChain架构介绍及其在环保领域的应用

1.LangChain 概述与架构 LangChain 是一个面向大型语言模型&#xff08;LLM&#xff09;应用的开发框架&#xff0c;其核心理念是将复杂的基于语言的 AI 系统拆分为可复用的模块&#xff0c;简化 LLM 与数据源的集成。LangChain 官方文档将其定义为“一个用于开发以 LLM 为驱动…

centos 7 安装NVIDIA Container Toolkit

要在 CentOS 7 上离线安装 NVIDIA Container Toolkit&#xff0c;需确保已安装 NVIDIA 驱动和 Docker 环境。以下是完整步骤及注意事项&#xff1a; ⚙️ 一、环境准备 验证 NVIDIA 驱动 运行 nvidia-smi 确认驱动已正确安装&#xff0c;若未安装需先离线安装驱动&#xff1a; …

C++学习之STL学习:list的使用

本篇我们将学习STL中list的使用 目录 list的初始和官方文档 list的官方文档 list的构造与析构 构造函数 析构函数 运算符重载 迭代器 正向迭代器 反向迭代器 const正向迭代器 const反向迭代器 容量 empty size max_size 访问 访问第一个元素​编辑 访问最后一个元素 修…

USB服务器在证券公司虚拟化进程中的应用分析

在证券公司全面拥抱虚拟化、云化的技术浪潮中&#xff0c;一个看似微小却至关重要的环节曾长期阻碍进程&#xff1a;分散在各业务环节的银行前置机U盾、各种系统认证Ukey等物理USB安全设备的管理难题。这些承载着资金划拨、交易认证核心权限的“小钥匙”&#xff0c;在传统模式…

网闸内部架构设计:分层与微服务的生死博弈

引言 “物理隔离是网闸的命脉,而架构设计决定其生死。” 在数据安全领域,网闸(安全隔离与信息交换系统)是守护核心网络的钢铁长城。但当开发者试图将现代架构思想(如微服务)引入其内部时,却可能引发灾难性冲突。本文通过深度拆解分层架构与微服务在网闸中的适用性,揭示…

通过MaaS平台免费使用大模型API

文章目录 一、引言&#xff1a;MaaS平台——免费使用大模型API的新选择二、模型代码与限制术语详解&#xff08;一&#xff09;模型代码含义解析&#xff08;二&#xff09;模型使用限制术语缩写详解 三、5个MaaS平台详细介绍&#xff08;一&#xff09;OpenRouter&#xff08;…

进程代理单窗口单IP技术:原理、应用与实现

“在当今数字化时代&#xff0c;网络隐私保护与多账号管理需求日益增长。单窗口单IP技术通过为每个进程分配独立网络身份&#xff0c;巧妙地解决了多账号管理中的IP关联难题。从游戏多开防封到数据采集优化&#xff0c;从隐私保护到测试验证&#xff0c;这项技术的应用场景不断…

Java教程——线程池和future

Future 详解 1. Future 是什么? Future 是 Java 中的一个接口(java.util.concurrent.Future),代表异步计算的未来结果。它允许你: 提交任务后立即返回在需要时检查任务是否完成获取任务结果(完成后)取消任务2. 怎么使用 Future? 通过线程池提交任务: ExecutorServ…

洛谷P1351 [NOIP 2014 提高组] 联合权值

洛谷P1351 [NOIP 2014 提高组] 联合权值 洛谷题目传送门 题目背景 NOIP2014 提高组 D1T2 题目描述 无向连通图 G G G 有 n n n 个点&#xff0c; n − 1 n-1 n−1 条边。点从 1 1 1 到 n n n 依次编号,编号为 i i i 的点的权值为 W i W_i Wi​&#xff0c;每条边的长…

Apache Doris Profile 深度解析:从获取到分析,解锁查询性能优化密码

在 Doris 数据库中&#xff0c;高效的查询性能是数据处理的关键。当我们遇到查询缓慢、资源消耗异常等问题时&#xff0c;Doris 提供的 Profile 工具就如同一位 “性能侦探”&#xff0c;能帮我们抽丝剥茧&#xff0c;找到问题根源。今天&#xff0c;我们就来深入聊聊如何分析 …

系统架构师

硬件&#xff1a; 运算器&#xff1a;1&#xff09;算术运算 加减乘除 2&#xff09;逻辑运算并进行逻辑测试&#xff1a;与或非 组件功能&#xff1a;算术逻辑单元ALU :处理数据 实现对数据的算术运算和逻辑运算 累加寄存器AC 通用寄存器&#xff0c;alu提供工作区 暂存运算结…

Unity HDRP + Azure IoT 工业设备监控系统实例

Unity HDRP Azure IoT 工业设备监控系统实例 下面是一个完整的工业设备监控解决方案&#xff0c;结合Unity HDRP&#xff08;高清渲染管线&#xff09;的高质量可视化与Azure IoT的实时数据处理能力。 系统架构 #mermaid-svg-XJnD6acrBbtbqYHW {font-family:"trebuchet…

(超详细)数据库项目初体验:使用C语言连接数据库完成短地址服务(本地运行版)

数据库项目初体验&#xff1a;使用C语言连接数据库完成短地址服务&#xff08;本地运行版&#xff09; 前言&#xff1a;初学者的思考 作为一个刚初学数据库的小白并且在之前我的博客中我有尝试使用C语言写过一个短地址服务&#xff0c;但是使用C语言编写的短地址服务只有短记…

mysql基础(一)快速上手篇

连接mysql 使用命令行窗口连接mysql数据库 语法&#xff1a;mysql –h主机名 –u用户名 –p密码 说明&#xff1a;-h参数指定数据库ip&#xff0c;本地服务器可以用localhost&#xff0c;-u参数指定用户名&#xff0c;-p参数指定用户密码。 注意&#xff1a;-p和密码值之间…

IntelliJ IDEA 2025- 下载安装教程图文版详细教程(附激活码)

目录 写在前面 一、介绍 二、下载 三、安装 &#x1f3c1; 写在最后 写在前面 > &#x1f680; 初学 Java&#xff1f;或者刚开始写项目&#xff0c;不知道该选哪个 IDE&#xff1f; 本篇教程手把手教你安装 IntelliJ IDEA —— JetBrains 出品的顶级 Java 开发环境&a…

数学经济专业大学四年规划

数学经济专业结合了数学的逻辑严谨性和经济学的现实应用性&#xff0c;为学生提供了强大的数理分析能力和经济洞察力。该专业毕业生在金融科技、量化投资、商业分析等领域具有显著优势&#xff0c;尤其在数字经济时代&#xff0c;这类复合型人才的需求量持续增长。一、数学经济…

局域网打印机共享怎么设置?如何配置内网本地网络打印机给异地电脑远程连接使用打印?

打印机共享怎么设置&#xff1f;如何设置本地内网的网络打印机共享给其他网络下电脑连接打印&#xff1f;打印机设置使用以及异地使用打印都是大家比较关注的问题&#xff0c;下面详细教程中分二步&#xff0c;先讲局域网内的打印机共享&#xff0c;再进一步介绍内网打印机地址…