顺序表和链表(双向带头链表)的区别
顺序表:
- 优点:
- 支持随机访问。需要随机访问结构支持算法可以很好的使用。
- cpu高速缓存利用率(命中率)更高。
- 存储密度高
- 缺点:
- 头部中部插入删除时间效率低。O(N)
- 连续的物理空间,空间不够了以后需要增容。
- 增容有一定程序消耗。
- 为了避免频繁增容,一般我们都以2倍数去增,如果用不完可能存在一定的空间的浪费。
链表(双向带头循环链表):
- 优点:
- 任意位置插入删除效率高。O(1)
- 按需申请释放空间。
- 缺点:
- 不支持随机访问。(用下标访问)意味着:一些排序,二分查找等在这种结构上不适用。
- 链表存储一个值,同时需要存储链接指针,也有一定的消耗。
- 存储密度小。
- cpu高速缓存命中率低。
总体而言。顺序表和链表的区别,如下表格:
不同点 | 顺序表 | 链表 |
---|---|---|
存储空间上 | 物理上一定连续 | 逻辑上连续,物理上不连续 |
随机访问 | 支持O(1) | 不支持O(N) |
任意位置插入或者删除元素 | 可能需要搬移元素,效率低O(N) | 只需要修改指针指向 |
插入 | 动态顺序表,空间不够时需要扩容 | 没有熔炼过的概念 |
应用场景 | 元素高效存储+频繁访问 | 位置任意访问和删除频繁 |
缓存利用率 | 高 | 低 |
存储密度
存储密度是指结点数据本身所占的存储量和整个结点结构中所占的存储量之比,即:
例如:
一般地,存储密度越大,存储空间的利用率就越高。显然,顺序表的存储密度为1(100%),而链表的存储密度小于1。
cpu高速缓存利用率讲解
备注:缓存利用率参考存储体系结构以及局部原理性。
那这和顺序表、链表有什么关系呢?如下分析:
现在有一个顺序表和一个链表:
我们直到cpu需要运行指令,顺序表和链表的数据在内存中。
首先访顺序表中存储数据1
的内存位置尾0x00123400和链表中存储数据1
(0x00200000),先看这个地址在缓存中没有(L1-cache、L2-cache、L3-cache),如果在就直接访问,不在就先加载到缓存,在访问。
我们可以想到在访问顺序表和链表的第一个数据时,由于数据都不在缓存中,所以二者的cpu利用率一样。
但是由计算机的理论支持:内存在访问时,默认会访问连续内存空间位置。这也就意味着在加载内存时,不会只加载一个数据的位置,而是加载这个数据后面的一片位置,具体加载多少取决于内存。由于顺序表就是连续的存储空间,而链表有可能不是连续的存储空间,所以在加载内存时,顺序表会加载一大片数据,而链表只是有可能加载一片数据,也有可能一次加载一个数据。所以顺序表的cpu高速缓存利用率高,而链表cpu高速缓存利用率低。