数据结构——顺序表的基本操作

前言

介绍

 🍃数据结构专区:数据结构

参考

该部分知识参考于《数据结构(C语言版 第2版)》24~28页

补充

此处的顺序表创建是课本中采用了定义方法为SqList Q来创建,并没有使用顺序表指针的方法,具体两个方法的差别我在此处补充一下

说明:顺序表指针L和顺序表Q都可以表示一个顺序表,但前者是通过指针L间接地表示顺序表,其定义方式为SqList* L,后者是直接地表示顺序表,其定义方式为SqList Q。

前者引用length域的方式为L->length,后者引用length的方式是Q.length。

前者开辟空间的方式是L = (SqList*)malloc(sizeof(SqList)),后者开辟空间使用new.

前者释放空间仅仅需要free(L),后者释放空间需要使用delete[]。

🌈每一个清晨,都是世界对你说的最温柔的早安:ૢ(≧▽≦)و✨


目录

前言

1、顺序表的基本概念

2、顺序表的基本操作

2.1 宏定义与结构体

2.2 初始化

2.3 销毁

2.4 判空

2.5 求表长

2.6 按序号查找(取值)

2.7 按值查找

2.8 插入

2.9 删除

2.10 输出顺序表

2.11 整体代码(含测试)

结语


1、顺序表的基本概念

顺序表(又称顺序存储结构的线性表)是一种线性数据结构,用于存储具有相同类型的数据元素。它使用一段地址连续的存储单元依次存储线性表的数据元素。以下是顺序表的基本概念:

  1. 存储结构
    • 顺序表使用一段连续的存储空间(如数组)来存储数据元素。
    • 每个数据元素在存储空间中都有一个唯一的索引(或位置),可以通过索引快速访问数据元素。
  2. 基本操作
    • 初始化:创建一个空的顺序表,并设置其初始容量。
    • 插入:在顺序表的指定位置插入一个数据元素。可能需要移动元素以腾出空间。
    • 删除:从顺序表的指定位置删除一个数据元素。可能需要移动元素以填补空缺。
    • 查找:根据数据元素的值或索引查找数据元素的位置。
    • 遍历:按顺序访问顺序表中的每个数据元素。
  3. 特点
    • 访问速度快:由于数据元素存储在连续的内存块中,可以通过索引直接访问任意位置的数据元素,时间复杂度为O(1)。
    • 插入和删除操作可能较慢:在顺序表中插入或删除数据元素时,可能需要移动其他数据元素,时间复杂度为O(n),其中n是顺序表的长度。
    • 存储密度高:顺序表中的数据元素在内存中是连续存储的,没有额外的指针开销,存储密度较高。

2、顺序表的基本操作

2.1 宏定义与结构体

#include<iostream>
#include <cstdlib>
using namespace std;//控制最大值
#define MAXSIZE 1000
//声明Status用于记录返回结果
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW -1typedef int ElemType;
typedef struct
{ElemType *elem;  //存储空间的基地址int length;
}SqList;

2.2 初始化 O(1)

//初始化
Status InitList(SqList& L)
{//构造一个空的顺序表L.elem = new ElemType[MAXSIZE];  //为顺序表分配一个大小为MAXSIZE的数组空间if (!L.elem)                     //如果分配失败就退出{exit(OVERFLOW);}L.length = 0;return OK;
}

2.3 销毁 O(1)

//销毁  
Status DestroyList(SqList& L)
{delete[] L.elem;  // 释放elem指向的数组  L.elem = NULL;    // 将指针设为NULL,避免野指针,这一步最好是置为nullptr  L.length = 0;     // 长度设为0,虽然这一步在销毁时不是必需的,但可以作为一种清理措施  return OK;
}

2.4 判空 O(1)

//判空
Status ListEmpty(SqList L)
{if (L.length = 0){return OK;}else{return ERROR;}
}

2.5 求表长 O(1)

//求线性表长度
int ListLength(SqList L)
{return(L.length);
}

2.6 按序号查找(取值) O(1)

//取值 ~ 按序号查找
//该算法根据指定的位置序号来获取顺序表中第i个位置的元素的值
//将第i个数据返还给e
Status GetElem(SqList L, int i, ElemType& e)
{//1.判断i值是否合理,不合理报错if (i < 1 || i > L.length){return ERROR;}e = L.elem[i - 1];   //第i-1位置存储第i个数据return OK;
}

2.7 按值查找 O(n)

//按值查找
//从第1个元素开始不断比较e,查找成功返回元素的序号i + 1
int LocateElem(SqList L, ElemType e)
{for (int i = 0; i < L.length; i++){if (L.elem[i] == e){return i + 1;}}return 0;  //查找失败返回0
}

2.8 插入 O(n)

//插入
//在表的第i个位置插入一个新的数据元素e
//第i个位置的下标是i - 1
Status ListInsert(SqList& L, int i, ElemType e)
{//判断位置是否合理//i的合法位置是 1 <= i <= L.length + 1 if (i < 1 || i > L.length + 1){return ERROR;}//判断空间是否充足if (L.length == MAXSIZE){return ERROR;}//将要插入位置后面的数据依次向后移动for (int j = L.length - 1; j >= i - 1; j--){L.elem[j + 1] = L.elem[j];}L.elem[i - 1] = e;++L.length;return OK;
}

2.9 删除 O(n)

//删除
//将第i个位置的元素删除,即将i+1至第n个元素依次向前移动一位
Status ListDelete(SqList& L, int i)
{//判断i位置是否合法if (i < 1 || i > L.length){return ERROR;}for (int j = i; j < L.length; j++){L.elem[j - 1] = L.elem[j];}--L.length;return OK;
}

2.10 输出顺序表 O(n)

//输出线性表
void DispList(SqList L)
{for (int i = 0; i < L.length; i++){cout << L.elem[i] << " ";}cout << endl;
}

2.11 整体代码(含测试)

#include<iostream>
#include <cstdlib>
using namespace std;//控制最大值
#define MAXSIZE 1000
//声明Status用于记录返回结果
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW -1typedef int ElemType;
typedef struct
{ElemType *elem;  //存储空间的基地址int length;
}SqList;//初始化
Status InitList(SqList& L)
{//构造一个空的顺序表L.elem = new ElemType[MAXSIZE];  //为顺序表分配一个大小为MAXSIZE的数组空间if (!L.elem)                     //如果分配失败就退出{exit(OVERFLOW);}L.length = 0;return OK;
}//销毁  
Status DestroyList(SqList& L)
{delete[] L.elem;  // 释放elem指向的数组  L.elem = NULL;    // 将指针设为NULL,避免野指针,这一步最好是置为nullptr  L.length = 0;     // 长度设为0,虽然这一步在销毁时不是必需的,但可以作为一种清理措施  return OK;
}//判空
Status ListEmpty(SqList L)
{if (L.length = 0){return OK;}else{return ERROR;}
}//求线性表长度
int ListLength(SqList L)
{return(L.length);
}//取值 ~ 按序号查找
//该算法根据指定的位置序号来获取顺序表中第i个位置的元素的值
//将第i个数据返还给e
Status GetElem(SqList L, int i, ElemType& e)
{//1.判断i值是否合理,不合理报错if (i < 1 || i > L.length){return ERROR;}e = L.elem[i - 1];   //第i-1位置存储第i个数据return OK;
}//按值查找
//从第1个元素开始不断比较e,查找成功返回元素的序号i + 1
int LocateElem(SqList L, ElemType e)
{for (int i = 0; i < L.length; i++){if (L.elem[i] == e){return i + 1;}}return 0;  //查找失败返回0
}//插入
//在表的第i个位置插入一个新的数据元素e
//第i个位置的下标是i - 1
Status ListInsert(SqList& L, int i, ElemType e)
{//判断位置是否合理//i的合法位置是 1 <= i <= L.length + 1 if (i < 1 || i > L.length + 1){return ERROR;}//判断空间是否充足if (L.length == MAXSIZE){return ERROR;}//将要插入位置后面的数据依次向后移动for (int j = L.length - 1; j >= i - 1; j--){L.elem[j + 1] = L.elem[j];}L.elem[i - 1] = e;++L.length;return OK;
}//删除
//将第i个位置的元素删除,即将i+1至第n个元素依次向前移动一位
Status ListDelete(SqList& L, int i)
{//判断i位置是否合法if (i < 1 || i > L.length){return ERROR;}for (int j = i; j <= L.length; j++){L.elem[j - 1] = L.elem[j];}--L.length;return OK;
}//输出线性表
void DispList(SqList L)
{for (int i = 0; i < L.length; i++){cout << L.elem[i] << " ";}cout << endl;
}int main() {SqList L;ElemType e;int position;cout << "开始测试顺序表操作函数:" << endl;// 测试初始化函数cout << "\n1. 测试初始化函数 InitList" << endl;if (InitList(L) == OK) {cout << "顺序表初始化成功" << endl;}else {cout << "顺序表初始化失败" << endl;return 1;}// 测试插入函数cout << "\n2. 测试插入函数 ListInsert" << endl;for (int i = 1; i <= 5; i++) {if (ListInsert(L, i, i * 10) == OK) {cout << "成功在位置 " << i << " 插入元素 " << i * 10 << endl;}else {cout << "在位置 " << i << " 插入元素失败" << endl;}}// 测试输出函数cout << "\n3. 测试输出函数 DispList" << endl;cout << "当前顺序表内容:";DispList(L);// 测试取值函数cout << "\n4. 测试取值函数 GetElem" << endl;if (GetElem(L, 3, e) == OK) {cout << "第3个元素的值为:" << e << endl;}else {cout << "获取第3个元素失败" << endl;}// 测试查找函数cout << "\n5. 测试查找函数 LocateElem" << endl;e = 30;position = LocateElem(L, e);if (position) {cout << "元素 " << e << " 在顺序表中的位置是:" << position << endl;}else {cout << "元素 " << e << " 不在顺序表中" << endl;}// 测试删除函数cout << "\n6. 测试删除函数 ListDelete" << endl;if (ListDelete(L, 2) == OK) {cout << "成功删除第2个元素" << endl;cout << "删除后的顺序表内容:";DispList(L);}else {cout << "删除第2个元素失败" << endl;}// 测试求长度函数cout << "\n7. 测试求长度函数 ListLength" << endl;cout << "当前顺序表的长度为:" << ListLength(L) << endl;// 测试判空函数cout << "\n8. 测试判空函数 ListEmpty" << endl;if (ListEmpty(L) == OK) {cout << "顺序表为空" << endl;}else {cout << "顺序表不为空" << endl;}// 测试销毁函数cout << "\n9. 测试销毁函数 DestroyList" << endl;if (DestroyList(L) == OK) {cout << "顺序表销毁成功" << endl;}else {cout << "顺序表销毁失败" << endl;}// 验证销毁后的状态cout << "\n10. 验证销毁后的状态" << endl;cout << "销毁后顺序表的长度:" << L.length << endl;cout << "销毁后顺序表的指针:" << (L.elem == NULL ? "NULL" : "非NULL") << endl;cout << "\n所有测试完成" << endl;return 0;
}

结语

顺序表的基本操作是后续学习各类型数据结构的基础,希望大家可以认真来研读每一处代码和每一处逻辑,也希望大家都有所进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/454804.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCL中环开工率下滑,员工集体要求解约赔偿

“ 尽管中环的市占率有所提高&#xff0c;但是高开工率也带来了巨量硅片库存&#xff0c;严重拖累了公司业绩。 ” 转载&#xff1a;科技新知 原创 作者丨依蔓 编辑丨蕨影 因大幅下调开工率&#xff0c;光伏硅片龙头TCL中环疑似遭遇员工“离职潮”&#xff1f; 近日&…

[云] 创建 Docker 镜像,将其推送到 Amazon Elastic Container Registry (ECR),并对已部署的应用程序进行负载测试

在此作业中&#xff0c;您将学习如何使用 AWS Lambda 和 API Gateway 将机器学习模型部署为无服务器应用程序。您将创建 Docker 镜像&#xff0c;将其推送到 Amazon Elastic Container Registry (ECR)&#xff0c;并对已部署的应用程序进行负载测试。此外&#xff0c;您还将分析…

【KEIL那些事 4】CMSIS缺失!!!!导致不能编译!!!!软件自带芯片下载缓慢!!!!!!快速下载芯片包!!!!!

安装了keli发现emmm&#xff0c;CMSIS缺失&#xff01;&#xff01;&#xff01;&#xff01;不能编译&#xff0c;&#xff0c;&#xff0c;自带下载芯片缓慢&#xff0c;&#xff0c;&#xff0c;官网下载emmm&#xff0c;竟然不带动的&#xff01;&#xff01;&#xff01;&…

数据库集群

主从复制 作用&#xff1a; 1.做数据的热备&#xff0c;作为后备数据库&#xff0c;主数据库服务器故障后&#xff0c;可切换到从数据库继续工作&#xff0c;避免数据丢失。 2.架构的扩展。业务量越来越大&#xff0c;I/O访问频率过高&#xff0c;单机无法满足&#xff0c;此…

基于node.js宜家宜业物业管理系统【附源码】

基于node.js宜家宜业物业管理系统 效果如下&#xff1a; 系统首页界面 业主登录界面 停车位页面 小区公告页面 管理员登录界面 管理员功能界面 物业管理员管理界面 缴费信息管理界面 物业管理员功能界面 研究背景 近年来互联网技术飞速发展&#xff0c;给人们的生活带来了极…

《云计算网络技术与应用》实训6-1:配置KVM虚拟机使用NAT网络

任务1、计算节点基础环境准备 1. 使用VMware安装CentOS 7虚拟机&#xff0c;安装时记得开启CPU虚拟化&#xff0c;命名为“KVMC6”。 2. &#xff08;网卡配置和之前的一样&#xff0c;都用100网段&#xff09;网关设置为192.168.100.1&#xff0c;地址段为192.168.100.10-25…

excel将文本型数字转变为数值型数字

问题导入&#xff1a;复制数字到excel表格中&#xff0c;但是表格中数字显示为文本&#xff0c;且无法通过常规方法转变为可进行四则运算的数字。例如&#xff1a;在i3单元格中输入常规的转换方法仍然报错。在j3单元格中输入ISTEXT(H3)显示h3单元格确实为文本。 解决办法&#…

Chrome DevTools 三: Performance 性能面板扩展—— 性能优化

Performance 性能 &#xff08;一&#xff09;性能指标 首次内容绘制 (First Contentful Paint&#xff0c;FCP)&#xff1a; 任意内容在页面上完成渲染的时间 最大内容绘制 (Largest Contentful Paint&#xff0c;LCP)&#xff1a; 最大内容在页面上完成渲染的时间 第一字节…

【经管】比特币与以太坊历史价格数据集(2014.1-2024.5)

一、数据介绍 数据名称&#xff1a;比特币与以太坊历史价格数据集 频率&#xff1a;逐日 时间范围&#xff1a; BTC&#xff1a;2014/9/18-2024/5/1 ETH&#xff1a;2017/11/10-2024/5/1 数据格式&#xff1a;面板数据 二、指标说明 共计7个指标&#xff1a;Date、Open…

天润融通大模型文本机器人,让客服迈入“无人化”的第一步

明明很着急&#xff0c;但客服机器人总是答非所问&#xff1f; 相信很多人都经历过这样的尴尬时刻&#xff0c;问题的关键&#xff0c;是传统文本机器人还在通过关键词和基础语义分析回答问题。 △传统机器人处理问题流程示意 要知道在客户咨询与服务过程中&#xff0c;用户的…

架构师备考-背诵精华(系统架构评估)

系统架构评估是在对架构分析、评估的基础上&#xff0c;对架构策略的选取进行决策。它利用数学或逻辑分析技术&#xff0c;针对系统的一致性、正确性、质量属性、规划结果等不同方面&#xff0c;提供描述性、预测性和指令性的分析结果。 重要概念 敏感点&#xff1a;敏感点是…

Linux系统基础-进程间通信(4)_模拟实现进程池

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux系统基础-进程间通信(4)_模拟实现进程池 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f4…

Claude 3.5 Sonnent(new)发布,编程能力反超o1

目录 1、近期OpenAI的重磅更新2、Claude 3.5深夜迎来重磅升级3、为什么这么大的更新却连模型版本号都不改一下&#xff1f;4、升级后的Claude 3.5 Sonnet&#xff1a;不只是“更快更强”5、Claude 3.5 Sonnet&#xff08;new&#xff09;适配更多场景&#xff08;1&#xff09;…

[实时计算flink]作业开发上线流程及规范

随着数据量的爆炸性增长和业务需求的日益复杂化&#xff0c;企业对实时数据处理能力的需求愈发迫切。Flink作为一种强大的流处理框架已经成为实时计算标准&#xff0c;其规范化的开发和运维流程对于企业提升数据处理效率、确保系统稳定性至关重要&#xff0c;旨在提升研发效率&…

力扣困难题汇总(16道)

题4&#xff08;困难&#xff09;&#xff1a; 思路&#xff1a; 找两数组中位数&#xff0c;这个看起来简单&#xff0c;顺手反应就是数第(mn)/2个&#xff0c;这个难在要求时间复杂度为log(mn)&#xff0c;所以不能这样搞&#xff0c;我的思路是&#xff1a;每次切割长度为较…

pdf怎么合并在一起?pdf合并的简单方法

pdf怎么合并在一起&#xff1f;在现代办公和学习环境中&#xff0c;PDF&#xff08;便携式文档格式&#xff09;文件因其兼容性强、易于分享和保持格式稳定而广泛应用。然而&#xff0c;在日常工作中&#xff0c;我们经常会遇到需要处理多个PDF文件的情况&#xff0c;例如&…

【uniapp】实现触底加载数据

前言&#xff1a;实现界面触底数据加载。后端接口得支持翻页传参&#xff08;本案例使用django&#xff09; 1、后端接口 1.1 封装翻页公共方法standardPagination.py # -*- coding: utf-8 -*- # Time : 2024/10/15 13:15 # Author : super # File : standardPaginat…

[Hbase]一 HBase基础

1. HBase简介 1.1 HBase定义 HBase数据模型的关键在于 稀疏、分布式、多维、排序 的映射。其中映射 map指代非关系型数据库的 key-Value结构。 1.2 HBase数据模型 1)Name Space 命名空间,类似于关系型数据库的database 概念,每个命名空间下有多个表。HBase 两个自…

MFC工控项目实例二十五多媒体定时计时器

承接专栏《MFC工控项目实例二十四模拟量校正值输入》 用多媒体定时器实现0.1秒计时器 1、在SEAL_PRESSUREDlg.h文件中添加代码 #include<MMSystem.h> #pragma comment(lib,"winmm.lib")class CSEAL_PRESSUREDlg : public CDialog { public:CSEAL_PRESSUREDlg(…

Redis实现全局ID生成器

全局ID生成器 为什么要用全局ID生成器 1.当我们使用数据库自增来实现id的生成时,规律过于明显,会给用户暴露很多信息 2.当我们订单量过大时无法用数据库的一张表来存放订单,如果两张表的id都是自增的话,id就会出现重复 什么是全局ID生成器 全局ID生成器,是一种在分布式系统…