C语言数据结构——线性表的链式存储结构

2023-05-16

文章目录

  • 线性表的链式存储结构
    • 1.基本概念
    • 2.设计与实现
    • 3.优点和缺点

线性表的链式存储结构

1.基本概念

链式存储定义:为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息之外,还需要存储指示其直接后继的信息。
在这里插入图片描述
n个结点连接成一个链表,即为线性表(a1 a2 a3…an)的链式存储结构,因此此链表的每个结点中包含一个指针域,所以叫做单链表。单链表正是通过每个结点的指针域将线性表的数据元素按其逻辑次序链接在一起。
在这里插入图片描述
组成部分
表头结点:链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息
数据结点:链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息

2.设计与实现

首先先创造一个整体的框架,先自定一个header文件,然后把想要实现的方法写入,然后直接在主程序中导入此头文件
header.h

//
// Created by 2NaCl on 2019/2/20.
//

#ifndef CPRIMERPLUS_HEADER_H
#define CPRIMERPLUS_HEADER_H

typedef void LinkList;//声明一下线性表

typedef struct _tag_LinkListNode{
    struct LinkListNode *next;
}LinkListNode;

LinkListNode node1;

LinkList *LinkList_Create();//创建一张线性表

void LinkList_Destroy(LinkList *list);//销毁一张线性表

void LinkList_Clear(LinkList *list);//清空结点元素

int LinkList_Length(LinkList *list);//返回线性表的长度

int LinkList_Insert(LinkList *list,LinkList *node,int pos);//向SeqList链表pos的位置插入一个结点node

LinkListNode *LinkList_Get(LinkList *list , int pos);//获取pos位置元素

LinkListNode *LinkList_Delete(LinkList *list,int pos);//删除pos位置元素

#endif //CPRIMERPLUS_HEADER_H

然后我们编写测试程序,调用我们拟定好的实现方法

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"

typedef struct Teacher{
    LinkListNode node;//老师是大结点,让大结点包含链表结点,形成链式存储结构
    int age;
    char name[30];
}Teacher;

int main(){
    int len = 0,ret = 0;
    LinkList *list = NULL;
    Teacher t1,t2,t3,t4,t5;
    t1.age=30;
    t2.age=31;
    t3.age=32;
    t4.age=33;
    t5.age=34;
    list = LinkList_Create();
    if (list == NULL) {
        return 0;
    }
    LinkList_Length(list);
    ret = LinkList_Insert(list, (LinkListNode *) (&t1), 0);
    ret = LinkList_Insert(list, (LinkListNode *) (&t2), 0);
    ret = LinkList_Insert(list, (LinkListNode *) (&t3), 0);
    ret = LinkList_Insert(list, (LinkListNode *) (&t4), 0);
    ret = LinkList_Insert(list, (LinkListNode *) (&t5), 0);

    for (int i = 0; i < LinkList_Length(list); ++i) {
        Teacher *teacher = (Teacher *) LinkList_Get(list, i);
        if (teacher==NULL) {
            printf("404");
        }
        printf("teacher->age:%d\n", teacher->age);
    }

    while (LinkList_Length(list) > 0) {
        Teacher *teacher = (Teacher *) LinkList_Delete(list, 0);
        if (teacher == NULL) {
            printf("404");
        }
        printf("teacher->age:%d\n", teacher->age);
    }

    LinkList_Destroy(list);


    system("pause");
}

最后把细节写好,本文采用的还是头插法,下面开始写具体实现方法的实现顺序
1.搭建链表框架
我们之前提到了,要在大的Teacher结点中,放入一个链表结点,然后连接所有的链表结点,实现链表,也就是说,这个链表框架的功能就是穿针引线,将内部的链表结构串联起来。

typedef struct _tag_LinkList{
    LinkListNode header;
    int length;
}tLinkList;

2.创建链表并且为其分配存储空间,和之前的顺序结构相差无几,也要在分配完链表的存储空间后使用到memset方法

LinkList *LinkList_Create(){
    tLinkList *ret = NULL;
    ret = (tLinkList *) malloc(sizeof(tLinkList));
    memset(ret, 0, sizeof(tLinkList));
    ret->length = 0;
    ret->header.next = NULL;
    return NULL;
}

3.然后是销毁链表,和顺序存储结构不相同的是,只需要一次free即可,free的就是链表内部的内存

void LinkList_Destroy(LinkList *list){
    if (list != NULL) {
        free(list);
        list = NULL;
    }
    return;
}

4.然后写clear方法,clear的目的是让链表回到初始值

void LinkList_Clear(LinkList *list){
    tLinkList *tLinkList1 = NULL;
    if (list == NULL) {
        return;
    }
    tLinkList1 = (tLinkList *) list;
    tLinkList1->header.next = NULL;
    tLinkList1->length = 0;
}

5.求链表长度

int LinkList_Length(LinkList *list){
    tLinkList *linkList1 = NULL;
    if (list == NULL) {
        return 0;
    }
    linkList1 = (tLinkList *) list;
    return linkList1->length;
}

6.链表的插入操作
其实道理很简单,指针指向谁,就把谁的地址赋给指针,主要注意辅助变量之间的关系就可以了。
画图说明:
在这里插入图片描述
现在想要让node结点插入到2和3中,就需要执行以下操作(因为链表是单向的,3号位置要保存在2号位置的next域中):
(1).node->next = current2->next;
(2).current2 ->next = node;

int LinkList_Insert(LinkList *list,LinkListNode *node,int pos){
    int ret = 0;
    LinkListNode *current = NULL;
    tLinkList *tList = NULL;
    if (pos < 0 || node == NULL || list == NULL) {
        ret = 0;
        printf("Insert有错误");
        return 0;
    }
    tList = (tLinkList *) list;
    current = &(tList->header);

    for (int i = 0; i < pos && (current->next != NULL); ++i) {
        current = current->next;
    }
    //用node连接后续链表
    node->next = current->next;
    //让前面的链表使用到node
    current->next = node;

    tList->length ++ ;
    return 0;
}

7.获取链表中的结点

LinkListNode *LinkList_Get(LinkList *list, int pos) {
    int ret = 0;
    tLinkList *tList = NULL;
    LinkListNode *current = NULL;
    if (pos < 0 || list == NULL) {
        printf("get出错");
        return 0;
    }
    tList = (tLinkList *) list;
    current = &(tList->header);
    for (int i = 0; i < pos && (current->next != NULL); i++) {
        current = current->next;
    }
    return current->next;
}

8.删除列表中的某个结点
在这里插入图片描述
现在要让current2跳过current3,直接next就是current4
核心步骤:
先声明一个辅助指针ret,然后
ret = current2->next;
current2->next=ret ->next;

LinkListNode *LinkList_Delete(LinkList *list,int pos){
    int i = 0;
    LinkListNode *current = NULL;
    LinkListNode *ret = NULL;
    tLinkList *tlist = NULL;
    if (list == NULL || pos < 0) {
        int ret = 0;
        printf("Delete出错");
        return NULL;
    }

    tlist = (tLinkList *) list;
    current = (&tlist->header);
    for (int i = 0; i < pos && (current->next != NULL); i++) {
        current = current->next;
    }
    //缓存被删除的结点
    ret = current->next;
    current->next = ret->next;
    return ret;

}

3.优点和缺点

优点:
无需一次性定制链表的容量
插入和删除操作无需移动数据元素
缺点:
数据元素必须保存后继元素的位置信息
获取指定元素的数据操作需要顺序访问之前的元素。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言数据结构——线性表的链式存储结构 的相关文章

  • gcc和makefile用法总结(建议收藏)

    文章目录 64 toc 1 用GCC制作静态链接库静态链接库的创建静态链接库的使用 2 用GCC制作动态链接库动态链接库的创建动态链接库的使用 3 GCC找不到库文件怎么办 xff1f GCC生成可执行文件时找不到库文件GCC运行可执行文件
  • linux---基础IO

    在标准库中我们学习了printf xff0c fprintf xff0c sprintf xff0c snprintf等等相关的函数 xff0c 接下来是我们的系统I O调用接口 open includ e lt sys types h g
  • HDU-2121(朱刘算法优化版+虚根处理无根树形图)

    hdu2121 span class token macro property span class token directive keyword include span span class token string lt bits
  • #10091. 「一本通 3.5 例 1」受欢迎的牛(强联通+度数结论)

    libreoj10091 题解 xff1a 首先简化一下 xff0c 若欢迎关系图是一个DAG 有向无环图 xff0c 则只要统计每个点的出度 xff0c 出度为0的点即为受所有牛欢迎的点且只有唯一一个 xff0c 因为若存在两个以上出度为
  • https://ac.nowcoder.com/acm/problem/13947(牛客网)

    Contest xff1a 链接 xff1a https ac nowcoder com acm problem 13947 来源 xff1a 牛客网 n支队伍一共参加了三场比赛 一支队伍x认为自己比另一支队伍y强当且仅当x在至少一场比赛中
  • https://ac.nowcoder.com/acm/problem/14136(牛客网 监视任务)

    题目链接 xff1a 题解 xff1a 本题我们不能一上来就用树状数组来统计每一位的贡献 xff0c 我们需要先对区间进行一个排序 xff0c 先按照区间的右端点由小到大排序 xff0c 再按照区间的左端点从小到大排序 xff0c 再按照区
  • https://ac.nowcoder.com/acm/problem/14269(Sum 牛客网)

    位运算 43 组合数学 43 树状数组 xff1a 题解 xff1a 我们如果直接计算操作2的话会很困难 xff0c 我们可以直接考虑一个数的二进制位对答案做出的贡献 xff0c 显然二进制位为0时就不会有任何贡献 xff0c 当我们知道所
  • 异或的路径(牛客网)

    异或路径 43 位运算 43 考虑贡献 题解 xff1a 我们要求所有点对构成的所有路径的异或权值总和 xff0c 肯定不能暴力 xff0c 我们可以知道 xff0c 先搞一个数组d i 表示i节点到根节点1的路径上边权异或和 xff0c
  • TCP为什么采用三次握手而不是两次握手

    希仁版 计算机网络 中的例子是这样的 xff0c 已失效的连接请求报文段 的产生在这样一种情况下 xff1a client发出的第一个连接请求报文段并没有丢失 xff0c 而是在某个网络结点长时间的滞留了 xff0c 以致延误到连接释放以后
  • linux生成可执行文件的命令

    linux生成带调试的可执行文件命令行 xff1a g span class token operator 43 43 span span class token operator span g main span class token
  • git rebase origin/develop

    1 进行git rebase origin develop之前需要进行 lt git add gt lt git commit gt 操作先将修改给提交到暂存区 2 执行git rebase origin develop时候有冲突的话需要自
  • linux---文件描述符和重定向

    文件描述符 进程就是通过struct file结构体来描述打开的文件 xff0c 使用struct file fd array 来存储我们的文件 那什么是文件描述符呢 xff1f 什么是文件描述符 xff1a 文件描述符就是struct f
  • git合并多个commit

    git合并多个commit
  • 深度学习资料

    深度学习资料
  • cmake总结

    cmake 用CMakeList txt产生makefile xff0c make 使用makefile编译可执行程序
  • kuangbin连通图专题,Network of Schools (POJ - 1236,tarjan算法求缩点+缩点的入度与出度的运用)

    kuangbin 题意是有N个学校 每个学校可能向几个学校进行数据传输 xff08 单向的 xff09 问 至少需要把一个文件给几个学校可以使给的N个学校都收到文件 再问在加几个通信线路可以使各个学校之间都能直接或间接的传递文件 一个强连通
  • endnote 文献保留前三个作者

    1 问题描述 xff1a endnote使用GBT7714文献格式 xff0c 显示文献的全部作者 2 想要达到的效果 xff1a 最多显示三个作者 3 解决方法 xff1a 还不知道怎么弄 xff0c 看看以后再来补充 xff0c 心情烦
  • RTK_LIB 源码、可执行文件、rtkget、观测文件、星历文件(精密星历、广播星历)、精密钟差文件介绍

    1 RTK LIB开源程序下载 xff1a 点开rtklib链接 xff1a 下载最新版本的可执行文件和程序源码 2 GNSS数据处理需要的文件 2 1 伪距定位 xff1a spp 观测数据 xff08 0 xff09 导航星历 广播星历
  • RTKLIB ppp rtk_post

    1 实时ppp xff1a IGS MGEX数据处理中心的播发的实时轨道钟差产品 xff0c 结合广播星历 xff0c 实现实时定位 2 事后的 xff08 近似实时 xff09 xff1a 下载精密星历 钟差产品 xff0c 结合其他的精
  • 4.使用静态库、动态库,常见问题解决

    使用动态库的流程 xff08 ORBSLAM3实例 xff09 xff1a 在调用动态库或静态库的 cpp文件添加库的头文件 xff08 可以包含路径 xff0c 也可以在cmakelist文件加头文件搜索路径 xff09 span cla

随机推荐

  • vscode查看代码更新历史

    开源代码推出新版本后 xff0c 如何查看代码更改信息 1 首先打开vscode xff0c 点击左侧的插件管理器 xff0c 进入插件面板 xff0c 搜索Git Graph并安装 2 点击下图图标 xff0c 即可进入Git Graph
  • git更新代码

    一 git一般有很多分支 xff0c 我们clone到本地的时候一般都是master分支 xff0c 那么如何切换到其他分支呢 xff1f 主要命令如下 xff1a 1 查看本地分支文件信息 xff0c 确保更新时不产生冲突 span cl
  • linux---硬链接和软链接

    文件系统 磁盘上文件读写存储与查找系统 xff08 管理 xff09 就是文件系统 xff0c 在每一个分区都会存在自己的文件系统 在这里我们有swap交换分区和文件分区 xff0c 我们这里只介绍文件分区 在文件分区都会有上图中的分块管理
  • char类型数组

    字符数组 xff08 一维 二维 xff09 字符数组是数组元素为char类型的一种数组 凡是适合数组的定义和赋值 xff0c 也都适合于字符数组 由于C语言没有提供字符串类型 xff0c 字符串一般用一维字符数组来存放 xff0c 而二维
  • ubuntu18.04 安装腾讯会议

    腾讯会议现在以及上线了Linux版本 xff0c 可以直接在腾讯会议官网下载linux 版本 xff0c 在官网点击免费下载 xff0c 可以直接下载Linux版本 腾讯会议下载链接 选择Linux版本 xff0c x86 64版本 xff
  • 2.树莓派系统备份

    树莓派使用SD卡来装载系统 xff0c 如果SD卡丢失或者损坏 xff0c 那么树莓派上的数据都会丢失 xff0c 所以一定要备份好SD卡 这篇文章可以帮你备份你的树莓派系统 主要内容为备份SD卡 xff0c 制作树莓派系统镜像以及在需要的
  • ic_gvins编译及环境配置问题解决

    RTK VIO松组合 对惯导精度要求较高 1 环境配置和编译 安装依赖项 span class token comment gcc 8 span span class token function sudo span span class
  • EVO画图设置

    一 绘图设置 1 更改背景色和网格 span class token comment 白色网格 span evo config span class token builtin class name set span plot seabor
  • GINS_OB环境配置

    1 程序简介 武大开源GNSS INS松组合IMU预积分有考虑地球自传和不考虑两种形式可以灵活设置GNSS中断时间IMU可以和里程计进行融合 2 环境配置 span class token comment gcc 8 g 43 43 8 s
  • OB_GINS程序框架

    1 程序运行 span class token builtin class name cd span OB GINS span class token comment 编译好的可执行文件 xff1a bin ob gins xff0c 参数
  • KEIL、MDK中关于__LINE__宏 printf 的显示不正确的问题

    span class token operator gt span define span class token function DEBUG span span class token punctuation span log span
  • VINS-回环检测与重定位

    参考博客 pose graph分析1 pose graph分析2 pose graph分析3
  • 源码安装naviagtion,但是出现[move_base-2] process has died 运行错误的解决办法

    今天开始记录ros遇到的问题 安装navigation可以使用两种方法 第一种 xff1a sudo apt get install ros kinetic navigation 这种安装方法最简单 xff0c 新手或者不需要动naviag
  • linux---静态库和动态库的制作和使用

    静态链接和动态链接 静态链接 xff1a 生成可执行代码 xff0c 链接静态库 xff08 与代码位置有关的链接方式 xff09 xff0c 需要将代码拷贝到我们的源代码中才能运行 动态链接 xff1a 生成可执行代码 xff0c 链接动
  • 加一

    加一 描述 给定一个由整数组成的非空数组所表示的非负整数 xff0c 在该数的基础上加一 最高位数字存放在数组的首位 xff0c 数组中每个元素只存储单个数字 你可以假设除了整数 0 之外 xff0c 这个整数不会以零开头 示例 1 输入
  • STM32bootloader原理解释

    STM32bootloader原理解释 一 STM32的常规启动流程 STM32的内部flash地址起始于0x8000000 xff0c 一般情况下 xff0c 程序文件就从此地址开始写入 此外STM32是基于Cortex M3内核的微控制
  • 模糊PID基本原理及matlab仿真实现(新手!新手!新手!)

    有关模糊pid的相关知识就把自己从刚接触到仿真出结果看到的大部分资料总结一下 xff0c 以及一些自己的ps 以下未说明的都为转载内容 1 转自 https blog csdn net weixin 36340979 article det
  • VMware+ubuntu+win10笔记本实现笔记本连接WIFI且ubuntu既可以上网又能连接开发板

    背景 最近在学习imx6ull开发板的时候 xff0c 发现开发板通过网线连接笔记本电脑却无法ping通ubuntu xff0c 于是捣鼓了很久终于可以了 xff0c 却又发现ubuntu不能上网了 xff0c 经过一番查找资料和尝试 xf
  • 在windows上用vscode打造比vc++6.0好用的C/C++ IDE,适用编程小白

    准备 xff1a 1 安装MinGW xff0c 添加gcc gdb等编译调试工具bin目录 头文件Include目录 库lib的路径到系统环境变量 xff0c 安装LLVM 添 加Clang编译器所在bin目录到系统环境变量 具体操作百度
  • C语言数据结构——线性表的链式存储结构

    文章目录 线性表的链式存储结构1 基本概念2 设计与实现3 优点和缺点 线性表的链式存储结构 1 基本概念 链式存储定义 xff1a 为了表示每个数据元素与其直接后继元素之间的逻辑关系 xff0c 每个元素除了存储本身的信息之外 xff0c