数据结构实验3:顺序表的基本操作

news2024/12/23 6:12:00

目录

一、实验目的

二、实验原理

1. 连续存储空间

2. 元素访问

3. 固定大小

4. 容量管理

5. 动态顺序表

6. 顺序表的插入

7. 顺序表的删除

 8. 顺序表的应用

三、实验内容

问题描述

代码

截图

分析 


一、实验目的

1、 熟练掌握顺序表结构体的实现。

2、 熟练掌握顺序表的存储结构上实现基本操 作:查找、插入和删除算法。

二、实验原理

1. 连续存储空间

顺序表的元素在内存中是连续存储的,这意味着每个元素占据相邻的内存位置。这种特性使得顺序表可以通过数组等数据结构来实现。

2. 元素访问

由于元素在内存中是连续存储的,所以可以通过下标或者偏移量直接访问任意位置的元素。这使得顺序表具有O(1)的时间复杂度,即在常数时间内能够完成元素的访问操作。

3. 固定大小

顺序表的大小在创建时通常是固定的,即在存储空间分配后不会改变。这意味着在插入或删除元素时可能需要移动其他元素,导致相应的时间复杂度为O(n)。

4. 容量管理

顺序表有一个容量的概念,表示其最大可容纳的元素个数。当元素数量超过容量时,可能需要进行扩容操作,即重新分配更大的存储空间,并将原有元素复制到新的空间中。

5. 动态顺序表

为了解决固定大小的问题,可以采用动态顺序表,即在需要时动态地调整存储空间的大小。这通常通过扩容和缩小的方式来实现,以适应不同的需求。

#include <iostream>
using namespace std;

#define INITIAL_CAPACITY 10

typedef struct {
    int* elements;   // 存储线性表元素的数组
    int size;        // 当前存储的元素数量
    int capacity;    // 当前分配的存储空间容量
} DynamicArrayList;

// 初始化动态顺序表
void initDynamicArrayList(DynamicArrayList* list) {
    list->elements = (int*)malloc(INITIAL_CAPACITY * sizeof(int));
    if (list->elements == NULL) {
        cout << "内存分配错误" << endl;
        exit(EXIT_FAILURE);
    }
    list->size = 0;
    list->capacity = INITIAL_CAPACITY;
}

// 获取当前存储的元素数量
int size(DynamicArrayList* list) {
    return list->size;
}

// 获取当前分配的存储空间容量
int capacity(DynamicArrayList* list) {
    return list->capacity;
}

// 判断动态顺序表是否为空
int isEmpty(DynamicArrayList* list) {
    return list->size == 0;
}

// 获取指定索引位置的元素值
int get(DynamicArrayList* list, int index) {
    if (index < 0 || index >= list->size) {
        cout << "访问溢出" << endl;
        exit(EXIT_FAILURE);
    }
    return list->elements[index];
}

// 设置指定索引位置的元素值
void set(DynamicArrayList* list, int index, int value) {
    if (index < 0 || index >= list->size) {
        cout << "访问溢出" << endl;
        exit(EXIT_FAILURE);
    }
    list->elements[index] = value;
}

// 在动态顺序表末尾添加元素
void add(DynamicArrayList* list, int value) {
    if (list->size == list->capacity) {
        // 如果存储空间已满,进行扩容操作
        list->capacity *= 2;
        list->elements = (int*)realloc(list->elements, list->capacity * sizeof(int));
        if (list->elements == NULL) {
            cout << "内存分配错误" << endl;
            exit(EXIT_FAILURE);
        }
    }
    list->elements[list->size++] = value;
}

// 释放动态顺序表的内存
void freeDynamicArrayList(DynamicArrayList* list) {
    free(list->elements);
    list->size = 0;
    list->capacity = 0;
}

int main() {
    DynamicArrayList list;
    initDynamicArrayList(&list);

    // 示例操作
    add(&list, 10);
    add(&list, 20);
    add(&list, 30);

    cout << "顺序表的大小为:" << size(&list) << endl;
    cout<<"顺序表的容量为:" <<capacity(&list)<<endl;

    cout<<"顺序表的第二个元素为:"<<get(&list, 1)<<endl;

    set(&list, 1, 25);
    cout << "顺序表的第二个元素为:" << get(&list, 1);

    freeDynamicArrayList(&list);

    return 0;
}

结果为

 

切记 大小≠容量

大小是有多少个元素,容量是指最多可以存储多少个元素

6. 顺序表的插入

将新元素插入到指定位置,并调整原有元素的位置以保持顺序表的有序性。

void Insert(ArrayList* list,int index,int value) {
    if ((index < 0) || (index >= MAX_SIZE)) {//访问越界
        cout << "访问越界" << endl;
        return;
    }
    else if(list->size==MAX_SIZE){//数组已满
        cout << "顺序表已满,无法插入" << endl;
        return;
    }
    else {
        for (int i = list->size - 1; i >= index; i--) {//index后的元素后移
            list->elements[i + 1] = list->elements[i];
        }
        list->elements[index] = value;
        list->size++;
    }
}

7. 顺序表的删除

将指定位置的元素移除,并调整顺序表中其他元素的位置,以保持有序表的结构 。

void Delete(ArrayList* list, int index) {
    if ((index < 0) || (index >=list->size)) {//访问越界
        cout << "访问越界" << endl;
        return;
    }
    else {
        for (int i = index; i <list->size; i++) {//index后的元素前移
            list->elements[i] = list->elements[i+1];
        }
        list->size--;
    }
}

 8. 顺序表的应用

  1. 数组: 数组是一种顺序表的实现方式,它在内存中按顺序存储元素。数组适用于需要快速随机访问元素的场景,例如在数学运算、图像处理等领域。

  2. 数据库: 在数据库中,表格可以被看作是一种顺序表。每一行记录都是表格中的一个元素,而每一列则对应于记录中的一个属性。数据库系统可以使用顺序表来快速检索、插入和删除记录。

  3. 缓存: 缓存是一种用于提高数据访问速度的机制。顺序表可以用于实现缓存,其中最近访问的数据被存储在靠近数组的一端,以提高访问效率。

  4. 文件存储: 顺序表可以用于存储文件中的数据。例如,一个文本文件的每一行可以被看作顺序表中的一个元素。

  5. 图形学: 在图形学中,顺序表可以用于存储图像的像素数据。图像的每个像素可以被看作是顺序表中的一个元素,通过对这些元素的操作,可以实现图像的处理和变换。

  6. 队列和栈: 虽然队列和栈通常使用链表来实现,但它们也可以通过顺序表来实现。在这种情况下,队列的元素在数组的一端进入,另一端出队,而栈则在数组的一端进出。

  7. 电子表格: 电子表格软件(如Microsoft Excel、Google Sheets等)中的表格可以被视为一种顺序表。每个单元格中的数据可以被看作是顺序表中的一个元素,通过公式和函数可以对这些元素进行操作。

三、实验内容

问题描述

1、 初始化顺序表 L;

2、 依次在 L 尾部插入元素-1,21,13,24,8;

3、 输出顺序表 L;

4、 输出顺序表 L 长度;

5、 判断顺序表 L 是否为空;

6、 输出顺序表 L 的第 3 个元素;

7、 输出元素 24 的位置;

8、 在 L 的第 4 个元素前插入元素 0;

9、 输出顺序表 L;

10、 删除 L 的第 5 个元素;

11、 输出顺序表 L。

代码

#include <iostream>
using namespace std;

#define MAX_SIZE 100

typedef struct ArrayList {
    int elements[MAX_SIZE];   // 存储线性表元素的数组
    int size;        // 当前存储的元素数量
};

//顺序表的初始化
void Initial_List(ArrayList* list) {
    list->size = 0;
}

//插入元素
void Insert(ArrayList* list,int index,int value) {
    if ((index < 0) || (index >= MAX_SIZE)) {//访问越界
        cout << "访问越界" << endl;
        return;
    }
    else if(list->size==MAX_SIZE){//数组已满
        cout << "顺序表已满,无法插入" << endl;
        return;
    }
    else {
        for (int i = list->size - 1; i >= index; i--) {//index后的元素后移
            list->elements[i + 1] = list->elements[i];
        }
        list->elements[index] = value;
        list->size++;
    }
}
void Delete(ArrayList* list, int index) {
    if ((index < 0) || (index >=list->size)) {//访问越界
        cout << "访问越界" << endl;
        return;
    }
    else {
        for (int i = index; i <list->size; i++) {//index后的元素前移
            list->elements[i] = list->elements[i+1];
        }
        list->size--;
    }
}

//返回某个元素的索引位置,默认返回第一个
int find_index(ArrayList* list, int value) {
    for (int i = 0; i < list->size; i++) {
        if (list->elements[i] == value) {
            return i;
            break;
        }
    }
    return -1;
}

//判断顺序表是否为空
int IsEmpty(ArrayList* list) {
    if (list->size == 0) {//若是空,则返回1
        return 1;
    }
    else {
        return 0;
    }
}
int main() {
    ArrayList L;
    int data[5] = { -1,21,13,24,8 };
    Initial_List(&L);//初始化顺序表L
    //尾部插入
    for (int i = 0; i < 5; i++) {
        Insert(&L, L.size, data[i]);
    }
    //输出顺序表
    cout << "顺序表为:";
    for (int i = 0; i < L.size; i++) {
        cout << L.elements[i]<<" ";
    }
    cout << endl;
    cout << "顺序表的长度为:" << L.size<<endl;
    if (IsEmpty(&L) == 1) {
        cout << "顺序表为空" << endl;
    }
    else {
        cout << "顺序表不为空" << endl;
    }
    cout << "顺序表的第三个元素为:" << L.elements[2] << endl;
    if ((find_index(&L, 24)) != -1) {
        cout<<"元素24的位置为:"<< find_index(&L, 24)<<endl;
    }
    else {
        cout<<"元素24不在顺序表中"<<endl;
    }
    //在第四个元素前插入0
    Insert(&L,3,0);
    //输出顺序表
    cout << "顺序表为:";
    for (int i = 0; i < L.size; i++) {
        cout << L.elements[i] << " ";
    }
    cout << endl;
    Delete(&L, 4);
    //输出顺序表
    cout << "顺序表为:";
    for (int i = 0; i < L.size; i++) {
        cout << L.elements[i] << " ";
    }
    return 0;
}

截图

分析 

这段代码并不难,稍微复杂的是链表,将会在下一篇文章中介绍

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录汇川:ITP与Autoshop进行仿真连接

1、定义如下程序&#xff1a; 2、ITP新建工程&#xff1a; 3、依次选择&#xff0c;最后修改IP 4、定义两个变量 5、拖一个按钮和一个圈出来&#xff0c;地址绑定&#xff1a;M1 6、地址绑定&#xff1a;Y1 7、PLC启动仿真 8、ITP启动在线模拟器 9、即可实现模拟仿真

Redis 配置(二)

目录 redis 配置 Redis 主从复制 主从复制的作用 主从复制流程 搭建Redis 主从复制 Redis 哨兵模式 哨兵模式的作用 哨兵结构 故障转移机制 主节点的选举 搭建Redis 哨兵模式 Redis 群集模式 集群的作用 Redis集群的数据分片 Redis集群的主从复制模型 搭建R…

拓数派加入 OpenCloudOS 操作系统开源社区,作为成员单位参与社区共建

近日&#xff0c;拓数派签署 CLA(Contributor License Agreement 贡献者许可协议)&#xff0c;正式加入 OpenCloudOS 操作系统开源社区。 拓数派&#xff08;英文名称“OpenPie”&#xff09;是国内基础数据计算领域的高科技创新企业。作为国内云上数据库和数据计算领域的引领者…

CentOS7部署GitLab-ce-16.7.0-ce.0.el7

文章目录 下载地址上传服务器安装访问配置external_url修改防火墙端口开放 重新加载配置访问GitLab出现502访问错误继续访问gitlab账户和密码修改GitLab常用命令 下载地址 gitlab 下载地址 上传服务器 scp -r C:\Users\xxx.xxxx\Downloads\gitlab-ce-16.7.0-ce.0.el7.x86_64…

黑马苍穹外卖学习Day3

目录 公共字段自动填充问题分析实现思路代码实现 新增菜品需求分析和设计接口设计代码开发开发文件上传接口功能开发 菜品分页查询需求分析和设计代码开发 菜品删除功能需求分析与设计代码实现代码优化 修改菜品需求分析和设计代码实现 公共字段自动填充 问题分析 员工表和分…

因为相信,所以简单,因为简单,所以坚持

因为相信&#xff0c;所以简单&#xff1b;因为简单&#xff0c;所以坚持。今天&#xff0c;我有幸受邀参加了九龙珠集团2023年以《蓄力生长》为主题的年会。在这里&#xff0c;我深刻感受到这两句话不仅是九龙珠集团成长的缩影&#xff0c;也是其不断前进的动力。在企业的经营…

选择智能酒精壁炉,拥抱环保与未来生活

保护环境一直是我们共同的责任和目标&#xff0c;而在这场争取保护环境的斗争中&#xff0c;选择使用智能酒精壁炉而非传统壁炉成为了一种积极的行动。这不仅仅是对环境负责&#xff0c;更是对我们自身生活质量的关照。 传统壁炉与智能酒精壁炉的对比 传统壁炉常常以木柴、煤炭…

如何创建VPC并配置安全组以保护您的阿里云服务器

将您的基础架构放在云上意味着您可以接触到全球的许多人。但是&#xff0c;这也意味着不怀好意的人可以访问您的服务。保护您的云网络非常重要。阿里云提供虚拟专用网络 &#xff08;VPC&#xff09;&#xff0c;这是一个安全隔离的私有云&#xff0c;将您的弹性计算服务 &…

算法第十一天-组合总和Ⅳ

组合总和Ⅳ 题目要求 解题思路 来自[负雪明烛] 题目有个明显的提示&#xff1a;求组合的个数&#xff0c;而不是每个组合。如果是要求出每个组合&#xff0c;那么必须使用回溯法&#xff0c;保存所有路径。但是如果是组合个数&#xff0c;一般都应该想到[动态规划]的解法。 直…

vite-admin框架搭建,ESLint + Prettier 语法检测和代码格式化

vite-admin框架搭建&#xff0c;ESLint Prettier 语法检测和代码格式化 1. 环境和工具2. 项目初始化3. 安装插件1. 安装ESLint1.1 安装插件1.2 初始化ESLint 2. 安装Prettier2.1 安装插件2.2 配置Prettier 3. vscode 安装插件及配置3.1 安装插件 ESLint 和 Prettier - Code fo…

许战海战略文库|加加食品:错过窗口期的“酱油第一股”如何逆袭

加加食品集团股份有限公司成立于1996年&#xff0c;是一家综合研发、生产和营销的大型调味品上市公司。该公司在2012年1月6日成功上市&#xff0c;被尊称为“中国酱油第一股”。然而&#xff0c;在近年来&#xff0c;该公司经历了重大挑战&#xff0c;包括持续的业绩下滑、低迷…

Docker简述与基础部署详解

docker官网&#xff1a;https://www.docker.com docker中文库:https://www.docker.org.cn/ Docker是一种开源的容器化平台&#xff0c;用于轻松打包、交付和运行应用程序。Docker的主要优势在于它提供了一种轻量级、可移植、自包含的容器化技术&#xff0c;使得应用程序及其所…

基于uniapp封装的card容器 带左右侧两侧标题内容区域

代码 <template><view class"card"><div class"x_flex_header"><div><title v-if"title ! " class"title" :title"title" :num"num"></title></div><div><s…

计算机网络—— 概述

概述 1.1 因特网概述 网络、互联网和因特网 网络由若干结点和连接这些结点的链路组成多个网络还可以通过路由器互联起来&#xff0c;这样就构成了一个覆盖范围更大的网络&#xff0c;即互联网&#xff08;或互连网&#xff09;。因特网&#xff08;Internet&#xff09;是世…

连接两个路由器的有线连法,关键时候可能会发挥不小的作用

路由器网桥连接两个或多个路由器&#xff0c;以扩展网络范围&#xff0c;提供额外的以太网端口和无线接入点。但在开始之前&#xff0c;你必须首先决定如何使用每个路由器。因此&#xff0c;你需要知道你想要实现什么&#xff0c;并清楚地了解你对每台设备的期望。 例如你想扩…

docker run 命令详解

一、前言 Docker容器是一个开源的应用容器引擎&#xff0c;让开发者可以以统一的方式打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何安装了Docker引擎的服务器上&#xff08;包括流行的Linux机器、Windows机器&#xff09;&#xff0c;也可以实现虚拟…

目标检测-One Stage-YOLOv5

文章目录 前言一、YOLOv5的网络结构和流程YOLOv5的不同版本YOLOv5的流程YOLOv5s的网络结构图 二、YOLOv5的创新点1. 网络结构2. 输入数据处理3. 训练策略 总结 前言 前文目标检测-One Stage-YOLOv4提到YOLOv4主要是基于技巧的集成&#xff0c;对于算法落地具有重大意义&#x…

面试算法105:最大的岛屿

题目 海洋岛屿地图可以用由0、1组成的二维数组表示&#xff0c;水平或竖直方向相连的一组1表示一个岛屿&#xff0c;请计算最大的岛屿的面积&#xff08;即岛屿中1的数目&#xff09;。例如&#xff0c;在下图中有4个岛屿&#xff0c;其中最大的岛屿的面积为5。 分析 将岛屿…

Mysql 数据库ERROR 1820 (HY000): You must reset your password using ALTER USER 解决办法

Mysql 5.7数据库原来一直都能正常访问&#xff0c;突然访问不了&#xff0c;查看日志提示数据库需要修改密码&#xff0c; 具体解决办法如下操作&#xff1a; Windows 下&#xff1a; mysql的bin目录下&#xff0c; mysql>use mysql; mysql>mysql -uroot -p密码; 判…

git常用命令及概念对比

查看日志 git config --list 查看git的配置 git status 查看暂存区和工作区的变化内容&#xff08;查看工作区和暂存区有哪些修改&#xff09; git log 查看当前分支的commit 记录 git log -p commitID详细查看commitID的具体内容 git log -L :funcName:fileName 查看file…