【C语言数据结构】第2章:线性表(2)--线性表的顺序存储结构

每日一句

乾坤未定,你我皆是黑马,

乾坤已定,我定扭转乾坤。


1.顺序存储的定义与本质

顺序表是线性表的物理实现方式 ,其核心是用连续的存储单元依次存储线性表的元素 ,使得逻辑上相邻的元素在物理存储上也相邻。这种存储方式的本质是通过 "物理位置的连续性" 保证逻辑关系的线性性

(1)核心特征

随机访问

通过元素的 "位置" 可直接计算其存储地址(如第 i 个元素的地址 = 首元素地址 + (i-1)× 单个元素占用的存储单元数);

存储密度高

无需额外存储元素间的关系(如指针),空间利用率高;

插入 / 删除效率低

插入或删除元素时,需移动大量后续元素以保持存储的连续性。

(2)与逻辑结构的关联

顺序表的物理结构完全匹配线性表的逻辑结构(一对一的序偶关系),是线性表最直观的实现方式。

2.顺序表的存储表示

顺序表的存储可分为静态存储动态存储两种方式:

静态顺序表

定义

使用固定大小的数组存储元素,表的最大长度在编译时确定。

代码示例(C 语言)

cpp 复制代码
#define MaxSize 100  // 预定义表的最大长度
typedef int DataType;  // 假设元素类型为int
typedef struct {
    DataType data[MaxSize];  // 存储元素的数组
    int length;  // 当前表的长度(元素个数)
} SeqList;

特点

实现简单,但最大长度固定,易出现 "空间浪费"(表元素少但数组大)或 "溢出"(表元素超过数组大小)。

动态顺序表

定义

使用指针和动态内存分配,表的最大长度在运行时确定,可根据需要扩展。

代码示例(C 语言)

cpp 复制代码
#define InitSize 10  // 初始分配的空间大小
typedef int DataType;
typedef struct {
    DataType *data;  // 指向动态分配数组的指针
    int length;  // 当前表的长度
    int maxSize;  // 当前分配的最大空间
} DynSeqList;

特点

灵活度高,可动态扩展空间,但需手动管理内存 (如扩容、释放),实现相对复杂。

3.顺序表的地址计算

顺序表支持随机访问的核心是 "地址可通过公式直接计算"。假设:

首元素的存储地址为 Loc(a1​);

每个元素占用 c 个存储单元(如int占 4 字节,double占 8 字节);则第 i 个元素的地址为:Loc(ai​)=Loc(a1​)+(i−1)×c

示例 :若首元素地址为 1000(十六进制),元素类型为int(c=4),则第 5 个元素的地址为:1000+(5−1)×4=1016

这种地址计算方式使得顺序表的 "按位置查找" 操作时间复杂度为 O(1),是其核心优势。

4.顺序表的基本操作实现

顺序表的核心操作(初始化、查找、插入、删除)需结合 "连续存储" 的特点设计:

初始化操作

1.静态顺序表:只需将length置 0。

cpp 复制代码
void InitSeqList(SeqList *L) {
    L->length = 0;  // 表初始化为空
}

2.动态顺序表:需分配初始内存,并设置lengthmaxSize

cpp 复制代码
void InitDynSeqList(DynSeqList *L) {
    L->data = (DataType *)malloc(InitSize * sizeof(DataType));
    if (L->data == NULL) exit(1);  // 内存分配失败则终止
    L->length = 0;
    L->maxSize = InitSize;
}

查找操作

1.按位置查找(GetElem):直接通过地址公式访问元素,时间复杂度 O(1)。

cpp 复制代码
DataType GetElem(SeqList L, int i) {
    if (i < 1 || i > L.length) {
        printf("位置越界");
        exit(1);
    }
    return L.data[i-1];  // 数组下标从0开始,位置i对应下标i-1
}

2.按值查找(LocateElem):遍历数组,逐个比较值,时间复杂度 O(n)。

cpp 复制代码
int LocateElem(SeqList L, DataType e) {
    for (int i = 0; i < L.length; i++) {
        if (L.data[i] == e) {
            return i + 1;  // 返回位置(从1开始)
        }
    }
    return 0;  // 查找失败
}

插入操作

步骤:①判断位置是否越界;②将第 i 至第 n 个元素后移一位;③插入新元素;④表长度加 1。

代码示例(静态顺序表):

cpp 复制代码
void InsertElem(SeqList *L, int i, DataType e) {
    if (i < 1 || i > L->length + 1) {  // 插入位置范围是1~length+1
        printf("位置越界");
        exit(1);
    }
    if (L->length >= MaxSize) {  // 表已满则无法插入
        printf("表已满");
        exit(1);
    }
    // 元素后移:从最后一个元素开始,直到第i个元素
    for (int j = L->length; j >= i; j--) {
        L->data[j] = L->data[j-1];
    }
    L->data[i-1] = e;  // 插入新元素
    L->length++;  // 表长度加1
}

时间复杂度:平均移动 n/2 个元素,最坏情况 O(n)(如在表头插入)。

删除操作

  • 步骤:①判断位置是否越界;②保存被删元素的值;③将第 i+1 至第 n 个元素前移一位;④表长度减 1。

  • 代码示例(静态顺序表):

    cpp 复制代码
    DataType DeleteElem(SeqList *L, int i) {
        if (i < 1 || i > L->length) {  // 删除位置范围是1~length
            printf("位置越界");
            exit(1);
        }
        DataType temp = L->data[i-1];  // 保存被删元素
        // 元素前移:从第i个元素开始,直到最后一个元素
        for (int j = i; j < L->length; j++) {
            L->data[j-1] = L->data[j];
        }
        L->length--;  // 表长度减1
        return temp;  // 返回被删元素
    }
  • 时间复杂度:平均移动 (n−1)/2 个元素,最坏情况 O(n)(如删除表头元素)。

5.顺序表的优缺点总结

优点

  • 支持随机访问,按位置查找效率高(O(1));
  • 存储密度高,无需额外空间存储元素间关系;
  • 实现简单,代码易读。

缺点

  • 插入 / 删除操作效率低(需移动大量元素,O(n));
  • 静态顺序表空间固定,易浪费或溢出;
  • 动态顺序表需手动管理内存,实现复杂且扩容有开销。

6.顺序表的适用场景

顺序表适用于**"查找频繁,插入删除少"**的场景:

  • 如 "学生信息管理系统"(频繁按学号查询,插入删除操作少);
  • 如 "考试成绩统计系统"(按考号查找成绩,偶尔添加 / 删除考生)。

若场景中插入删除操作频繁(如 "消息队列""撤销操作栈"),则更适合选择链表。

总结

顺序表是线性表的 "连续存储" 实现,其核心优势是随机访问效率高 ,核心劣势是插入删除效率低。理解顺序表的存储方式、地址计算和操作实现,是掌握 "数据结构与存储方式关联" 的关键。后续学习链表时,可通过对比二者的优缺点,更深入理解 "数据结构的选择需结合场景" 的原则。

相关推荐
代码村新手2 小时前
C语言-字符函数和字符串函数
c语言·开发语言
Yupureki4 小时前
从零开始的C++学习生活 3:类和对象(中)
c语言·c++·学习·visual studio
小许学java5 小时前
七大排序算法的基本原理
数据结构·算法·排序算法
凤年徐6 小时前
【C++】string类
c语言·开发语言·c++
小龙报6 小时前
《KelpBar海带Linux智慧屏项目》
linux·c语言·vscode·单片机·物联网·ubuntu·学习方法
_dindong7 小时前
动规:01背包
数据结构·笔记·学习·算法·leetcode·动态规划·力扣
-雷阵雨-7 小时前
数据结构——排序算法全解析(入门到精通)
java·开发语言·数据结构·排序算法·intellij-idea
XH华8 小时前
C语言深度解剖:第一章关键字(一)
c语言·开发语言
LGL6030A8 小时前
数据结构学习(1)——指针、结构体、链表(C语言)
数据结构·学习