【数据结构】C语言从零编写一个链表

前言

链表不同于顺序表,顺序表是以数组为存储基础的数据结构,它在内存中表现为一块连续的内存空间;而链表不需要,它通过一个指针来连接各个分散的结点,形成了一个链状的结构,每个结点存放一个元素,以及一个指向下一个结点的指针,通过这样一个一个相连,最后形成了链表。

链表分为带头结点的链表和不带头结点的链表,戴头结点的链表就是会有一个头结点指向后续的整个链表,但是头结点不存放数据。本篇博客构建一个带头节点的链表。

构建单个节点的结构体

首先构建一个结构体表示链表的单个节点;其中包含该节点储存的数据,和下一个节点的指针。

typedef int E;

struct ListNode
{
    E element;
    struct ListNode * next;
};

typedef struct ListNode * Node;

typedef关键字为int类型定义了一个新的别名E。

定义了一个名为ListNode的结构体。这个结构体表示单链表中的一个节点。

编写初始化函数

初始化链表的时候,由于只有一个头节点,所以我们让该节点指向的下一个地址为NULL。

void initList(Node node)
{
    node->next = NULL;
}

初始化一个链表的头节点,使其next指针指向NULL,以表示这是一个空链表或者该节点是链表的最后一个节点。

实现链表的插入

链表的插入大概分为三个步骤

  • 首先找到需要插入的地方
  • 将需要插入的节点指向前驱节点的下一个节点
  • 将前驱节点指向需要插入的节点
int insertList(Node node,E element,int index)
{
    if (index < 1) return 0;
    while (--index)
    {
        node = node->next;
        if (node == NULL) return 0;
    }
    Node new_node = malloc(sizeof (struct ListNode));
    new_node->element = element;
    new_node->next = node->next;
    node->next = new_node;

    return 1;

}

函数在成功插入后返回 1,表示插入成功。

这样就编写完链表的插入操作了,现在来测试一下;

编写一个打印链表元素的函数:

void printList(Node head){
    while (head->next) {
        head = head->next;
        printf("%d ", head->element);
    }
}

在主函数中初始化链表 并执行测试函数:

int main()
{
    struct ListNode head;
    initList(&head);
    for (int i = 1; i <= 3; ++i) {
        insertList(&head, i * 10, i);
    }
    printList(&head); // 10 20 30

    return 0;
}

数据成功打印。

实现删除链表节点的功能

删除节点主要分三步:

  • 找到需要删除的节点
  • 将该节点的上一个节点指向需要删除节点的下一个节点
  • 释放需要删除的节点的内存空间
int deleteList(Node node,int index)
{
    if (index < 1) return 0;

    while (--index) {
        node = node->next;
        if(node == NULL) return 0;
    }

    Node tmp = node->next; // 存储待删除节点的地址
    node->next = node->next->next;
    free(tmp); // 释放地址

    return 1;
}

获取对应位置上的元素

getList函数则用于获取链表中指定索引处的元素地址。

E * getList(Node node,int index)
{
    if (index < 1) return NULL;
    do {
        node = node->next;
        if (node == NULL) return NULL;
    } while (--index);
    
    return &(node->element);
}

查找对应元素的位置

findList的目的是在一个链表中查找一个特定的元素element,并返回该元素在链表中的位置(假设从1开始计数)。

int findList(Node node, E element)
{
    int i = 1;
   node = node->next;
    while (node)
    {
        if (node->element == element) return i;
        node = node->next;
        i++;
    }

    return -1;
}

求链表的长度

int sizeList(Node node)
{
    int i = 0;
    while(node->next)
    {
        node = node->next;
        i++;
    }
    return i;
}

全部代码

#include <stdio.h>
#include <stdlib.h>

/*
 * 链表
 */
typedef int E;

struct ListNode
{
    E element;
    struct ListNode * next;
};

typedef struct ListNode * Node;

void initList(Node node)
{
    node->next = NULL;
}

int insertList(Node node,E element,int index)
{
    if (index < 1) return 0;
    while (--index)
    {
        node = node->next;
        if (node == NULL) return 0;
    }
    Node new_node = malloc(sizeof (struct ListNode));
    new_node->element = element;
    new_node->next = node->next;
    node->next = new_node;

    return 1;

}

int deleteList(Node node,int index)
{
    if (index < 1) return 0;

    while (--index) {
        node = node->next;
        if(node == NULL) return 0;
    }

    Node tmp = node->next; // 存储待删除节点的地址
    node->next = node->next->next;
    free(tmp); // 释放地址

    return 1;
}

E * getList(Node node,int index)
{
    if (index < 1) return NULL;
    do {
        node = node->next;
        if (node == NULL) return NULL;
    } while (--index);

    return &(node->element);
}

int findList(Node node, E element)
{
    int i = 1;
   node = node->next;
    while (node)
    {
        if (node->element == element) return i;
        node = node->next;
        i++;
    }

    return -1;
}

int sizeList(Node node)
{
    int i = 0;
    while(node->next)
    {
        node = node->next;
        i++;
    }
    return i;
}

void printList(Node head){
    while (head->next) {
        head = head->next;
        printf("%d ", head->element);
    }
}

int main()
{
    struct ListNode head;
    initList(&head);
    for (int i = 1; i <= 3; ++i) {
        insertList(&head, i * 10, i);
    }
    printList(&head);

    return 0;
}

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

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

相关文章

从0到1手写vue源码

模版引擎 数组join法(字符串) es6反引号法(模版字符串换行) mustache (小胡子) 引入mustache 模版引擎的使用 mustache.render(templatestr,data)

【linux学习---1】点亮一个LED---驱动一个GPIO

文章目录 1、原理图找对应引脚2、IO复用3、IO配置4、GPIO配置5、GPIO时钟使能6、总结 1、原理图找对应引脚 从上图 可以看出&#xff0c; 蜂鸣器 接到了 BEEP 上&#xff0c; BEEP 就是 GPIO5_IO05 2、IO复用 查找IMX6UL参考手册 和 STM32一样&#xff0c;如果某个 IO 要作为…

ctfshow sql注入

开启其他注入 web221 limit注入 给出查询语句 以及过滤逻辑为空 获取数据库名即可 limit 用于控制返回结果行数 limit后面似乎只能跟PROCEDURE ANALYSE( ) 函数了 PROCEDURE ANALYSE( ) 函数用于分析查询结果的函数 参数是用来控制函数的 这个参数的位置 可以放入报错函数 原…

centos7.9 python3环境(virtualenv)搭建及所遇错误

人望山&#xff0c;鱼窥荷&#xff0c;真正喜欢想要的&#xff0c;没有一样可以轻易得到。 目录 # 1. 解决版本冲突问题--建议不要跳过(一定要查看软链接是否链接正确) # 2. python3(virtualenv)环境搭建 # 3. virtualenv常用命令 # 4. 所遇错误解析 ## 4.1 遇到 No modul…

关于python编程从入门到实践书中的外星人项目的 if event.key == pygame.K_q: sys.exit()失败问题

按q没有退出程序。原因是输入法中英文问题。 本人默认输入法是搜狗&#xff0c;其他的输入法如微软拼音等都行&#xff0c;但是注意运行的时候切换为英文。千万记得运行时不是中&#xff0c;而是英&#xff0c;按q才能退出

【数据结构】堆栈

目录 一、堆栈的基本概念 1.1 堆栈定义 1.2 堆栈操作 1.3 堆栈应用 二、顺序栈 2.1 定义 2.2 操作 2.3 C语言实现 三、共享栈 3.1 定义 3.2 操作 3.3 C语言实现 四、链式栈 4.1 定义 4.2 操作 4.3 C语言实现 五、总结 堆栈(Stack)重要的数据结构,它…

Python--线程基础

相关概念 线程是"轻量级进程",是计算机中CPU进行任务调度的最小单位。 线程属于进程的一部分,一个线程只能属于一个进程,而一个进程可以有多个线程,且至少有一个线程。 每个进程开始的创建的时候,都会随之创建一个主线程。 进程负责分配和隔离资源(CPU, 内存…

机器学习辅助的乙醇浓度检测

目录 1.为什么要机器学习 2. 神经网络一般组成 3.BP神经网络工作过程 4.评价指标 5.实操代码 1.为什么要用机器学习 人工分析大量的谐振模式&#xff0c;建立各种WGM的响应与未知目标之间的关系&#xff0c;是一个很大的挑战。机器学习(ML)能够自行识别全谱的全部特征。作为…

【Python】Python中的常量与变量

常量与变量 导读一、新建项目二、常量2.1 字面常量2.2 特殊常量 三、变量3.1 变量的定义3.2 变量的命名3.2.1 关键字 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我们详细介绍了Python环境的搭建过程&#xff0c;…

《代号鸢》国服,能否推动国乙市场重新洗牌?

灵犀互娱《如鸢》顺利拿到版号&#xff0c;再次搅浑了国乙市场这潭水。 六月份游戏版号审批公布后&#xff0c;灵犀互娱运营的《如鸢》引起了关注&#xff0c;这个与《代号鸢》原名《三国志如鸢》雷同的名字&#xff0c;竟然让《代号鸢》玩家大面积破防了。 其实目前关于《如…

游戏冻结工具 -- 雪藏HsFreezer v1.78

软件简介 HsFreezer是一款多功能游戏冻结工具&#xff0c;它允许用户随意暂停和继续游戏&#xff0c;同时具备系统优化和进程管理的功能。这款软件特别适合希望在游戏加载时间节省或在游戏与其他任务之间快速切换的用户。其主要特点包括快捷键操作、单锁模式的丝滑切换&#x…

湖北建筑安全员A证跨省调出审核不通过?可能是这些原因

湖北建筑安全员A证跨省调出审核不通过&#xff1f;可能是这些原因 湖北建筑安全员A证跨省调出审核不通过怎么办&#xff1f; 湖北建筑安全员ABC正常情况下都是可以跨省调出的&#xff0c;现在建筑三类人员安全员ABC在全国工程质量安全监管信息平台都是可以查询的&#xff0c;在…

《中国化工贸易》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《中国化工贸易》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《中国化工贸易》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;中国石油和化学工业联合会 主办单…

据阿谱尔统计,全球mRNA原料酶市场预计2024年达到11.98亿美元

Codexis 宣布与 Aldevron 达成协议&#xff0c;授予 Aldevron Codexis 的 Codex HiCap RNA 聚合酶的全球制造和商业化权利。 Applied DNA、Maravai LifeSciences (MRVI) 和 Alphazyme 达成协议&#xff0c;Alphazyme 将扩大 Applied DNA 专有 Linea™ RNA 聚合酶 (RNAP) 的生产…

图书管理系统(含登录验证码操作)

文章目录 登录需求分析登录界面注册功能&#xff1a;登录功能&#xff1a;忘记密码&#xff1a;验证码规则&#xff1a; 图书管理系统需求Book包Book类BookList类 IOperation包IOperation接口查找图书新增图书删除图书显示图书借阅图书归还图书退出系统 User包user类Users类adm…

干货分享|如何将前端代理服务器(BFF)接入身份认证(3完结篇)

续集3 前篇文章在前面发布&#xff0c;同学们可以自行找一下。 本篇文章将继续通过实例来详细讲解如何将前端代理服务器&#xff08;BFF&#xff09;接入身份认证。我们将使用一个示例应用来演示 BFF 与身份认证的集成过程。 3 在 Full BFF 中接入认证平台 本小节将介绍如何…

矢量绘图设计Sketch中文 Sketch直装安装包

Sketch是一款专为UI设计师和UX专家打造的矢量图形设计软件&#xff0c;以其简洁的界面、强大的功能和高效的协作能力而闻名。Sketch支持快速创建高质量的UI界面、图标、图形和插画&#xff0c;其矢量绘图工具让设计细节更加精准。同时&#xff0c;Sketch内置丰富的插件和组件库…

设计模式-结构型-08-组合模式

文章目录 1、学校院系展示需求2、组合模式基本介绍3、组合模式示例3.1、 解决学校院系展示&#xff08;透明模式1&#xff09;3.2、高考的科目&#xff08;透明模式2&#xff09;3.3、高考的科目&#xff08;安全组合模式&#xff09; 4、JDK 源码分析5、注意事项和细节 1、学校…

MySQL之应用层优化(二)

应用层优化 Web服务器问题 寻找最优并发度 每个Web服务器都有一个最佳并发度——就是说&#xff0c;让进程处理请求尽可能快&#xff0c;并且不超过系统负载的最优的并发连接数。这就是前面说的最大系统容量。进行一个简单的测量和建模&#xff0c;或者只是反复试验&#xf…

Python基础入门知识

目录 引言 简要介绍Python语言 为什么要学习Python Python的应用领域 Python安装和环境配置 Python的下载和安装(Windows, macOS, Linux) 配置Python环境变量 安装和使用IDE(如PyCharm, VS Code) Python基本语法 注释 变量和数据类型(数字,字符串,列表,元组,字典,…