一、线性表逻辑结构
线性表定义:线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。
一个数据元素可由多个数据项(item)组成,此种情况下常把数据元素称为记录(record),含有大量记录的线性表又称文件(file)。
线性表中的个数n定义为线性表的长度,n=0时称为空表。在非空表中每个数据元素都有一个确定的位置,如用ai表示数据元素,则i称为数据元素ai在线性表中的位序。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。
线性表的特征
1.集合中必存在唯一的一个"第一元素"。
2.集合中必存在唯一的一个 "最后元素" 。
3.除最后一个元素之外,均有 唯一的后继(后件)。
4.除第一个元素之外,均有 唯一的前驱(前件)。
三、线性表的存储结构
基于线性表的逻辑结构,线性表实现的逻辑结构可以采用顺序存储结构和链式存储结构。在C语言编码中,可以使用一维数组和链表来实现线性表。在java语言中,ArrayList(数组列表)和LinkedList(链式列表)的实现也基于这两种存储方式,因此,在使用上,可以根据以下来判断他们性能的优缺点。
1、顺序存储结构
用一段连续的存储单元一次存储线性表的数据元素。在C语言描述中,采用一维数组来实现顺序存储结构。因为数组使用前先开辟一段连续的内存存储空间及数组本身的特点,因此会有如下相对于链式存储结构的优缺点。
优点:(1)无需为元素的逻辑关系开辟额为的存储空间,即相对于链式来说,存储空间占用小。
(2)随机存取,可以根据数组下标,随机存取一个元素。
缺点:(1)需要预先分配足够大的存储空间,估计过大,可能会导致顺序表后部大量闲置;预先分配过小,又会造成溢出。
(2)当删除或插入一个元素时,平均移动大约表中一半的元素,因此对n较大的顺序表效率低。
2、链式存储结构
主要针对于顺序存储结构的两个缺点而设计。
链表:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。以下为链表删除一个结点的实例,在代码编程中,只需要把删除结点的前驱结点的指针域指向删除结点的后继结点即可,再释放被删除结点的空间。无需移动结点,因而相对于数组方式,在删除、或增加一个结点时,无需移动元素,因而平均效率更高。
优点:
(1) 在链表中做插入删除操作时,只需要修改结点的指针域的指向,无需移动结点,因此对n较大的链表效率高。
(2) 不需要预先分配足够大的存储空间,避免造成空间闲置或溢出的情况。
缺点:
(1) 需要为表示结点间的逻辑关系(指针变量)而增加额外的存储开销。
(2) 查找结点时,只能通过遍历方式结点的方式。
三、链表类型
为了克服单向链表的缺点,又有了双向量表和循环链表。
1、单向链表
单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点;列表是由结点构成,head指针指向第一个成为表头结点,而终止于最后一个指向nuLL的指针。
2、双向链表
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。相对于单项链表来说,又开销了一个指针域,但是在查找性能方面优于单向链表。一个删除的实例
3、循环链表
又可以分为单向循环链表和双向循环链表
循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。