1、线性结构
在数据元素的非空有限集中:
-
存在唯一的一个被称做“第一个”的数据元素
-
存在唯一的一个被称做“最后一个”的数据元素
-
除第一个之外,集合中的每个数据元素均只有一个前驱
-
除最后一个之外,集合中的每个数据元素均只有一个后继
2、线性表
线性表是n个数据元素的有限序列,同一线性表中的元素必定具有相同特性,相阾的数据元素之间存在着序偶关系。
线性表中元素的个数n(n>=0)定义为线性表的长度,0==n时称为空表,在非空表中每个数据元素都有一个确定的位置(下标)。
线性表是一个相当灵活的数据结构,
线性表的顺序表示和实现:
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。
它的长度可根据需要增长或缩短。
线性表的链式表示和实现
线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中的任一元素,它的存储位置可以用一个简单、直观的公式来表示。
这个特点也铸成了这种存储结构的缺点:在插入、删除操作时,需要移动大量的元素。而线性表的另一种表示方法——链存储结构刚好弥补了它的缺点。
链存储结构不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构所有具有的缺点,但同时也失去了顺序存储结构可随机存取的优点。
链存储结构的特点是元素可以使用存储内存中的任何位置(可以是连续的,也可以不连续),元素a[i]和a[i+1]的逻辑关系不依靠相对位置,而是元素中增加一个指示其后继元素的数据(元素指针),元素本身的数据+后继信息构成了存储映像,俗称节点(node)。
typedef struct Node { TYPE data; // 数据域 struct Node* next; // 指针域 }Node;
若干个元素节点通过指针域连接起来,形成的线性表结构称为链式表,简称链表,节点中只有一个指向后继元素的指针域,这种链表也被称为单向链表。
单向链表必须有一个指向第一个节点的指针,被称为头指针,被它指向的节点也被称为头节点,头节点可以不存储数据,单纯的作为一个占位节点,最后一个节点指向空,作为结束标志。
双向链表
所谓的双向链表就是链表节点中有两个指针域,一个指向前一个节点,叫前驱指针一般取名为prev,另一个指向后一个节点,叫后继指针,一般取名为next,双向链表的优点是可以从后向前遍历链表,对于链表后半部分的节点的访问效率大大提升。
// 双向链表节点 typedef struct Node { struct Node* prev; // 前驱指针域 TYPE data; // 数据域 struct Node* next; // 后继指针域 }Node;
根据之前的经验,当从前往后操作链表时,有一个空的头节点,方便操作,但现在我们需要从后往前操作链表,所以也需要一个空的尾节点。
双向循环链表
所谓的双向循环链表就是头节点的前驱是尾节点,头节点是尾节点的后继,这样的好处是可以让头节点、尾节点共用一个空白节点,有些奇怪的是当链表空时,空白节点的前驱和后继指针都指向自己,操作双向循环链表时,不存在空指针,以下是有修改代码,其它代码与双向链表没有区别。