数据结构-线性表的链式表示

目录

  • 前言
  • 一、线性表的链式表示和实现
    • 1.1 线性表的表示
    • 1.2 基本操作的实现
    • 1.3 线性表的链式表示的优缺点
  • 总结

前言

本篇文章主要介绍线性表的链式表示

一、线性表的链式表示和实现

1.1 线性表的表示

线性表的链式表示又称为链式存储结构或链式映像
链式存储定义:逻辑上相邻的数据元素在物理存储结构中不一定相邻
线性表的链式表示是用一组物理位置任意的存储单元来存放线性表的数据元素,这组存储单元可能是连续,也可能是不连续的,取决于操作系统的分配策略。
线性表的逻辑关系使用指针表示

线性表
( a , b , c , d ) (a,b,c,d) (a,b,c,d)
链式存储结构
在这里插入图片描述
一个结点由数据域和指针域组成
数据域:数据元素本身本身信息,
指针域:存储其后继结点的存储地址
一般,称指向第一个结点的指针称为链表的头指针

一般,可以将链式存储结构简化如下图表示:
在这里插入图片描述
单链表是由头指针唯一确定,因此单链表可以用头指针的名字来命令。

与链式存储结构有关的术语
假设有一个线性表 ( a 1 , a 2 , ⋯ , a n ) (a_1,a_2,\cdots,a_n) (a1,a2,,an),其链式存储结构如下:
在这里插入图片描述

头指针:指向链表的第一个结点的指针
首元结点:指链表中存储第一个数据元素 a 1 a_1 a1的结点
头结点:为了便于对链表的处理,在链表的首元结点之前附加的一个结点

假设一个线性表为 ( a , b , c , d ) (a,b,c,d) (a,b,c,d)
不带头结点的链式存储结构
在这里插入图片描述

带头结点的链式存储结构
在这里插入图片描述
讨论

  1. 如何表示空表?
    无头结点时,头指针为空时表示空表
    有头结点时,当头结点的指针域为空时表示空表
  2. 在链表设置头结点的好处?
    便于首元结点的处理
    便于空表和非空表的处理

1.2 基本操作的实现

单链表的定义和表示

//定义返回值常量
#define SUCCESS 1
#define ERROR 0//假设数据元素类型为char
typedef char ElemType;//定义结点类型
struct Node;				  	
typedef struct Node* PNode;   //假设作为结点指针类型
struct Node {ElemType data;   //数据域PNode next;		//指针域
};typedef struct Node* LinkList;  //假设作为单链表类型

为了处理方便,这是使用带头结点的链式存储结构。
下面介绍如何实现线性表的基本操作。

  1. 创建空链表
    step1 使用malloc()函数创建一个sizeof(struct Node)大小的空间作为头结点
    step2 将头结点的指针域置为NULL,表示一个空表

    	//3.1 创建一个空链表
    LinkList createNullList_link(void)
    {LinkList llist = (LinkList)malloc(sizeof(struct Node));if (NULL == llist){printf("malloc fail!\n");return NULL;}llist->next = NULL;return llist;
    }
  2. 销毁链表
    step1 首先销毁链表的数据元素结点
    step2 最后销毁链表的头结点

    //3.2 销毁一个单链表
    void destroyList_link(LinkList* linkList)
    {assert(linkList && *linkList);PNode p = (*linkList)->next;//1. 销毁数据元素结点while (p){PNode pnext = p->next;free(p);p = pnext;}//2. 销毁头结点free(*linkList);*linkList = NULL;
    }
    
  3. 链表的查找
    step1 判断链表是否为空表
    step2 从首元结点开始查找
    step3 查找失败,返回ERROR;查找成功,返回数据元素的位置序号

    	//3.7 根据指定数据元素e获取数据元素的对应序号
    int locateElem_link(LinkList linkList, ElemType e)
    {assert(linkList);PNode p = linkList->next; //首元结点int j = 1;while (p && p->data != e){p = p->next;j++;}if (p)return j;elsereturn ERROR;
    }
    
  4. 链表的插入
    step1 首先找到 a i − 1 的存储位置 p a_{i-1}的存储位置p ai1的存储位置p
    step2 生成一个数据域为e的新结点newNode
    step3 插入新结点,即newNode的指针域指向 a i a_i ai,结点 a i − 1 a_{i-1} ai1的指针域指向newNode
    在这里插入图片描述

    //3.8 在第i个元素之前插入数据元素e
    int insertElem_link(LinkList linkList, int i, ElemType e)
    {assert(linkList);PNode p = linkList;  //考虑插入位置可能在第1个之前int j = 0;while (p && j < i - 1){p = p->next;++j;}if (!p || j > i - 1)  //当 p == NULL成立时,说明i-1大于表长; j > i-1 为了应对i <= 0情况 return ERROR;//新建结点PNode newNode = (PNode)malloc(sizeof(struct Node));if (NULL == newNode){printf("malloc fail!\n");return ERROR;}newNode->data = e;newNode->next = p->next;p->next = newNode;return SUCCESS;
    }
    
  5. 链表的删除
    step1 首先找到 a i − 1 a_{i-1} ai1的存储位置p
    step2 使结点 a i − 1 a_{i-1} ai1的指针域指向 a i + 1 a_{i+1} ai+1
    在这里插入图片描述

    
    //3.9 将链表第i个数据元素删除
    int deleteElem_link(LinkList linkList, int i)
    {assert(linkList);PNode p = linkList;int j = 0;while (p->next && j < i - 1){p = p->next;j++;}if (!(p->next) || j > i - 1)  //p->next,因为删除的是p->next,而不是p所指的结点return ERROR;PNode q = p->next;p->next = q->next;free(q);q = NULL;return SUCCESS;
    }
    

1.3 线性表的链式表示的优缺点

  • 优点
    在线性表的链式存储结构中,数据元素之间的逻辑关系靠结点的指针域来指示,结点的空间是动态申请和动态释放的,所以不需要预先按最大的需要分配连续空间;
    线性表的插入和删除只需要修改指针域,而不需要移动其他数据元素

  • 缺点
    存储密度小,每个结点的指针域需要额外占用存储空间;
    链式存储结构是一种非随机存储结构,查找任一个结点都要从头指针开始,沿着指针链一个一个地搜索,增加算法的时间代价。

总结

完整代码:https://gitee.com/PYSpring/data-structure/tree/master

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

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

相关文章

MATLAB将两个折线图画在一个图里

界面如图 输入行数和列数&#xff0c;点击开始填入数据&#xff0c;其中第一列为x值&#xff0c;后面几列&#xff0c;每一列都是y坐标值&#xff0c;填好后点击画在同一张图里即可。点击置零就把所有数变成0&#xff0c;另外也可以选择节点样式。 .mlapp格式的文件如下 夸克…

【MotionCap】ImportError: cannot import name ‘packaging‘ from ‘pkg_resources‘

ImportError: cannot import name ‘packaging’ from ‘pkg_resources’ 降低setuptools的版本 参考大神:(ai-mocap) zhangbin@ubuntu-server:~/proj/04_mocap/third-party$ pip install -e neural_renderer

C# 验证PDF数字签名的有效性

数字签名作为PDF文档中的重要安全机制&#xff0c;不仅能够验证文件的来源&#xff0c;还能确保文件内容在传输过程中未被篡改。然而&#xff0c;如何正确验证PDF文件的数字签名&#xff0c;是确保文件完整性和可信度的关键。本文将详细介绍如何使用免费.NET控件通过C#验证PDF签…

OpenCV 车牌检测

OpenCV 车牌检测 级联分类器算法流程车牌检测相关链接 级联分类器 假设我们需要识别汽车图像中车牌的位置&#xff0c;利用深度学习目标检测技术可以采取基于锚框的模型&#xff0c;但这需要在大量图像上训练模型。 但是&#xff0c;级联分类器可以作为预训练文件直接使用&…

C++ 106 之 list容器

#include <iostream> #include <string> using namespace std; // #include <vector> // 容器头文件 #include <algorithm> // 标准算法头文件 #include <list>void printList(const list<int> & list1){for(list<int>::const…

【ai】ubuntu18.04 找不到 nvcc --version问题

nvcc --version显示command not found问题 这个是cuda 库: windows安装了12.5 : 参考大神:解决nvcc --version显示command not found问题 原文链接:https://blog.csdn.net/Flying_sfeng/article/details/103343813 /usr/local/cuda/lib64 与 /usr/local/cuda-11.3/lib64 完…

【C++】string类的模拟实现

文章目录 string类的存储结构默认成员函数构造函数析构函数拷贝构造函数赋值重载 容量操作size()capacity()reserve()resize()clear() 遍历与访问operator[ ]迭代器范围与for 增删查改push_back()pop_back()append()operatorinsert()erase()c_str()find()substr() 非成员函数op…

VisualRules组件功能介绍-计算表格(二)

本章内容 1、计算表格数据回写数据库 2、计算表格数据更新 3、计算表格数据汇总 4、计算表格数据追加 一、计算表格数据回写数据库 计算表格数据回写数据库表。采用遍历计算表格逐条插入数据库表。在具体操作过程可以采用向导方式操作。 先在数据库表中创建tb_user_new表。…

python-糖果俱乐部(赛氪OJ)

[题目描述] 为了庆祝“华为杯”的举办&#xff0c;校园中开展了许多有趣的热身小活动。小理听到这个消息非常激动&#xff0c;他赶忙去参加了糖果俱乐部的活动。 该活动的规则是这样的&#xff1a;摊位上有 n 堆糖果&#xff0c;第 i 堆糖果有 ai​ 个&#xff0c;参与的同学可…

让采购和工程师们既爱又恨的任务——BOM

在项目研发与生产过程中&#xff0c;有一个常常让采购经理和工程师们既爱又恨的任务&#xff0c;那就是整理BBOMB。BOM作为连接设计与制造的桥梁&#xff0c;其重要性不言而喻&#xff0c;它详细列出了产品构成所需的所有零部件、材料及其规格、数量&#xff0c;是成本估算、采…

用四个场景案例,分析使用大模型对程序员工作的帮助提升_大模型应用场景

引言 随着人工智能技术的不断发展&#xff0c;大模型在软件开发中的应用越来越广泛。 这些大模型&#xff0c;如GPT、文心一言、讯飞星火、盘古大模型等&#xff0c;可以帮助程序员提高工作效率&#xff0c;加快开发速度&#xff0c;并提供更好的用户体验。 本文将介绍我在实…

Unity海面效果——4、法线贴图和高光

Unity引擎制作海面效果 大家好&#xff0c;我是阿赵。 继续做海面效果&#xff0c;上次做完了漫反射颜色和水波动画&#xff0c;这次来做法线和高光效果。 一、 高光的计算 之前介绍过高光的光照模型做法&#xff0c;比较常用的是Blinn-Phong 所以我这里也稍微连线实现了一下 …

苍穹外卖项目 常用注解 + 动态sql

常用注解 常见的注解解析方法有两种&#xff1a; 编译期直接扫描&#xff1a;编译器在编译 Java 代码的时候扫描对应的注解并处理&#xff0c;比如某个方法使用Override 注解&#xff0c;编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。运行期通过反射处理&…

云数据中心运维新纪元:让Linux服务器如虎添翼

文章目录 一、Linux系统管理的高级技巧1. 性能调优与监控&#xff1a;2. 自动化与脚本编写&#xff1a;3. 文件系统与存储管理&#xff1a; 二、服务器配置优化的策略1. 硬件选型与配置&#xff1a;2. 网络配置与优化&#xff1a;3. 应用部署与调优&#xff1a; 三、安全策略的…

postgre事务id用完后,如何解决这个问题

在PG中事务年龄不能超过2^31 &#xff08;2的31次方2,147,483,648&#xff09;&#xff0c;如果超过了&#xff0c;这条数据就会丢失。 PG中不允许这种情况出现&#xff0c;当事务的年龄离2^31还有1千万的时候&#xff0c;数据库的日志中就会 有如下告警&#xff1a; warning:…

js获取当前浏览器地址,ip,端口号等等

前言&#xff1a; js获取当前浏览器地址&#xff0c;ip&#xff0c;端口号等等 window.location属性查询 具体属性&#xff1a; 1、获取他的ip地址 window.location.hostname 2、获取他的端口号 window.location.port 3、获取他的全路径 window.location.origin 4、获取…

【机器学习】基于层次的聚类方法:理论与实践

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 基于层次的聚类方法&#xff1a;理论与实践引言1. 层次聚类基础1.1 概述1.2 距离…

讨论Nginx服务器的反爬虫和反DDoS攻击策略

Nginx服务器是一个高性能的Web服务器和反向代理服务器&#xff0c;具有强大的反爬虫和反DDoS攻击能力。本文将讨论Nginx服务器的反爬虫和反DDoS攻击策略&#xff0c;并给出相关的代码示例。 一、反爬虫策略 爬虫是一种自动化程序&#xff0c;用于从互联网上收集特定网站的数据…

【产品运营】Saas的核心六大数据

国内头部软件公司的一季度表现惨不忍睹&#xff0c;为啥美国的还那么赚钱呢&#xff1f;其实核心是&#xff0c;没几个Saas产品经理是看数据的&#xff0c;也不知道看啥数据。 SaaS 行业&#xff0c;天天抛头露面、名头叫的响的 SaaS 产品&#xff0c;真没有几个赚钱的。 那为…

笔记101:OSQP求解器的底层算法 -- ADMM算法

前言1&#xff1a;这篇博客仅限于介绍拉格朗日乘子法&#xff0c;KKT条件&#xff0c;ALM算法&#xff0c;ADMM算法等最优化方法的使用以及简版代码实现&#xff0c;但不会涉及具体的数学推导&#xff1b;不过在下面我会给出具体数学推导的相关文章和截图&#xff0c;供学有余力…