当前位置: 首页 > news >正文

数据结构之顺序表(动态)

目录

前言:

二、顺序表的定义与核心特性

2.1 定义

2.2 核心特性

三、顺序表的分类

3.1 静态顺序表

3.2 动态顺序表

四、顺序表的基本操作实现(C 语言)

4.1 结构体定义

4. 2初始化

4.3 扩容操作

4. 4插入元素

4.4.1尾部

4.4.2头部

4.4.3指定

4.5 删除元素

4.5.1尾部

4.5.2头部

4.5.3指定

4.6 查找元素

4.7遍历顺序表

4.8 销毁顺序表

五、顺序表的操作复杂度分析

5.1 时间复杂度

5.2空间复杂度

六、顺序表的优缺点

6.1 优点

6.2 缺点

七、应用场景

八、总结


前言:


在数据结构中,线性表是最基础且常用的结构之一,而顺序表作为线性表的重要实现方式,以其存储的连续性和访问的高效性在编程领域占据重要地位。顺序表通过数组的形式存储数据元素,元素之间的逻辑关系通过物理存储位置的连续性来体现,是理解线性表本质和数组应用的关键载体。本文将从原理、实现、操作特性及应用场景等方面,全面解析顺序表的核心知识。

二、顺序表的定义与核心特性

2.1 定义

 顺序表是将线性表中的元素按照一定顺序依次存储在一片连续的物理存储空间中的数据结构。简单来说,顺序表就是用数组实现的线性表,数组的下标对应元素的逻辑位置。

2.2 核心特性

- 存储连续性:元素在内存中占据连续的存储空间,相邻元素的物理地址相差一个元素的大小。
- 随机访问:可通过数组下标直接访问任意位置的元素,时间复杂度为 O(1)。
- 固定容量:静态顺序表的容量在初始化时确定,动态顺序表可动态扩容,但扩容会产生额外开销。
- 元素有序性:元素的逻辑顺序与物理存储顺序一致。

三、顺序表的分类

3.1 静态顺序表

- 特点:使用固定大小的数组存储元素,容量一旦确定无法修改。
- 适用场景:元素个数已知且固定的场景,避免动态扩容的开销。
- 缺陷:容量不足时无法添加新元素,容量过大则造成内存浪费。

typedef int  SLDataType;
#define N 100
typedef struct SeqList
{SLDataType a[100];//定长数组int size; // 有效数据个数
}SL;

3.2 动态顺序表

- 特点:使用动态分配的数组存储元素,容量可根据需求动态扩容(通常扩容为原容量的 2 倍或 1.5 倍)。
- 适用场景:元素个数不确定、需要灵活增减的场景。
- 优势:内存利用率更高,可灵活应对元素数量的变化。

typedef int  SLDataType;
// 动态顺序表 -- 按需申请
typedef struct SeqList
{SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量
}SL;

四、顺序表的基本操作实现(C 语言)


 以动态顺序表为例,实现初始化、插入、删除、查找、销毁等核心操作。

4.1 结构体定义

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int  SLDataType;
// 动态顺序表 -- 按需申请
typedef struct SeqList
{SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量
}SL;

4. 2初始化

void SLInit(SL* ps)
{assert(ps);ps->a = NULL;ps->capacity = ps->size = 0;
}

4.3 扩容操作
 

void SLCheckCapacity(SL* ps)
{assert(ps);// 扩容函数,容量翻倍//当元数个数等于空间时即为满if (ps->capacity == ps->size){int time = ps->capacity == 0 ? 4 : 2 * ps->capacity;//防止扩容失败找不到原先地址SLDataType* arr = (SLDataType*)realloc(ps->a,sizeof(SLDataType)*time);if (arr == NULL){perror("realloc arr");return;}ps->a = arr;ps->capacity = time;}
}

4. 4插入元素

4.4.1尾部

void SLPushBack(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size++] = x;
}

4.4.2头部

void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);	for (int i = ps->size; i > 0; i--){ps->a[i] = ps->a[i-1];}ps->a[0] = x;ps->size++;
}

4.4.3指定

//指定位置前插入
void SLInsert(SL* ps, int pos, SLDataType x)
{//pos为指定位置assert(ps);assert(pos < ps->size&& pos >= 0);SLCheckCapacity(ps);for (int i = ps->size; i >pos; i--){ps->a[i] = ps->a[i - 1];}ps->a[pos] = x;ps->size++;
}

4.5 删除元素

4.5.1尾部

void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);ps->size--;
}

4.5.2头部

void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i < ps->size - 1; i++){ps->a[i] = ps->a[i+1];}ps->size--;
}

4.5.3指定

//指定位置删
void SLErase(SL* ps, int pos)
{assert(ps);assert(ps->size);assert(pos < ps->size&& pos >= 0);for (int i = pos; i < ps->size-1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

4.6 查找元素

//返回下标,没有就返回-1
int SLFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){return i;}}return -1;
}

4.7遍历顺序表

void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}

4.8 销毁顺序表

void SLDestroy(SL* ps)
{assert(ps);if(ps->a){free(ps->a);ps->a = NULL;}ps->capacity = ps->size = 0;
}

五、顺序表的操作复杂度分析

5.1 时间复杂度

- 访问元素:O(1),直接通过下标访问。
- 插入/删除元素:O(n),需移动后续元素(最坏情况下移动 n 个元素)。
- 查找元素:O(n),需遍历数组(未排序)。
- 扩容操作:O(n),需拷贝原数组元素到新数组。

5.2空间复杂度

- 整体空间复杂度为 O(n),n 为顺序表的容量。

六、顺序表的优缺点

6.1 优点

- 随机访问效率高,适合频繁查询的场景。
- 存储密度高,无需额外空间存储元素间的逻辑关系。
- 实现简单,易于理解和操作。

6.2 缺点

- 插入/删除操作效率低,元素移动开销大。
- 动态扩容存在内存浪费和拷贝开销。
- 固定容量的静态顺序表灵活性差。

七、应用场景


 - 频繁查询、少量增删的场景,如成绩排名表、静态数据缓存。
- 需要随机访问元素的场景,如数组模拟栈、队列。
- 内存空间充足,追求访问效率优先的场景。

八、总结


 顺序表作为线性表的基础实现,其核心优势在于随机访问的高效性,而短板则是插入删除操作的低效性。在实际开发中,需根据业务场景选择合适的线性表实现:若频繁查询,顺序表是优选;若频繁增删,则链表更合适。理解顺序表的原理和操作特性,不仅能帮助我们高效解决问题,更能为后续学习栈、队列等复杂数据结构奠定坚实基础。

http://www.dtcms.com/a/597022.html

相关文章:

  • Prover9/Mace4 的形式化语言简介
  • CSDN文章如何转出为PDF文件保存
  • 多级缓存解决方案
  • C++ 二分查找(Binary Search):从原理到实战的全面解析
  • Synbo Protocol 受邀出席ETHShanghai 2025,以共识机制重构链上融资生态
  • 软考 系统架构设计师历年真题集萃(198)—— 2025年11月系统架构设计师真题1
  • 专业网站开发服务电商网站建设哪个好
  • 哈希表和unordered_map和unordered_set
  • HTTP报文格式
  • 厦门网页建站申请费用怎么找出网站的备案号
  • maven专题
  • 渭南市住房和城乡建设局官方网站定制网站和模板网站及仿站的区别
  • Data Agent业务场景方案分析
  • AWS ALB 和目标组异常事件监控实战
  • python中模拟浏览器操作之playwright使用说明以及打包浏览器驱动问题
  • pnpm环境下防止误使用npm的方法
  • 服务器证书与网站不符2020中国企业500强榜单
  • 医疗电子试验箱 生物电子实验箱 生物医学教学平台 嵌入式生物医学电子实验箱
  • 网易云音乐解析(无损音乐均可下载)
  • android StateFlow和sharedflow
  • 幽冥大陆(十八)手机摄像头注册到电脑源码——东方仙盟炼气期
  • 2025年渗透测试面试题总结-240(题目+回答)
  • 防滑齿构型与牙体组织损伤风险的相关性分析
  • C#7、如何处理异常
  • 网站建设培训公司番禺厂家关键词优化
  • Oracle19c单机部署(本地)
  • 【vscode】vscode上plantuml安装和使用
  • Prompt 提示词工程
  • html5做网站总结邢台 网站建设
  • 黑马JAVAWeb -Vue工程化 - Element Plus