数据结构与算法——线性表
线性表
定义和基本操作
定义
线性表是具有相同
数据类型的n(n大于0)个数据元素的有限序列
,其中n为表长,当n=0时线性表是一个空表。若用L命名线性表,则其一般表示为
$$
L = (a1, a2, ..., ai, ai+1, ..., an)
$$
ai
时线性表中第i个元素线性表中的位序
。
a1
是表头元素;
an
是表尾元素;
除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅有一个直接后驱。
基本操作
一个数据结构的基本操作是指最核心、最基本的操作。其它较复杂的操作可通过调用其基本操作来实现。线性表的主要操作如下:
// 1. 初始化表。构造一个空的线性表
InitList(&L)
// 2. 求表长,返回线性表L的长度,即L中数据元素的个数
Length(L)
// 3. 按值查找操作。在表L中查找具有给定关键字值得元素
LocateElem(L, e)
// 4. 按位查找操作。获取表L中第i个位置的元素的值
Tips:
- 对数据的操作——创建销毁、增删改查
- c语言函数的定义需要指定参数类型
- 实际开发中,可根据实际需求定义其它的基本操作
- 函数名和参数的形式、命名都可以改变(Reference:严蔚敏版)
- 当需要对参数的修改结果“带回来”的时候传入引用
&
为什么要实现对数据结构的基本操作?
- 团队合作编程,你定义的数据结构要让别人可以很方便的使用。
- 将常用的操作或运算封装成函数,避免重复工作,降低出错风险。
总结

线性表的物理结构
线性表的顺序表示
线性表的定义
线性表的顺序存储又叫做顺序表。用顺序存储的方式实现线性表顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。
假定线性表的元素类型为ElemType,则线性表的顺序存储类型描述为:
#define MAXSIZE 50
typedef struct {
ElemType data[MAXSIZE];
int length;
}
此种表示方式是由缺陷的。如果当第51个元素到来时,它是没有地方可以插入的。也就是说,一旦空间占满,在加入新的数据就会产生溢出,进而导致程序崩溃。
所以引出动态分配。
动态分配时,存储空间是在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,就需要开辟一块更大的存储空间,用以替代原来的存储空间,从而达到扩充数据空间的目的,而不需要为线性表一次性的划分所有空间。
#define INITSIZE 50
typedef struct {
// 动态分配数组的指针
ElemType *data;
// 数组的最大容量
int maxsize;
// 数组的当前个数
int length;
}
C的初始动态分配语句为
L.data = (ElemType *)malloc(sizeof(ElemType) * INITSIZE)
C++的初始化分配语句为
L.data = new ElemType[INITSIZE]
顺序表的最主要特点是随机访问,即通过首地址和元素需要可在时间O(1)内找到指定的元素。
顺序表的存储密度高,每个节点只存储数据元素。
顺序表逻辑相邻的元素物理上也相邻,所以插入和删除操作需要移动大量的元素。
顺序表上基本操作的实现
插入操作
boll ListInsert(SqList &L, int i, ElemType e) {
if (i < 1 || i > L.length)
return false;
if (L.length > MAXSIZE)
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;
}
删除操作
bool ListDelete(SqList &L, int i, int &e) {
if (i < 1 || i > L.length)
return false;
e = data[i-1];
for(int j = i; j < L.length; j++) {
L.data[j-1] = L.data[j];
}
L.length--;
return true;
}
最好情况:删除表尾元素,时间复杂度为O(1)
最坏情况:删除表头元素,时间复杂度为O(n)
平均情况:i=1循环n-1次;i=2循环n-2次
故为 0 + 1 + 2 + ... + n-1 平均为(n-1) / 2

按值查找
int LocateElem(SqList L, ElemType e) {
for(int i=0;i<L.length;i++) {
if(L.data[i] == e)
return i+1;
}
return 0;
}
最好情况:目标元素在表头,循环一次 O(1)
最坏情况:目标元素在表尾,循环n次 O(n)
平均情况:(1 + 2 + ... + n)/n = (n+1)/n
按位查找
静态分配
ElemType GetElem(SqList L, int i) {
if (i < 1 || i > L.length) {
return null;
}
return L.data[i-1];
}
《数据结构》考研初试中,手写代码可以直接使用“==”,无论是结构体类型还是基本结构类型。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南