顺序表和链表的比较
一、基于空间的考虑
1、
顺序表的存储空间是静态分配的,在程序执行之前必须明确规定体制的存储规模。若线性表的长度n变化较大,则存储规模难以预先确定。估计过大将造成空间浪费,估计太小又将使空间溢出的机会增多,但是动态顺序表加入的扩容机制,只要内存空间尚有空闲,溢出现象便不会出现。而动态链表(既然都这么说了,当然也是有静态链表这么一说的,但是在此就不做过多讨论了,我会在下一博客浅谈一下静态链表)的存储空间是动态分配的,只要内存空间尚有空闲,就不会产生溢出。
2、
存储密度(Storage Density)是指结点数据本身所占的存储量和整个结点结构所占的存储量之比,即存储密度=结点数据本身所占的存储量/结点结构所占的存储总量。链表中的每个结点,除了数据域外,还要额外设置指针域,从存储密度讲,这是不经济的。
一般地,存储密度越大,存储空间的利用率就越高。显然顺序表的存储密度为1,而链表的存储密度小于1。
例如,单链表的结点数据均为整数,指针所占空间在32位环境下和整形量相同,而Windows默认对齐值#pragma pack(8),因此单链表的存储密度为50%。因此若不考虑顺序表中的备用结点空间(就是一开始在结构体内定义了一个较大的数组作为备用结点空间)则顺序表的存储空间利用率为100%,而单链表的存储空间利用率为50%。由此可知,当线性表的长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表作为存储结构。如果在不能确定存储数据多少的情况下,用链表是非常合适的,因为在这种情况下,链表的总体空间利用率非常高,哪怕是动态顺序表的也远没有链表的高。
二、基于时间的考虑
顺序表是由向量实现的,它是一种随机存取结构,对表中任一结点都可以在O(1)的时间内直接进行存取,而链表中的结点需从头指针起顺着链才能找到。因此,若线性表的操作主要是进行查找,很少做插入和删除时,宜采用顺序表做存储结构。
在链表中的任何位置上进行插入和删除时,都只需要修改指针。而在顺序表中进行插入和删除时,平均要移动表中近一半的结点,尤其是当每个结点的信息量较大时,移动结点的时间开销就相当可观。因此,对于频繁进行插入和删除的线性表,宜采用链表做存储结构。若表的插入和删除主要发生在表的首尾两端,则宜采用尾指针表示的单循环链表。
三、基于语言的考虑
在没有提供指针类型的高级语言环境中,若要采用链表结构,则可以使用游标实现的静态链表。虽然静态链表存储分配上有不足之处,但它和动态链表一样,具有插入和删除的方便特点。
值得提出的是即使是对那些具有指针类型的语言,静态链表也有其用武之地。特别是当线性表的长度不变,仅需改变结点的相对关系时,静态链表比动态链表可能更方便。
顺序表插入,尾插方便,其他的不方便,删除同理。
链表插入,头插方便,其他的不方便,删除同理。虽然在链表中的任何位置上进行插入和删除时,都只需要修改指针,这操作起来是很方便,但前提是你得找到这个位置,而找对于链表来说就会比较麻烦。这也是为什么头插/删相较于其他的插入和删除方式比较方便。