第二章——线性表之循环链表、静态链表

发布于:2025-06-12 ⋅ 阅读:(23) ⋅ 点赞:(0)

循环链表

循环单链表

循环单链表和单链表的区别在于,表中最后一个结点的指针不是NULL,而改为指向头结点,从而使整个链表成环,如下图所示:
在这里插入图片描述
显然,在循环链表中没有指针域为NULL的结点,因此,循环单链表的判空条件不是头结点的指针是否为空,而是它是否等于头指针L

循环双链表

与循环单链表类似,循环双链表中,尾结点的next指针要指向头结点,头结点的prior指针要指向尾结点。
如何判断一个循环双链表是空表呢?当其头结点的next域和prior域都等于头指针L时。
在这里插入图片描述

静态链表

静态链表是用数组来描述线性表的链式存储结构,结点也有数据域data和指针域next,与前面所讲的链表中的指针不同的是,这里的指针是结点在数组中的相对地址也就是数组下标,又称游标。和顺序表一样,静态链表也要预先分配一块连续的内存空间
总的来说,静态链表没有单链表使用起来方便。但对于一些不支持指针的高级语言(如Basic),这是一种非常巧妙的设计方法。
静态链表和单链表的对应关系如下图所示:
在这里插入图片描述

顺序表和链表的比较

存取(读/写)方式

  • 顺序表可以顺序存取,也可以随机存取;
  • 链表只能从表头开始依次顺序存取。
  • 比如:顺序表访问第i个位置时仅需访问一次,而链表则需从表头开始依次访问i次。

逻辑结构与物理结构

  • 采用顺序存储时,逻辑上相邻的元素,对应的物理存储位置也相邻。
  • 而采用链式存储时,逻辑上相邻的元素,物理存储位置不一定相邻,对应的逻辑关系是通过指针链接来表示的。

查找、插入和删除操作

  • 对于按值查找,顺序表无序时,两者的时间复杂度均为O(n);顺序表有序时,可采用折半查找,此时的时间复杂度为O(logn)。
  • 对于按序号查找,顺序表支持随机访问,时间复杂度为O(1);而链表的平均时间复杂度为O(n)。
  • 顺序表的插入、删除操作,平均需移动半个表长的元素。
  • 链表的插入、删除操作,只需修改相关结点的指针域即可。

空间分配

  • 顺序存储在静态存储分配的情形下,一旦存储空间装满就不能扩充,若再加入新元素,则会出现内存溢出,因此需要预先分配足够大的存储空间。然而,预先分配过大,可能会导致顺序表后部大量闲置;预先分配过小,则可能会溢出。
  • 顺序存储在动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量元素,导致操作系统效率降低,而且若内存中没有更大块的连续存储空间,则会导致分配失败。
  • 链式存储的结点空间只在需要时申请分配,只要内存有空间就可以分配,操作灵活、高效。此外,由于链表的每个结点都带有指针域,因此存储密度不够大。