【数据结构】单链表的头节点与尾节点

news2025/1/13 17:28:33

在这里插入图片描述

🎈个人主页:豌豆射手^
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏:数据结构
🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!

【数据结构】单链表的头节点与尾节点

  • 引言
    • 一 概念
      • 头节点(Head Node)
        • 头节点的作用:
      • 尾节点(Tail Node)
        • 尾节点的作用:
      • 总结
    • 二 代码
  • 总结

在这里插入图片描述

引言

一 概念

在数据结构中的单链表中,头节点(Head Node)和尾节点(Tail Node)是两个特殊的节点,它们在链表结构中扮演着不同的角色。

头节点(Head Node)

头节点是链表中的第一个节点,它通常用于简化对链表的操作。头节点并不总是包含实际的数据,有时候它只是一个哨兵节点(Dummy Node),用于指向链表中的第一个实际数据节点。头节点的存在可以使得链表的操作更加统一和方便,特别是在进行插入、删除和遍历操作时。

头节点的作用:
  1. 简化插入操作:当需要在链表头部插入新节点时,如果链表有头节点,就可以直接将新节点的指针指向头节点原本指向的节点,然后将头节点的指针指向新节点。如果没有头节点,就需要处理一些特殊情况,比如判断链表是否为空。
  2. 简化删除操作:类似地,当需要删除链表头部的节点时,如果有头节点,只需要将头节点的指针指向下一个节点即可。如果没有头节点,则需要特别注意链表是否为空,以及如何处理删除后的链表头部。
  3. 统一链表操作:有了头节点,无论是链表的头部还是尾部,都可以使用统一的操作方式,这使得代码更加简洁和易于维护。

尾节点(Tail Node)

尾节点是链表中的最后一个节点。在单链表中,每个节点都包含一个指向下一个节点的指针,而尾节点的这个指针通常设置为 NULL,表示链表的结束。

尾节点的作用:
  1. 标记链表结束:通过尾节点的 NULL 指针,可以方便地知道链表何时结束,这是遍历链表时的重要标识。
  2. 简化插入操作:当需要在链表尾部插入新节点时,只需要将尾节点的指针指向新节点,然后将新节点的指针设置为 NULL。这样可以避免从头节点开始遍历整个链表来找到最后一个节点。

总结

头节点和尾节点在单链表中的作用主要体现在简化链表操作和提高代码的可读性和可维护性。它们使得链表的插入、删除和遍历等操作更加高效和一致。然而,并不是所有的单链表实现都会使用头节点,这取决于具体的应用场景和需求。在某些情况下,为了节省内存空间或简化数据结构,可能会选择不使用头节点。

二 代码

在C语言中实现单链表的头节点和尾节点,我们需要首先定义链表节点的结构体,然后编写创建链表、添加节点等函数。下面是一个简单的示例,它展示了如何创建一个包含头节点和尾节点的单链表,并向其中添加数据节点。

#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 == NULL) {
        printf("Memory allocation failed!\n");
        exit(1); // 如果内存分配失败,退出程序
    }
    newNode->data = data;    // 设置节点的数据
    newNode->next = NULL;    // 新节点的next指针初始化为NULL
    return newNode;          // 返回新创建的节点
}

// 在链表尾部添加节点
void appendNode(Node** head, Node** tail, int data) {
    Node* newNode = createNode(data); // 创建新节点
    if (*head == NULL) {             // 如果链表为空(即头节点为空)
        *head = newNode;             // 新节点成为头节点
        *tail = newNode;             // 新节点也成为尾节点
    } else {
        (*tail)->next = newNode;    // 将新节点添加到当前尾节点的后面
        *tail = newNode;             // 更新尾节点为新节点
    }
}

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

// 释放链表内存
void freeList(Node* head) {
    Node* temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }
}

int main() {
    Node* head = NULL;    // 初始化头节点为NULL
    Node* tail = NULL;    // 初始化尾节点为NULL

    // 向链表尾部添加节点
    appendNode(&head, &tail, 10);
    appendNode(&head, &tail, 20);
    appendNode(&head, &tail, 30);

    // 打印链表
    printList(head);

    // 释放链表内存
    freeList(head);

    return 0;
}

下面是对代码的详细解释:

  1. 定义链表节点结构体 Node,包含 datanext 两个成员。

  2. createNode 函数用于创建新节点,并初始化其 datanext 成员。如果内存分配失败,则打印错误信息并退出程序。

  3. appendNode 函数用于在链表尾部添加新节点。它接受头节点和尾节点的地址作为参数,以便在添加新节点时能够更新这两个指针。

    • 如果链表为空(即头节点为 NULL),新节点既是头节点也是尾节点。
    • 如果链表不为空,将新节点添加到当前尾节点的后面,并更新尾节点为新节点。
  4. printList 函数用于打印链表的内容。从头节点开始,遍历链表直到 NULL 指针,并打印每个节点的数据。

  5. freeList 函数用于释放链表占用的内存。从头节点开始,逐个释放每个节点所占用的内存。

  6. main 函数中,我们初始化头节点和尾节点为 NULL,然后调用 appendNode 函数向链表尾部添加几个节点。接着,我们调用 printList 函数打印链表的内容。最后,调用 freeList 函数释放链表占用的内存。

注意:在这个示例中,我们并没有显式地创建一个头节点来存储链表信息,而是将头节点作为链表的一部分,它同时存储数据和指向下一个节点的指针。如果你需要一个只包含指针而不包含数据的头节点,你需要在创建链表时单独处理它,并更新相关的逻辑。

另外,上面的代码示例没有包含错误处理逻辑,比如检查 malloc 调用是否成功。在实际编程中,你应该总是检查内存分配是否成功,并在必要时采取适当的错误处理措施。

总结

这篇文章到这里就结束了

谢谢大家的阅读!

如果觉得这篇博客对你有用的话,别忘记三连哦。

我是豌豆射手^,让我们我们下次再见

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Appian发布最新版本:通过AI流程自动化推动业务发展

Appian公司于2024年4月16日在弗吉尼亚州麦克莱恩宣布推出Appian平台的最新版本。此版本引入了Process HQ&#xff0c;这是一个集流程挖掘和企业AI于一体的系统&#xff0c;结合了Appian的数据平台。Process HQ为企业运营提供前所未有的可见性&#xff0c;支持数据驱动的决策和流…

nas如何异地共享文件?

nas异地共享文件是一种通过网络实现不同地区电脑与电脑、设备与设备、电脑与设备之间的文件共享的技术。通过nas&#xff08;网络附加存储&#xff09;设备&#xff0c;用户可以在不同地点的电脑或设备之间快速、安全地共享文件和数据。本文将介绍nas异地共享文件的原理以及它在…

宝塔面板使用docker+nginx+gunicorn部署Django项目实战教程

第一步&#xff1a;创建Django项目 使用pip install django安装创建django项目的依赖在电脑某个根目录下执行django-admin startproject app创建一个名为app的Django项目。目录结构如下: ├── app │ ├── init.py │ ├── asgi.py │ ├── settings.py │ ├── url…

SQL注入作业

目录 一、万能密码和二阶注入测试 1.万能密码 2.二阶注入测试 二、联合查询注入测试 1.判断注入点 2.判断当前查询语句的列数 3.查询数据库基本信息 4.查询数据库中的数据 三、报错注入 1. 报错注入函数EXTRATVALUE 2.UPDATEXML 四、盲注测试 1.布尔盲注 判断数据…

【学习】软件压力测试对软件产品的作用

在信息化高速发展的今天&#xff0c;软件产品已经成为各行各业不可或缺的一部分。然而&#xff0c;随着软件功能的日益复杂和用户需求的不断增长&#xff0c;软件产品的稳定性和可靠性问题也愈发凸显。在这样的背景下&#xff0c;软件压力测试作为软件质量保障的重要手段之一&a…

回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测&#xff0…

盗梦攻击:虚拟现实系统中的沉浸式劫持

虚拟现实&#xff08;VR&#xff09;硬件和软件的最新进展将改变我们与世界和彼此互动的方式&#xff0c;VR头显有可能为用户提供几乎与现实无差别的深度沉浸式体验。它们还可以作为一种跨越遥远距离的方式&#xff0c;通过使用个性化的化身或我们的数字代表&#xff0c;促进社…

旅游陪同翻译难吗, 旅游翻译英译中哪家好?

近来&#xff0c;随着中国旅游业的蓬勃发展&#xff0c;旅游陪同翻译的需求也水涨船高&#xff0c;这些专业的翻译服务者为中外游客搭建起友谊的桥梁&#xff0c;引领他们共同探索中国这片古老而神秘的土地 。那么&#xff0c;旅游陪同翻译英译中难吗&#xff1f;我们如何在众多…

机器学习和深度学习-- 李宏毅(笔记于个人理解)Day 21

Day 21 Self- Attention 选修部分 ​ 学完自适应 再回来看看 Sequence Labling 假如我们现在有一个需要读完全部句子才能解的问题&#xff0c; 那么red window 就需要变得是最大的&#xff08;最长的句子&#xff09;&#xff1b; 其实这里大家有没有想过&#xff0c;这个玩意…

Android Studio历史版本下载地址

https://developer.android.com/studio/archive?hlzh-cn https://blog.csdn.net/crasowas/article/details/130304836

豆瓣影评信息爬取 (爬虫)

代码块&#xff1a; from lxml import etree import requestsheaders{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0 }url_list[] for i in range(0,5):i*20urlsf"https:…

顺序表链表经典算法题

1.链表反转 typedef struct ListNode listnode; struct ListNode* reverseList(struct ListNode* head) {if(head NULL){return head;}listnode* p1 NULL;listnode* p2 head;listnode* p3 head->next;while(p2){p2->next p1;p1 p2;p2 p3;if(p3)p3 p3->next;}…

ubuntu22.04 启用 root登录

1&#xff0c;设置 root密码 普通用户输入如下命令给 root 设置密码 sudo passwd root 根据提示设置密码。 2&#xff0c;允许 root 登录 vim /etc/pam.d/gdm-password 以及 vim /etc/pam.d/gdm-autologin 注释两个文件中如下图所示的代码 3&#xff0c;允许 ssh 方式 ro…

移动端适配之viewport

目录 盒模型&#xff1a;widthcontent&#xff08;padding border&#xff09; class"content-box"内容盒模型&#xff08;W3C盒&#xff09; class"border-box"边框盒模型&#xff08;IE 盒&#xff09; scroll滚动 window浏览器视窗&#xff1a;包括…

IP 和 TCP 抓包分析实验

实验拓扑 实验需求 1、配置IP地址&#xff0c;R1的g0/0口是1.1.1.1/24 &#xff0c;R2的g0/0口是1.1.1.2/24 2、在该链路上开启抓包 3、在R1上ping R2 4、开启wireshark&#xff0c;查看抓取的ping包的内容 5、在R2上开启ftp服务 6、在R1上访问R2的FTP 7、在wireshark查…

【游戏专区】贪吃蛇

1&#xff0c;游戏背景 贪吃蛇&#xff08;Snake&#xff09;是一款经典的电子游戏&#xff0c;最初在1976年由 Gremlin 公司开发。它的游戏背景相对简单&#xff0c;但具有高度的成瘾性。 1. **游戏场景**&#xff1a;通常在一个有界的矩形区域内进行&#xff0c;可以是一个…

电磁炉原理笔记

电磁炉加热原理 【电磁炉工作原理&#xff0c;电涡流感应加热原理】 https://www.bilibili.com/video/BV11M411M7Wt/?share_sourcecopy_web&vd_source44c5c5fe44538189ece80f09460cf625 我是看的这个科普视频&#xff1b; 总结一下就是下图&#xff1a; 线圈的磁场影响…

Spring Boot JNA 实现调用 DLL文件(清晰明了)

概述 项目需要用到 重采样算法&#xff0c;JAVA 没有现成的&#xff0c;只能通过 JNA 调用 C 的 DLL 实现&#xff0c;JNA中&#xff0c;它提供了一个动态的C语言编写的转发器&#xff0c;可以自动实现Java和C的数据类型映射。不再需要编写C动态链接库。 实现需求 根据 一个…

rc_visard 3D Stereo Senso

1 简介 rc_visard 3D立体视觉传感器 支持的接口标准 GenICam Generic Interface for CamerasGigE Gigabit Ethernet 词汇表 SGM semi-global matching 半全局匹配 SLAM Simultaneous Localization and Mapping 即时定位与地图构建 2 安全 3 硬件规格 坐标系 rc_visar…

【云计算】云数据中心网络(三):NAT 网关

《云网络》系列&#xff0c;共包含以下文章&#xff1a; 云网络是未来的网络基础设施云网络产品体系概述云数据中心网络&#xff08;一&#xff09;&#xff1a;VPC云数据中心网络&#xff08;二&#xff09;&#xff1a;弹性公网 IP云数据中心网络&#xff08;三&#xff09;…