顺序表笔记

一、学习顺序表的核心目的

学习数据结构的核心诉求是解决程序运行的效率问题与算法实现的基础支撑问题,而顺序表作为线性表的基础实现形式,是理解这两个核心的关键起点:

  1. 效率优化:原生数组在处理大规模数据时,插入 / 删除元素需移动大量数据、无法灵活统计有效数据个数,顺序表通过封装数组并规范操作逻辑,可针对性优化这些场景的时间 / 空间效率;
  2. 算法基础:栈、队列等常用数据结构的底层可基于顺序表实现,掌握顺序表是后续学习复杂算法(如排序、查找)的必要前提。

二、顺序表的核心概念

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;
}
相关推荐
宵时待雨2 小时前
数据结构(初阶)笔记归纳6:双向链表的实现
c语言·开发语言·数据结构·笔记·算法·链表
狐572 小时前
2026-01-20-LeetCode刷题笔记-3314-构造最小位运算数组I
笔记·算法·leetcode
0和1的舞者2 小时前
非力扣hot100-二叉树专题-刷题笔记(一)
笔记·后端·算法·leetcode·职场和发展·知识
FMRbpm2 小时前
树的练习7--------LCR 052.递增顺序搜索树
数据结构·c++·算法·leetcode·深度优先·新手入门
技术民工之路2 小时前
MATLAB线性方程组,运算符、inv()、pinv()全解析
线性代数·算法·matlab
一起努力啊~2 小时前
算法刷题--双指针法
算法
Coovally AI模型快速验证2 小时前
从“单例模仿”到“多面融合”,视觉上下文学习迈向“团队协作”式提示融合
人工智能·学习·算法·yolo·计算机视觉·人机交互
明洞日记2 小时前
【软考每日一练007】位图计算与内存管理深度全解
c++·算法·ai·操作系统·进程
敲敲了个代码2 小时前
前端指纹技术是如何实现的?(Canvas、Audio、硬件API 核心原理解密)
前端·javascript·学习·算法·面试·web