【408数据结构 03】线性表与顺序表:C++手写SeqList
专栏导航 :本篇是《408数据结构:C++手写实现 + 图解 + 真题》第 03 篇。
上一篇 :【408数据结构 02】时间复杂度与空间复杂度:大O、均摊、408怎么考
下一篇:【408数据结构 04】单链表基础:头插、尾插、查找、插入、删除
### 文章目录
- [【408数据结构 03】线性表与顺序表:C++手写SeqList](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [@toc](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [一、本篇考点定位](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [二、线性表是什么](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [2.1 逻辑结构](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [2.2 两种基本存储方式](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [三、顺序表的定义](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [3.1 结构](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [3.2 图解](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [3.3 特点](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [四、顺序表的基本操作](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.1 静态分配与动态分配](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.2 初始化](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.3 插入操作](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.4 删除操作](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.5 按位查找](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.6 按值查找](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.7 扩容](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [4.8 销毁](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [五、平均移动次数分析(408 高频)](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [5.1 插入的平均移动次数](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [5.2 删除的平均移动次数](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [5.3 对比表](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [六、完整 C++ 手写实现](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [七、408 真题与考法](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [7.1 选择题:地址计算](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [7.2 选择题:平均移动次数](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [7.3 选择题:插入位置合法性](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [7.4 综合题:顺序表算法设计](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [7.5 综合题:有序顺序表合并](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [八、易错点总结](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
- [九、总结与下一篇预告](#文章目录 【408数据结构 03】线性表与顺序表:C++手写SeqList @[toc] 一、本篇考点定位 二、线性表是什么 2.1 逻辑结构 2.2 两种基本存储方式 三、顺序表的定义 3.1 结构 3.2 图解 3.3 特点 四、顺序表的基本操作 4.1 静态分配与动态分配 4.2 初始化 4.3 插入操作 4.4 删除操作 4.5 按位查找 4.6 按值查找 4.7 扩容 4.8 销毁 五、平均移动次数分析(408 高频) 5.1 插入的平均移动次数 5.2 删除的平均移动次数 5.3 对比表 六、完整 C++ 手写实现 七、408 真题与考法 7.1 选择题:地址计算 7.2 选择题:平均移动次数 7.3 选择题:插入位置合法性 7.4 综合题:顺序表算法设计 7.5 综合题:有序顺序表合并 八、易错点总结 九、总结与下一篇预告)
一、本篇考点定位
线性表是 408 数据结构的第一章核心内容,也是后面栈、队列、串的基础。
408 对线性表的考查主要集中在:
| 考点 | 重要程度 | 常见题型 |
|---|---|---|
| 线性表的逻辑结构与存储结构 | ★★★★ | 选择题 |
| 顺序表的定义与地址计算 | ★★★★★ | 选择题 |
| 顺序表插入、删除、查找 | ★★★★★ | 选择题 + 算法题 |
| 平均移动次数分析 | ★★★★★ | 选择题高频 |
| 顺序表与链表的对比 | ★★★★ | 选择题 |
| 顺序表算法设计 | ★★★★★ | 综合应用题 |
这篇重点讲顺序表,下一篇讲单链表。
一句话概括本篇目标:
能手写一个完整的顺序表,能算插入删除的平均移动次数,能做 408 真题。
二、线性表是什么
2.1 逻辑结构
线性表是 n 个数据元素的有限序列,记作:
text
(a1, a2, a3, ..., an)
特点:
- 有且仅有一个"第一个"元素
a1。 - 有且仅有一个"最后一个"元素
an。 - 除第一个外,每个元素有且仅有一个直接前驱。
- 除最后一个外,每个元素有且仅有一个直接后继。
- 元素之间是一对一的线性关系。
注意:线性表是逻辑结构 ,不关心怎么存。
怎么存,才是存储结构要解决的问题。
2.2 两种基本存储方式
| 存储方式 | 特点 | 代表 |
|---|---|---|
| 顺序存储 | 用一段连续内存依次存放 | 顺序表 |
| 链式存储 | 用指针把结点串起来 | 链表 |
本篇讲顺序存储。
三、顺序表的定义
3.1 结构
顺序表用一段地址连续的存储单元依次存放线性表元素。
假设每个元素占 sizeof(ElemType) 个字节,第一个元素地址为 LOC(a1),则第 i 个元素地址:
text
LOC(ai) = LOC(a1) + (i - 1) * sizeof(ElemType)
这就是 408 常考的随机访问公式。
3.2 图解
text
索引: 0 1 2 3 4 5
+-----+-----+-----+-----+-----+-----+
data: | a1 | a2 | a3 | a4 | a5 | |
+-----+-----+-----+-----+-----+-----+
地址: 1000 1004 1008 1012 1016 1020
假设 sizeof(ElemType) = 4,起始地址 1000。
a1地址:1000a3地址:1000 + (3-1)*4 = 1008a5地址:1000 + (5-1)*4 = 1016
3.3 特点
优点:
- 随机访问 :
O(1)时间按下标取元素。 - 存储密度高:只存数据,不存指针。
- 缓存友好:连续内存,CPU 缓存命中率高。
缺点:
- 插入删除慢 :平均要移动一半元素,
O(n)。 - 容量固定:静态分配时长度固定,扩容麻烦。
- 需要连续空间:内存碎片多时可能分配失败。
四、顺序表的基本操作
4.1 静态分配与动态分配
静态分配:
cpp
#define MAXSIZE 100
typedef struct {
ElemType data[MAXSIZE];
int length;
} SqList;
动态分配:
cpp
typedef struct {
ElemType *data;
int length;
int capacity;
} SeqList;
408 教材常用静态分配,但动态分配更接近工程。
本篇手写用动态分配,更灵活,也更方便理解扩容。
4.2 初始化
cpp
void InitList(SeqList &L) {
L.data = new ElemType[INIT_CAPACITY];
L.length = 0;
L.capacity = INIT_CAPACITY;
}
4.3 插入操作
在第 i 个位置插入元素 e,i 从 1 开始。
步骤:
- 判断
i是否合法:1 <= i <= length + 1。 - 判断表是否已满,满则扩容。
- 把第
i到第length个元素后移一位。 - 在位置
i放入e。 length++。
图解:在位置 2 插入 x
text
插入前:
索引: 0 1 2 3 4
+-----+-----+-----+-----+-----+
data: | a1 | a2 | a3 | a4 | |
+-----+-----+-----+-----+-----+
length = 4
从后往前移动:
a4 -> 位置4
a3 -> 位置3
a2 -> 位置2
插入后:
索引: 0 1 2 3 4
+-----+-----+-----+-----+-----+
data: | a1 | x | a2 | a3 | a4 |
+-----+-----+-----+-----+-----+
length = 5
代码:
cpp
bool ListInsert(SeqList &L, int i, ElemType e) {
if (i < 1 || i > L.length + 1) {
return false;
}
if (L.length == L.capacity) {
if (!Resize(L, L.capacity * 2)) {
return false;
}
}
for (int j = L.length; j >= i; j--) {
L.data[j] = L.data[j - 1];
}
L.data[i - 1] = e;
L.length++;
return true;
}
关键:从后往前移动,否则会覆盖。
4.4 删除操作
删除第 i 个元素,并用 e 返回被删除的值。
步骤:
- 判断
i是否合法:1 <= i <= length。 - 保存
data[i-1]到e。 - 把第
i+1到第length个元素前移一位。 length--。
图解:删除位置 2
text
删除前:
索引: 0 1 2 3 4
+-----+-----+-----+-----+-----+
data: | a1 | a2 | a3 | a4 | a5 |
+-----+-----+-----+-----+-----+
length = 5
从前往后移动:
a3 -> 位置1
a4 -> 位置2
a5 -> 位置3
删除后:
索引: 0 1 2 3 4
+-----+-----+-----+-----+-----+
data: | a1 | a3 | a4 | a5 | |
+-----+-----+-----+-----+-----+
length = 4
代码:
cpp
bool ListDelete(SeqList &L, int i, ElemType &e) {
if (i < 1 || i > L.length) {
return false;
}
e = L.data[i - 1];
for (int j = i; j < L.length; j++) {
L.data[j - 1] = L.data[j];
}
L.length--;
return true;
}
关键:从前往后移动。
4.5 按位查找
cpp
bool GetElem(const SeqList &L, int i, ElemType &e) {
if (i < 1 || i > L.length) {
return false;
}
e = L.data[i - 1];
return true;
}
时间复杂度:O(1)。
4.6 按值查找
cpp
int LocateElem(const SeqList &L, ElemType e) {
for (int i = 0; i < L.length; i++) {
if (L.data[i] == e) {
return i + 1;
}
}
return 0;
}
时间复杂度:O(n)。
4.7 扩容
cpp
bool Resize(SeqList &L, int newCapacity) {
if (newCapacity <= L.capacity) {
return true;
}
ElemType *newData = new ElemType[newCapacity];
for (int i = 0; i < L.length; i++) {
newData[i] = L.data[i];
}
delete[] L.data;
L.data = newData;
L.capacity = newCapacity;
return true;
}
4.8 销毁
cpp
void DestroyList(SeqList &L) {
delete[] L.data;
L.data = nullptr;
L.length = 0;
L.capacity = 0;
}
五、平均移动次数分析(408 高频)
这是 408 选择题最爱考的点,必须掌握。
5.1 插入的平均移动次数
设顺序表长度为 n,共有 n+1 个可插入位置。
在第 i 个位置插入,需要移动 n - i + 1 个元素。
假设等概率插入,即每个位置概率 1/(n+1):
text
ASL_insert = Σ (n - i + 1) * 1/(n+1) (i = 1 到 n+1)
= (1/(n+1)) * [n + (n-1) + ... + 1 + 0]
= (1/(n+1)) * n(n+1)/2
= n/2
结论:
顺序表插入操作平均移动 n/2 个元素,时间复杂度 O(n)。
5.2 删除的平均移动次数
设顺序表长度为 n,删除第 i 个元素,需要移动 n - i 个元素。
假设等概率删除,即每个位置概率 1/n:
text
ASL_delete = Σ (n - i) * 1/n (i = 1 到 n)
= (1/n) * [(n-1) + (n-2) + ... + 1 + 0]
= (1/n) * n(n-1)/2
= (n-1)/2
结论:
顺序表删除操作平均移动 (n-1)/2 个元素,时间复杂度 O(n)。
5.3 对比表
| 操作 | 最好 | 最坏 | 平均 | 时间复杂度 |
|---|---|---|---|---|
| 按位查找 | 1 次 | 1 次 | 1 次 | O(1) |
| 按值查找 | 1 次 | n 次 | (n+1)/2 次 | O(n) |
| 插入 | 0 次 | n 次 | n/2 次 | O(n) |
| 删除 | 0 次 | n-1 次 | (n-1)/2 次 | O(n) |
记忆口诀:
插入平均 n/2,删除平均 (n-1)/2。
六、完整 C++ 手写实现
下面给出一个完整可运行的顺序表实现,包含初始化、插入、删除、查找、扩容、打印、销毁。
cpp
#include <iostream>
using namespace std;
#define INIT_CAPACITY 4
typedef int ElemType;
typedef struct {
ElemType *data;
int length;
int capacity;
} SeqList;
// 初始化
void InitList(SeqList &L) {
L.data = new ElemType[INIT_CAPACITY];
L.length = 0;
L.capacity = INIT_CAPACITY;
}
// 扩容
bool Resize(SeqList &L, int newCapacity) {
if (newCapacity <= L.capacity) {
return true;
}
ElemType *newData = new ElemType[newCapacity];
for (int i = 0; i < L.length; i++) {
newData[i] = L.data[i];
}
delete[] L.data;
L.data = newData;
L.capacity = newCapacity;
return true;
}
// 插入:在第 i 个位置插入 e,i 从 1 开始
bool ListInsert(SeqList &L, int i, ElemType e) {
if (i < 1 || i > L.length + 1) {
return false;
}
if (L.length == L.capacity) {
if (!Resize(L, L.capacity * 2)) {
return false;
}
}
for (int j = L.length; j >= i; j--) {
L.data[j] = L.data[j - 1];
}
L.data[i - 1] = e;
L.length++;
return true;
}
// 删除:删除第 i 个元素,用 e 返回
bool ListDelete(SeqList &L, int i, ElemType &e) {
if (i < 1 || i > L.length) {
return false;
}
e = L.data[i - 1];
for (int j = i; j < L.length; j++) {
L.data[j - 1] = L.data[j];
}
L.length--;
return true;
}
// 按位查找
bool GetElem(const SeqList &L, int i, ElemType &e) {
if (i < 1 || i > L.length) {
return false;
}
e = L.data[i - 1];
return true;
}
// 按值查找,返回位置,0 表示未找到
int LocateElem(const SeqList &L, ElemType e) {
for (int i = 0; i < L.length; i++) {
if (L.data[i] == e) {
return i + 1;
}
}
return 0;
}
// 打印
void PrintList(const SeqList &L) {
cout << "SeqList(length=" << L.length
<< ", capacity=" << L.capacity << "): ";
for (int i = 0; i < L.length; i++) {
cout << L.data[i] << " ";
}
cout << endl;
}
// 销毁
void DestroyList(SeqList &L) {
delete[] L.data;
L.data = nullptr;
L.length = 0;
L.capacity = 0;
}
// 测试
int main() {
SeqList L;
InitList(L);
for (int i = 1; i <= 10; i++) {
ListInsert(L, i, i * 10);
}
PrintList(L);
ListInsert(L, 3, 999);
PrintList(L);
ElemType e;
ListDelete(L, 5, e);
cout << "deleted: " << e << endl;
PrintList(L);
GetElem(L, 2, e);
cout << "get elem 2: " << e << endl;
cout << "locate 999: " << LocateElem(L, 999) << endl;
DestroyList(L);
return 0;
}
运行结果:
text
SeqList(length=10, capacity=16): 10 20 30 40 50 60 70 80 90 100
SeqList(length=11, capacity=16): 10 20 999 30 40 50 60 70 80 90 100
deleted: 40
SeqList(length=10, capacity=16): 10 20 999 30 50 60 70 80 90 100
get elem 2: 20
locate 999: 3
七、408 真题与考法
7.1 选择题:地址计算
题目:
设顺序表中有 n 个元素,每个元素占 k 个存储单元,第一个元素地址为 LOC(a1),则第 i 个元素的地址是( )。
A. LOC(a1) + i * k
B. LOC(a1) + (i - 1) * k
C. LOC(a1) + (i + 1) * k
D. LOC(a1) + i
答案:B
7.2 选择题:平均移动次数
题目:
在长度为 n 的顺序表中,插入一个元素平均需要移动多少个元素?( )
A. n
B. n/2
C. (n-1)/2
D. (n+1)/2
答案:B
题目:
在长度为 n 的顺序表中,删除一个元素平均需要移动多少个元素?( )
A. n
B. n/2
C. (n-1)/2
D. (n+1)/2
答案:C
7.3 选择题:插入位置合法性
题目:
在长度为 n 的顺序表中,第 i 个位置插入元素,i 的合法范围是( )。
A. 1 <= i <= n
B. 1 <= i <= n + 1
C. 0 <= i <= n
D. 0 <= i <= n + 1
答案:B
7.4 综合题:顺序表算法设计
题目:
设计一个算法,从顺序表中删除所有值为 x 的元素,要求时间复杂度 O(n),空间复杂度 O(1)。
思路:
用 k 记录不等于 x 的元素个数,遍历一遍,把不等于 x 的元素前移。
代码:
cpp
void DeleteAllX(SeqList &L, ElemType x) {
int k = 0;
for (int i = 0; i < L.length; i++) {
if (L.data[i] != x) {
L.data[k] = L.data[i];
k++;
}
}
L.length = k;
}
复杂度:
- 时间复杂度:
O(n),只遍历一次。 - 空间复杂度:
O(1),只用了常数个辅助变量。
7.5 综合题:有序顺序表合并
题目:
将两个有序顺序表合并为一个新的有序顺序表。
思路:
双指针,从前往后比较,小的先放入结果。
代码:
cpp
bool MergeList(const SeqList &A, const SeqList &B, SeqList &C) {
if (A.length + B.length > C.capacity) {
return false;
}
int i = 0, j = 0, k = 0;
while (i < A.length && j < B.length) {
if (A.data[i] <= B.data[j]) {
C.data[k++] = A.data[i++];
} else {
C.data[k++] = B.data[j++];
}
}
while (i < A.length) C.data[k++] = A.data[i++];
while (j < B.length) C.data[k++] = B.data[j++];
C.length = k;
return true;
}
复杂度:
- 时间复杂度:
O(n + m)。 - 空间复杂度:
O(1)(不计结果表)。
八、易错点总结
-
下标从 0 还是 1 开始
408 题目中位置
i通常从 1 开始,代码里数组下标从 0 开始,注意转换。 -
插入位置范围是
1 <= i <= length + 1容易漏掉
length + 1,也就是表尾插入。 -
删除位置范围是
1 <= i <= length删除不能到
length + 1。 -
插入从后往前移动,删除从前往后移动
方向搞反会覆盖数据。
-
平均移动次数公式要记牢
插入
n/2,删除(n-1)/2。 -
顺序表长度和容量不是一回事
length是当前元素个数,capacity是最大容量。 -
扩容后要释放旧空间
工程代码里
delete[]不能忘,408 答题可简化。 -
算法题最后一定要写复杂度分析
这是 408 综合题的得分点。
九、总结与下一篇预告
本篇讲了:
- 线性表的逻辑结构与两种存储方式。
- 顺序表的定义、地址计算、优缺点。
- 插入、删除、查找、扩容的 C++ 手写实现。
- 插入平均移动
n/2,删除平均移动(n-1)/2。 - 408 真题考法与两道综合题。
- 常见易错点。
一句话总结:
顺序表的核心是"连续存储 + 随机访问",代价是插入删除要移动元素。
下一篇进入链式存储:
【408数据结构 04】单链表基础:头插、尾插、查找、插入、删除
我会用图解讲清头结点、头插法、尾插法,手写单链表的增删查改,分析时间复杂度,并配 408 真题。
专栏导航
- 上一篇:【408数据结构 02】时间复杂度与空间复杂度:408怎么考
- 下一篇:【408数据结构 04】单链表基础:头插、尾插、查找、插入、删除
- 专栏目录:《408数据结构:C++手写实现 + 图解 + 真题》
标签 :数据结构、C++、考研408、计算机考研、算法
分类:数据结构与算法
如果这篇对你有帮助,欢迎点赞、收藏、评论。你的支持是我持续更新的动力。