Fork me on GitHub

数据结构与算法之线性结构

线性表

定义:线性表是n个数据元素的有限序列,其一般描述为A=(a1,a2,a3,......,an)
存储方式:
(1)顺序存储

向量存储或一维数组存储
(2)链式存储
链式存储又分为单向链表存储、单向循环链表与双向链表存储。

单向链表

定义:单向链表是指结点中的指针域只有一个沿着同一方向表示的链式存储结构
存储方式:

如上图所示(图参考《数据结构与算法分析》),data是数据域,存储元素的值,next为指针域,存放相邻的下一个结点的地址

单链表加尾指针

定义:是在单向链表结构上,在尾结点上加了一个指针,方便进行尾端操作

单向循环链表

定义:循环链表又称为循环线性链表,定义基本上等同于单向链表,但是将单向链表的末尾结点的指针域的null变为指向第一个结点,逻辑上形成环形。
存储方式:类似于单向链表

双链表

在单向链表的基础上,在每个结点中再增加一个指向其直接前趋的指针域,这样就形成了两个方向的链,称之为双向链表。
存储方式:

与单链表相比加了一个前趋结点

双向循环链表

定义:在双链表基础上,将尾结点的后置指针指向头结点,将头结点的前置指针指向尾结点,在逻辑上是形成了两个方向的环形。

头指针、头结点和首元结点

首元结点:顾名思义,首先的第一个元素的结点
头结点:添加在首元结点前的一个结点,不是真实的元素结点,只是为了首元结点能跟其他结点一样方便操作。
头指针:指向链表第一个结点的指针,如果第一个结点是头结点,那么就是指向头结点,如果没有头结点,那么就指向首元结点

线性表的基本操作

如果作为一个开发者身份来创建一个线性表,需要考虑如何组织好数据,如何提供一套有用而且必要的操作,作为一个使用者来说,使用线性表如何解决自己的问题,它提供了哪些行之有效的操作。
通常在我们使用一个数据结构的时候,默认将会创建一个空表,或者创建一个带有多个元素的表,需要判断表是否为空,以便可以去遍历表的元素或者操作元素,检查某个元素是否在表中,需要动态改变表中元素的内容,比如修改指定元素,删除指定元素,删除一些满足某些条件的元素,有时会希望能组合多个表,或者从已有的表中获得一个新表,通过遍历表对表中所有元素都进行某个操作等。这些都是对于一个线性结构来说,很常见的一些操作。现在以开发者身份来说,满足这些必要操作,是创建线性表数据结构的基本要求。以下是线性表的一些基本操作,有多种复杂操作可以进行补充,比如对表中某个元素都进行某个操作、求两个表之间的并集、交集、差集等。
1、创建空表
2、清空表数据
3、判断表是否为空
4、获取表的长度
5、首端插入元素
6、尾端插入元素
7、在某个位置插入
8、首端删除元素
9、尾端删除元素
10、在某个位置删除
11、定位某个元素(查找某个元素的位置,如果不存在,返回-1)
12、遍历列表
13、修改某个位置的元素

总结

1、什么情况下,顺序表比链表好?

在频繁定位元素的情况下,顺序表比链表的性能高,顺序表可以常量时间去访问元素,链表则需要线性时间才能定位到元素。
2、单循环链表为什么使用尾指针比头指针比较好?
因为单循环链表中想要删除最后一个结点或者在头结点之前添加一个结点,都需要先找到末尾结点,这样时间复杂度则为O(n),如果为末尾结点加一个尾指针,那么时间复杂符就为O(1)了
3、多种链表优缺点总结
单链表:支持O(1)的首端插入和弹出元素,但定位元素和尾端操作都需要O(n)时间
单链表加尾指针:支持O(1)时间复杂度的首端插入和弹出、尾端的插入,但是对于尾端弹出元素还是不能高效实现
单向循环链表:支持O(1)时间复杂度的首尾操作,但是对于链表遍历的时候,结束循环条件有所不同
双向链表:支持O(1)时间复杂度的首尾操作,可以高效的找到前后结点
循环双向链表:支持O(1)时间复杂度的首尾操作,可以高效的找到前后结点,但是对于链表遍历的时候,结束循环条件有所不同

posted @   三脚半猫  阅读(187)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
点击右上角即可分享
微信分享提示