🎡从本章开始,我会逐步和大家学习数据结构的相关内容。
🎶本章会简单介绍线性表的顺序存储结构和链式存储结构的相关概念。
💕至于它们基本功能的实现,在后续文章中小编会为大家详细展开。
🎁还请喜欢的朋友们多多支持!
一、线性表的定义及特点
由n(n≧0)个数据特性相同的元素构成的有序数列称为线性表
- n=0时,即元素个数、线性表长度为零,称为空表。
- n>0时,及非空的线性表或线性结构,这种线性表具有以下特点:
(1)存在唯一的“第一个”数据元素。
(2)存在唯一的“最后一个”数据元素。
(3)除第一个元素外,结构中每个数据元素均只有一个前驱。
(4)除最后一个元素外,结构中每个数据元素均只有一个后继。
二、线性表的分类
1.顺序存储
🎡顺序存储的概念
简单的来说就是用一组地址连续的存储单元依次存储线性表中的数据元素,逻辑上相邻的数据元素,在物理次序上也是相邻的。通常,称这种顺序存储结构的线性表为顺序表。
只要确定了存储线性表的起始位置, 线性表中任一数据元素都可随机存取, 所以线性表的顺序存储结构是一种随机存取的存储结构。
🎡顺序表的优缺点
优点:
- 存储密度大(结点本身所占存储量/节点结构所占存储量)
- 数据元素地址连续,可以随机存取表中任一元素
缺点:
- 在插入、删除某一元素时,需要移动大量元素
- 浪费存储空间
- 属于静态存储形式,数据元素的个数不能自由扩充
💥易错:数组的下标是从 0 开始的,而线性表的位置序号是从 1 开始的,所以要注意区分元素的位置序号和该元素在数组中的下标位置之间的对应关系
为了克服顺序表的这些缺点,我们可以通过线性表的另一种表示方法——链式存储结构来解决
2.链式存储
🎡链式存储的概念
链式存储结构采用一组任意的存储单元存储线性表(可以连续可以不连续),包括数据域和指针域,数据域存数据,指针域指示其后继的信息。通常,称这种链式存储结构的线性表为链表。
链表又可以分为单链表、双链表、循环链表和静态链表。
头指针
通常使用“头指针”来标识一个链表。链表非空时,头指针指向的是第一个结点的存储位置。
头结点
在单链表的第一个结点之前附加一个结点,称为头结点。头结点的data域可以不设任何信息,也可以记录表长等相关信息。若链表是带有头结点的,则头指针指向头结点的存储位置。
带头结点和不带头结点的区别
- 带头结点的链表在第一个位置的插入、删除操作更加方便
试想一下,如果不带头节点对首元结点进行操作时,每次必须都要更新头指针的指向。与之相反,带头结点的链表在对首元结点进行操作时只需要固定的更新头结点中的指针域就可以了。 - 对空表和非空表的操作统一
带头结点的链表无论是否为空表,头指针都指向头结点,若不带头结点,当链表为空表时,头指针指向NULL;链表不为空表时,头指针指向第一个结点的地址。
💥强调:无论是否有头结点,头指针始终指向链表的第一个结点。如果有头结点,头指针就指向头结点。链表一般为带头结点的链表。
🎡单链表
我们将每个结点中只包含一个指针域的链表称为单链表。
单链表的缺点:
- 其查找时间复杂度为O(n),每次查找都需要从头遍历链表
- 存储密度小,指针域需额外占用存储空间。
因为单链表存在的这些缺点,无法直接找到前驱结点,所以就用到了双向链表和循环链表💕
🎡双链表
顾名思义,我们将每个结点中包含两个指针域,,一个存放前驱结点地址,一个存放后继结点地址的链表称为双向链表,简称双链表。
双链表的缺点:增加删除结点复杂,需要多分配一个指针存储空间。
🎡循环链表
简单的来说,循环链表就是将尾结点原来next域的NULL变成头结点的地址(指向头结点)
🎶小tips:
- 判断循环链表结束条件:p->next=L
- 在使用单循环链表时,可以用尾指针指向最后一个元素,这样若对头结点和尾结点操作,时间复杂度均为O(1)
好啦ヾ(≧▽≦*)o,线性表的顺序、链式存储结构就简单介绍到这里,它们基本功能的实现会在后续文章中详细展开,如果发现什么错误的地方还请朋友们斧正❤️