一、学习顺序表的核心目的
学习数据结构的核心诉求是解决程序运行的效率问题与算法实现的基础支撑问题,而顺序表作为线性表的基础实现形式,是理解这两个核心的关键起点:
- 效率优化:原生数组在处理大规模数据时,插入 / 删除元素需移动大量数据、无法灵活统计有效数据个数,顺序表通过封装数组并规范操作逻辑,可针对性优化这些场景的时间 / 空间效率;
- 算法基础:栈、队列等常用数据结构的底层可基于顺序表实现,掌握顺序表是后续学习复杂算法(如排序、查找)的必要前提。
二、顺序表的核心概念
1. 定义
顺序表本质是对原生数组的封装,通过结构体整合 "存储数据的数组" 和 "记录有效数据个数的变量",并封装增、删、查、改等操作,让数组的使用更规范、高效。
2. 分类
根据存储空间的灵活性,顺序表分为两类:
| 类型 | 特点 |
|---|---|
| 静态顺序表 | 数组长度通过宏定义(如#define N 10)固定,存储空间编译时确定,无法动态扩容 |
| 动态顺序表 | 用数组指针指向存储空间,新增 "容量变量" 记录空间大小,可按需扩容,空间利用率更高 |
三、顺序表的核心实现(C 语言)
1. 基础结构定义
(1)静态顺序表
#include <stdio.h>
#include <stdlib.h>
// 宏定义数组长度(静态顺序表固定长度)
#define MAX_SIZE 10
// 定义静态顺序表结构体
typedef struct {
int data[MAX_SIZE]; // 存储数据的数组
int size; // 有效数据个数
} StaticSeqList;
(2)动态顺序表
// 定义动态顺序表结构体
typedef struct {
int* data; // 指向存储数据的数组
int size; // 有效数据个数
int capacity;// 数组总容量(存储空间大小)
} DynamicSeqList;
2. 核心操作实现
(1)初始化
初始化的核心是将 "有效数据个数置 0",动态顺序表需额外初始化存储空间:
// 静态顺序表初始化
void InitStaticSeqList(StaticSeqList* list) {
if (list == NULL) return;
list->size = 0; // 有效数据个数初始化为0
}
// 动态顺序表初始化(初始容量设为8)
int InitDynamicSeqList(DynamicSeqList* list) {
if (list == NULL) return -1;
list->capacity = 8;
list->data = (int*)malloc(sizeof(int) * list->capacity);
if (list->data == NULL) return -1; // 内存分配失败
list->size = 0;
return 0;
}
(2)增加元素(尾部插入 + 指定位置插入)
增加元素的核心逻辑:先检查存储空间是否已满→验证位置合法性→插入元素→更新有效数据个数。
// 静态顺序表尾部插入
int StaticPushBack(StaticSeqList* list, int value) {
// 检查顺序表是否已满
if (list == NULL || list->size >= MAX_SIZE) return -1;
list->data[list->size] = value; // 插入到尾部
list->size++; // 有效个数+1
return 0;
}
// 静态顺序表指定位置插入(pos从0开始)
int StaticInsert(StaticSeqList* list, int pos, int value) {
// 检查合法性:指针非空、位置合法、顺序表未满
if (list == NULL || pos < 0 || pos > list->size || list->size >= MAX_SIZE) return -1;
// 从后往前移动元素,为插入位置腾出空间
for (int i = list->size; i > pos; i--) {
list->data[i] = list->data[i-1];
}
list->data[pos] = value; // 插入元素
list->size++; // 有效个数+1
return 0;
}
(3)删除元素
删除的核心逻辑:验证位置合法性→移动元素覆盖待删除值→更新有效数据个数。
// 静态顺序表删除指定位置元素
int StaticDelete(StaticSeqList* list, int pos) {
if (list == NULL || pos < 0 || pos >= list->size) return -1;
// 从删除位置往后,元素依次前移
for (int i = pos; i < list->size - 1; i++) {
list->data[i] = list->data[i+1];
}
list->size--; // 有效个数-1
return 0;
}
(4)查找与修改
// 查找元素:返回第一个匹配值的下标,未找到返回-1
int StaticFind(StaticSeqList* list, int value) {
if (list == NULL) return -1;
for (int i = 0; i < list->size; i++) {
if (list->data[i] == value) {
return i;
}
}
return -1;
}
// 修改指定位置元素值
int StaticModify(StaticSeqList* list, int pos, int newValue) {
if (list == NULL || pos < 0 || pos >= list->size) return -1;
list->data[pos] = newValue;
return 0;
}
(5)测试示例
int main() {
// 静态顺序表测试
StaticSeqList list;
InitStaticSeqList(&list); // 初始化
// 尾部插入元素
StaticPushBack(&list, 10);
StaticPushBack(&list, 20);
// 指定位置插入(下标1插入15)
StaticInsert(&list, 1, 15);
// 查找元素20的位置
int findPos = StaticFind(&list, 20);
printf("元素20的下标:%d\n", findPos); // 输出:2
// 修改下标1的元素为18
StaticModify(&list, 1, 18);
// 删除下标2的元素
StaticDelete(&list, 2);
// 遍历输出所有元素
printf("顺序表元素:");
for (int i = 0; i < list->size; i++) {
printf("%d ", list.data[i]); // 输出:10 18
}
return 0;
}