顺序表 | 链表 | |
尾插尾删 | 尾插/尾删:O(1) | 不带头结点的单链表--尾插,删除节点方式遍历链表O(N) |
插入删除 | 任意位置的插入和删除O(n) | 单链表只能插入节点之后,在给节点位置之后O(1) |
访问元素 | 支持随机访问 | 不支持随机访问 |
底层空间 | 连续空间 | 空间不连续 |
扩容问题 | 扩容两倍 | 不扩容 |
空间利用率 | 看具体场景 | 看具体场景 |
重复开辟空间 | 不需要 | 需要(频繁的申请空间,每次插入都需要申请,频繁向系统要一些小的内存块,内存碎片问题,内存空间在开辟时候 需要额外的向系统要多一点,保证堆上这个空间被用)在不同编译器下可能不一样Vs上前面要了32个字节,后面加4个字节,效率也低 |
应用场景 | 插入删除元素不多,只需要存储数据 | |
缓存利用率 | 高 | 低 |
cpu在操作数据的时候,内存将数据加载到缓存中去(局部原理性),在缓存中去读的时候,不会只读一块,会读取连续的数据
相关数据结构构造
class DataStuct {
public:
//静态存储,以数组作为存储结构,他们的内存是连续的
#define N 7
typedef int SLDataType;
typedef struct Staticlist {
int array[N];
int capacity;
};
//动态的去开辟内存空间 他们的内存还是连续的
typedef struct Seqlist {
SLDataType *array;
size_t size; //有效个数
size_t capacity; //容量的大小
};
/*
中间/头部的插入 复杂度为O(N)
动态数组增容需要申请新空间,会有不小消耗
增容一般是2倍的增长,但是还是避免不了合理不合理
*/
typedef struct Slist {
SLDataType _data;
struct Slist *next;
};
}