重生之我在异世界学编程之C语言:深入结构体篇(下)

大家好,这里是小编的博客频道
小编的博客:就爱学编程

很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!

本文目录

  • 引言
  • 结构体的自引用实现链表
      • 一、链表的基本概念
        • 1. 单向链表
        • 2. 双向链表
        • 3. 循环链表
      • 二、使用结构体定义链表节点
      • 三、创建链表的基本操作
        • 1. 创建新节点
        • 2. 在链表头部插入节点
        • 3. 在链表尾部插入节点
        • 4. 删除节点
        • 5. 打印链表
      • 四、完整示例代码
  • 快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

引言

在C语言中,结构体(struct)是一种用户自定义的数据类型,它允许将多个不同类型的数据项组合成一个单一的类型。结构体是编程中组织相关数据的有效方式,尤其在处理复杂数据时显得尤为重要。以下是对C语言结构体进阶知识-——实现链表的介绍,一起来看看吧!!

在这里插入图片描述


那接下来就让我们开始遨游在知识的海洋!

结构体的自引用实现链表


一、链表的基本概念

链表是一种线性数据结构,但与数组不同的是,链表中的元素在内存中不必连续存储。链表由一系列的节点(Node)组成,每个节点包含两部分:一部分是存储数据的域(Data Field),另一部分是指向下一个节点的指针(Pointer Field)。根据指针的指向不同,链表可以分为单向链表、双向链表和循环链表等。

1. 单向链表

单向链表是最简单的链表形式,其中每个节点只包含一个指向下一个节点的指针。最后一个节点的指针为NULL,表示链表的结束。

2. 双向链表

双向链表中的每个节点除了包含指向下一个节点的指针外,还包含指向前一个节点的指针。这使得在链表中向前或向后遍历都成为可能。

3. 循环链表

循环链表的特点是最后一个节点的指针不是指向NULL,而是指向链表的第一个节点,从而形成一个环状结构。


二、使用结构体定义链表节点

在C语言中,可以使用结构体来定义链表节点。以下是一个单向链表节点的定义示例:

#include <stdio.h>
#include <stdlib.h>// 定义链表节点结构体
typedef struct Node {int data;           // 数据域struct Node* next;  // 指针域,指向下一个节点
} Node;

在这个例子中,Node结构体有两个成员:一个是整型变量data用于存储数据,另一个是指针next用于指向下一个Node类型的节点。


三、创建链表的基本操作

1. 创建新节点

要创建一个新的链表节点,需要动态分配内存并初始化其数据和指针。以下是创建新节点的函数示例:

// 创建新节点并返回其指针
Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node)); // 动态分配内存if (!newNode) {printf("Memory allocation error
");exit(1);}newNode->data = data;                       // 初始化数据域newNode->next = NULL;                       // 初始化指针域为空return newNode;
}
2. 在链表头部插入节点

要在链表的头部插入一个新节点,只需更新新节点的next指针使其指向当前的头节点,然后更新头指针指向新节点。以下是该操作的函数示例:

// 在链表头部插入新节点
void insertAtHead(Node** head, int data) {Node* newNode = createNode(data); // 创建新节点newNode->next = *head;            // 新节点的next指向当前头节点*head = newNode;                  // 更新头指针指向新节点
}

注意这里使用了双重指针Node** head,以便能够修改头指针本身的值。

3. 在链表尾部插入节点

要在链表的尾部插入一个新节点,需要遍历到链表的末尾,然后将末尾节点的next指针指向新节点。以下是该操作的函数示例:

// 在链表尾部插入新节点
void insertAtTail(Node** head, int data) {Node* newNode = createNode(data); // 创建新节点if (*head == NULL) {              // 如果链表为空,则新节点成为头节点*head = newNode;return;}Node* temp = *head;               // 使用临时指针遍历链表while (temp->next != NULL) {      // 找到最后一个节点temp = temp->next;}temp->next = newNode;             // 将最后一个节点的next指向新节点
}
4. 删除节点

删除节点需要根据给定的值找到目标节点,并调整前一个节点的next指针使其跳过目标节点。以下是删除节点的函数示例:

// 根据值删除节点
void deleteNode(Node** head, int key) {Node* temp = *head;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); // 释放被删除节点的内存
}
5. 打印链表

为了验证链表的正确性,通常需要编写一个打印链表的函数:

// 打印链表中的所有节点
void printList(Node* head) {Node* temp = head;while (temp != NULL) {printf("%d -> ", temp->data);temp = temp->next;}printf("NULL
");
}

四、完整示例代码

以下是一个完整的示例程序,它展示了如何创建和操作一个简单的单向链表:

#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node* next;
} Node;Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (!newNode) {printf("Memory allocation error
");exit(1);}newNode->data = data;newNode->next = NULL;return newNode;
}void insertAtHead(Node** head, int data) {Node* newNode = createNode(data);newNode->next = *head;*head = newNode;
}void insertAtTail(Node** head, int data) {Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;return;}Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}void deleteNode(Node** head, int key) {Node* temp = *head;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(Node* head) {Node* temp = head;while (temp != NULL) {printf("%d -> ", temp->data);temp = temp->next;}printf("NULL
");
}int main() {Node* head = NULL;insertAtHead(&head, 10);insertAtHead(&head, 20);insertAtTail(&head, 30);insertAtTail(&head, 40);printf("Linked List: ");printList(head);deleteNode(&head, 20);printf("After deleting 20: ");printList(head);deleteNode(&head, 10);printf("After deleting 10: ");printList(head);return 0;
}
  • 通过上述步骤,我们了解了如何在C语言中使用结构体来实现链表,并掌握了基本的链表操作如创建节点、插入节点、删除节点以及打印链表的方法。这些基本操作是实现更复杂链表算法和数据结构

快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

linux学习day03_linux文件与目录管理

1、相对路径和绝对路径的区别 绝对路径&#xff1a;路径的写法“一定由根目录 / 写起”&#xff0c;例如&#xff1a; /usr/share/doc 这个目录。 相对路径&#xff1a;路径的写法“不是由 / 写起”&#xff0c;例如由 /usr/share/doc 要到 /usr/share/man 下面 时&#xff0…

深入浅出:Gin框架中的测试与Mock

深入浅出&#xff1a;Gin框架中的测试与Mock 引言 在现代软件开发中&#xff0c;编写高质量的代码离不开有效的测试。对于Web应用程序来说&#xff0c;单元测试、集成测试和端到端测试都是确保系统稳定性和可靠性的重要手段。本文将带你深入了解如何在Gin框架中进行测试&…

未来网络技术的新征程:5G、物联网与边缘计算(10/10)

一、5G 网络&#xff1a;引领未来通信新潮流 &#xff08;一&#xff09;5G 网络的特点 高速率&#xff1a;5G 依托良好技术架构&#xff0c;提供更高的网络速度&#xff0c;峰值要求不低于 20Gb/s&#xff0c;下载速度最高达 10Gbps。相比 4G 网络&#xff0c;5G 的基站速度…

LDR6500U PD取电协议芯片:高效充电与智能管理的典范

在当今快速发展的电子设备市场中&#xff0c;高效、安全、稳定的充电技术已成为衡量设备性能的重要指标之一。而LDR6500U&#xff0c;作为乐得瑞科技有限公司针对USB PD&#xff08;Power Delivery&#xff09;协议及Quick Charge&#xff08;QC&#xff09;协议开发的一款高性…

Plugin - 插件开发05_Solon中的插件实现机制

文章目录 Pre概述插件插件扩展机制&#xff08;Spi&#xff09;插件扩展机制概述插件扩展机制的优势 插件扩展机制实现步骤第一步&#xff1a;定制插件实现类示例代码&#xff1a;插件实现类 第二步&#xff1a;通过插件配置文件声明插件示例插件配置文件&#xff1a;META-INF/…

JAVA-二叉树的概念和性质

目录 一.树形结构 1.1 概念 1.2 树的概念(重要)​编辑 补充&#xff1a;高度和深度的区别 1.3 树的应用 二. 二叉树&#xff08;重点&#xff09; 2.1 概念 2.2 两种特殊的二叉树 2.3 二叉树的性质 2.4 选择题 一.树形结构 1.1 概念 树是一种 非线性 的数据结构&…

SVM的基本思想

一、SVM的基本思想 SVM的基本思想是在样本的向量空间中寻找一个超平面&#xff0c;使得两类样本被分割在平面的两端。这样的平面理论上有无穷多个&#xff0c;但SVM的目标是找到一个最优的超平面&#xff0c;即两侧距离超平面最近的样本点到超平面的距离被最大化的超平面。这个…

【TCP 网络通信(发送端 + 接收端)实例 —— Python】

TCP 网络通信&#xff08;发送端 接收端&#xff09;实例 —— Python 1. 引言2. 创建 TCP 服务器&#xff08;接收端&#xff09;2.1 代码示例&#xff1a;TCP 服务器2.2 代码解释&#xff1a; 3. 创建 TCP 客户端&#xff08;发送端&#xff09;3.1 代码示例&#xff1a;TCP…

day08 接口测试(3)——postman工具使用

下载 postman 的历史版本&#xff1a;Postman 历史版本下载 - 简书 今天开始学习 postman 这个测试工具啦。 【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、postman简介 2、postman的安装 3、给postman安装插件——newman 3.1 环境安装 3.1.1 安…

README写作技巧

做一个项目&#xff0c;首先第一眼看上去要美观&#xff0c;这样才有看下去的动力。做项目亦是如此&#xff0c;如果每一步应付做的话&#xff0c;我想动力也不会太大&#xff0c;最终很大概率会放弃或者进度缓慢。 1.README组成 README是对项目的一个说明&#xff0c;它对观看…

渗透测试---burpsuite(5)web网页端抓包与APP渗透测试

声明&#xff1a;学习素材来自b站up【泷羽Sec】&#xff0c;侵删&#xff0c;若阅读过程中有相关方面的不足&#xff0c;还请指正&#xff0c;本文只做相关技术分享,切莫从事违法等相关行为&#xff0c;本人与泷羽sec团队一律不承担一切后果 视频地址&#xff1a;泷羽---bp&…

【Springboot3+vue3】从零到一搭建Springboot3+vue3前后端分离项目之前端环境搭建

【Springboot3vue3】从零到一搭建Springboot3vue3前后端分离项目之前端环境搭建 2 前端环境搭建2.1 环境准备2.2 创建Vue3项目2.3 项目搭建准备2.4 安装Element Plus2.5 安装axios2.5.1 配置&#xff08;创建实例&#xff0c;配置请求&#xff0c;响应拦截器&#xff09;2.5.2 …

11.27-12.5谷粒商城

目录 新增商品 1.上线会员服务 2. 获取分类关联的品牌 3.获取选定分类下的属性分组和属性 4.新增商品vo 5.保存商品信息 6.Spu检索 7.Sku商品检索 新增商品 1.上线会员服务 将会员服务注册到nacos注册中心&#xff0c;启用服务注册发现EnableDiscoveryClient。 同时新增…

深入解析非桥PCI设备的访问和配置方法

往期内容 本文章相关专栏往期内容&#xff0c;PCI/PCIe子系统专栏&#xff1a; 嵌入式系统的内存访问和总线通信机制解析、PCI/PCIe引入 Uart子系统专栏&#xff1a; 专栏地址&#xff1a;Uart子系统 Linux内核早期打印机制与RS485通信技术 – 末片&#xff0c;有专栏内容观看…

ArrayList常见操作源码逐句剖析

目录 前言 正文 1.需要了解的一些字段属性 1.存储 ArrayList 元素的数组缓冲区。 2.集合的大小 3.默认集合容量大小 2.ArrayList对象创建 1.无参构造 2.有参构造1 3.有参构造2 3.添加元素add(E e)以及扩容机制 ​编辑 后言 前言 源码的剖析有助于理解设计模式&…

现代密码学|Rabin密码体制及其数学基础 | 椭圆曲线密码体制及其运算 | DH密钥交换及中间人攻击

文章目录 参考Rabin密码体制及其数学基础中国剩余定理二次剩余Rabin密码体制实例 椭圆曲线密码体制及其运算原理运算规则加密解密实例 DH密钥交换及中间人攻击中间人攻击 参考 现代密码学&#xff5c;Rabin密码体制及其数学基础 现代密码学&#xff5c;椭圆曲线密码体制及其运…

硬件选型规则

光源选型: 先用型号中带H的&#xff0c;没有的选标准的. 光源和光源控制器的搭配需要确保接口一致。 根据型号表中的最佳工作距离和相机的尺寸。 光源控制器选型&#xff1a; 首先选择海康风格系列光源控制器考虑与光源的接口匹配。功率应该满足接近光源功率。检查是否退市…

sharedPreference包的使用总结

文章目录 1 概念介绍2 实现方法3 示例代码我们在上一章回中介绍了"如何自定义评分条"相关的内容,本章回中将介绍如何实现本地存储.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 Flutter是一套跨平台的UI框架,它不像原生SDK一样提供本地存储功能,因此,我们在…

TCP连接的时候遇到的异常(目标端口没开放)

import asyncioasync def check_port(ip, port, timeout1):"""检查目标 IP 和端口是否开放:param ip: 目标 IP 地址:param port: 目标端口:param timeout: 超时时间&#xff08;秒&#xff09;"""try:reader, writer await asyncio.open_connec…

C总结(C语言知识点,深化重难点)

C语言 1.使用C语言的7个步骤2.ASCII码3.提高程序可读性的机巧4.如何使用多种整形5.打印多种整形6.课移植类型&#xff1a;stdint.h和inttypes.h7.浮点数常量8.浮点值的上溢和下溢9.使用数据类型11.常量和C预处理器12.转换说明的意义12.1转换不匹配13.副作用和序列点14.数组简介…