1.双向链表:
typedef struct DuLNode
{
ElemType data; //数据域
struct DuLNode* prior; //指向前驱的指针域
struct DuLNode* next; //指向后继的指针域
} DuLNode, *DuLinkList;
2.循环链表:最后一个结点的指针域指向第一个结点的链表。如果对链表常做的操作是在表尾进行,可以定义一个指向尾结点的尾指针,可以使得操作效率得以提高。循环链表和单链表的差别:
(1)判断链表中最后一个结点的条件不再是后继是否为空,而是后继是否为头结点。
(2)单链表只能从头结点开始遍历整个链表,单循环链表可以从表中任意结点开始遍历整个链表。
3.双向循环链表:查询操作和单链表相同。插入和删除时需要同时修改两个方向上的指针。
4.静态链表:借助数组来描述线性表的链式存储结构,每个结点也有数据域和指针域,与链表中的指针不同的是,静态链表的指针是结点的相对地址(数组的下标),称之为静态指针。静态链表特点如下:
(1)所有数据元素均存储在一个连续的空间段,但是相邻两个元素不一定处于相邻的空间;
(2)修改指针域即可完成插入和删除操作,不需要移动数据元素,但是也不能随机访问静态链表中的元素;
(3)一次性分配所有存储空间,插入、删除时无需再向操作系统申请或释放空间,但也限制了最大表长。
5.线性表的静态单链表存储结构:
#define MAXSIZE 1000
typedef struct
{
ElemType data;
int next;
} component, SLinkList[MAXSIZE];
静态链表适用于不支持指针的高级语言,或者最大元素数固定但插入、删除操作频繁的链表应用中。有关基于静态链表上的线性表的操作基本与动态链表相同,除了一些描述方法有些区别外,算法思路相同。
6.顺序表和链表各有优缺点:
(1)顺序存储优点:
①方法简单,各种高级语言中都有数组,容易实现。
②不用为表示结点间的逻辑关系而增加额外的存储开销。
③顺序表具有按元素序号随机访问的特点。
(2)顺序存储缺点:
①在顺序表中做插入、删除操作时,平均移动大约表长一半的元素,因此对n较大的顺序表效率较低。
②需要预先分配足够大的存储空间,估计过大,可能会导致顺序表后部大量闲置;预先分配过小,又会造成溢出。
(链表的优缺点与顺序表相反。)
7.选取存储结构的方法:
(1)基于存储的考虑:顺序表在程序执行之前必须明确规定它的存储规模,事先对MAXSIZE要有合适的设定,过大造成浪费,过小造成溢出。线性表的长度或存储规模难以估计时,不宜采用顺序表;链表不用事先估计存储规模,但链表的存储密度较低。
(2)基于运算的考虑:在顺序表中按序号访问数据元素的时间性能是0(1),而链表中按序号访问的时间性能是O(n),所以如果经常做的运算是按序号访问数据元素,显然顺序表优于链表;而在顺序表中做插入、删除时平均移动表中一半的元素,当数据元素的信息量较大且表较长时,代价较大;在链表中做插入、删除,虽然也要找插入位置,但主要操作是比较,从这个角度看显然后者优于前者。
(3)顺序表容易实现,任何高级语言中都有数组类型,链表的操作是基于指针的,相对来讲前者简单些。