数据结构与算法学习笔记之线性表三---顺序表的动态分配存储表示和实现(C++)

目录

前言

1.顺序表的动态分配存储表示

2.顺序表的静态存储表示

1.初始化

2.销毁

3.清空

4.判空

5.表长       

6.数据元素

7.获取下标

8.前驱节点

9.后继节点

10.插入

11.删除

12.遍历

13.测试代码


前言

    这篇文章讲的是线性表的动态分配存储表示。

1.顺序表的动态分配存储表示

        在上一篇博客中,我们介绍了线性表的静态分配存储结构。使用静态分配的时候,有个缺点就是数组的长度是固定的,顺序表中数据元素达到上上限之后,我们就无法继续操作了。

         C++中我们除了使用静态数组之外,还可以动态的给数据元素分配存储空间,这样的话线性表的长度就可变了,我们就可以更加灵活的操作表了。

2.顺序表的静态存储表示

       在C++中顺序表的动态分配存储结构定义如下:

//----- 线性表的动态分配顺序存储结构 - - - - -
#define LIST_INIT_SIZE 10  // 线性表存储空间的初始分配量
#define LISTINCREMENT  10   // 线性表存储空间的分配增量
typedef int ElementType;
typedef int Status;
typedef struct {ElementType * element; // 存储空间基址int length;            // 当前长度int lisezsize;         // 当前分配的存储容量(以sizeof(ElementType)为单位)
}SeqList;

        其中,数组指针elem表示线性表的基地址,length表示线性表的当前长度,listsize指示顺序表当前分配的存储空间大小,一旦因为插入元素而空间不足的时候,可进行再分配,即为顺序表增加一个大小存储为LISTINCREMENT个数据元素的空间。

1.初始化

        顺序表的时候分配初始内存空间

// 初始化顺序表
Status initSeqList(SqList *sqList){sqList->element = new ElementType[LIST_INIT_SIZE];//分配内存if (!sqList->element) {return 0; // 内存分配失败}sqList->length = 0; // 初始长度为0sqList->listsize = LIST_INIT_SIZE; // 初始存储容量为初始分配量return 1; // 初始化成功
}

2.销毁

        删除动态分配的存储空间,置空指针和容量大小

// 销毁
void destroySqList(SqList *sqList){delete [] sqList->element;sqList->element = nullptr;//讲指针置空sqList->length = 0;sqList->listsize = 0;
}

3.清空

        长度置为0

// 清空
void clearSqList(SqList *sqList){sqList->length = 0;// 长度置为0.但存储空间不变
}

4.判空

// 判空
Status emptySqList(SqList *sqList){return sqList->length == 0;
}

5.表长       

        返回顺序表的长度

// 长度
int staticSqListLength(StaticSqList *sqList){return sqList->length;
}

6.数据元素

        遍历数组根据下标获取数据元素

// 获取元素
Status getElemForSqList(SqList *sqList,int location,ElementType * element){if (location > sqList->length - 1 || location < 0) {return 0;}*element = sqList->element[location];return 1;
}

7.获取下标

// 获取元素下标
Status locationElemForSqList(SqList *sqList,ElementType element,int *location){for (int i = 0; i < sqList->length; i++) {if (sqList->element[i] == element) {* location = i;return 1;}}return 0;
}

8.前驱节点

// 前驱节点
Status priorElemForSqList(SqList *sqList,ElementType currentElement,ElementType * priorElement){for (int i = 0; i < sqList->length; i++) {if (sqList->element[i] == currentElement) {if (i >= 1) {* priorElement = sqList->element[i-1];return 1;}}}return 0;
}

9.后继节点

// 后继节点
Status nextElemForSqList(SqList *sqList,ElementType currentElement,ElementType * nextElement){for (int i = 0; i < sqList->length; i++) {if (sqList->element[i] == currentElement) {if (i < sqList->length - 1) {* nextElement = sqList->element[i+1];return 1;}}}return 0;
}

10.插入

        当我们使用动态分配存储表示顺序表的时候,如果在插入元素时发现顺序表的存储空间已满,我们需要动态地扩展存储空间,以容纳更多的元素。这就涉及到重新分配内存,并将原有数据复制到新的存储空间中,然后再进行元素插入操作。这样可以确保在插入元素时不会受到存储空间的限制。

// 插入
Status insertSqList(SqList *sqList, int pos, ElementType element) {if (pos < 0 || pos > sqList->length + 1) {return 0;}// 检查存储空间是否足够,不足则扩展存储空间if (sqList->length >= sqList->listsize) {ElementType *newElement = new ElementType[sqList->listsize + LISTINCREMENT]; // 新的存储空间if (!newElement) {return 0; // 内存分配失败}// 将原有数据复制到新的存储空间中for (int i = 0; i < sqList->length; ++i) {newElement[i] = sqList->element[i];}// 释放原有存储空间delete[] sqList->element;// 更新指针指向新的存储空间sqList->element = newElement;// 更新存储容量sqList->listsize += LISTINCREMENT;}// 插入位置之后的元素后移for (int i = sqList->length; i > pos - 1; i--) {sqList->element[i] = sqList->element[i - 1];}// 插入新元素sqList->element[pos - 1] = element;// 更新顺序表的长度sqList->length++;return 1; // 插入成功
}

11.删除

// 删除
Status deleteSqList(SqList *sqList, int i, ElementType *element) {if (i < 1 || i > sqList->length || sqList->length == 0) {return 0;}*element = sqList->element[i - 1];for (int j = i; j < sqList->length; j++) { // 删除位置之后的元素前移sqList->element[j - 1] = sqList->element[j];}sqList->length--;return 1;
}

12.遍历

// 遍历
void traverseSqList(SqList *sqList){for (int i = 0; i<sqList->length; i++) {cout<<sqList->element[i]<<"\t";}cout<<endl;
}

13.测试代码

void testSeqList(void){SqList sqList;cout<<"顺序表初始化......"<<endl;if (initSeqList(&sqList)) {cout<<"顺序表初始化成功"<<endl;}cout<<"顺序表判空和长度计算......"<<endl;if (emptySqList(&sqList)) {cout<<"顺序表为空,长度为"<<SqListLength(&sqList)<<endl;}cout<<"顺序表插入测试......"<<endl;for (int i = 1; i <=11 ; i++) {if (insertSqList(&sqList, sqList.length + 1, i)) {cout<<"数据元素"<<i<<"插入成功"<<endl;}else{cout<<"数据元素"<<i<<"插入失败"<<endl;}}cout<<"插入之后的静态顺序表"<<endl;traverseSqList(&sqList);cout<<"顺序表删除测试......"<<endl;ElementType element;if (deleteSqList(&sqList, 10, &element)){cout<<"数据元素"<<element<<"删除成功"<<endl;}cout<<"删除之后的静态顺序表"<<endl;traverseSqList(&sqList);//后继节点测试ElementType nextElement;if (nextElemForSqList(&sqList, 8, &nextElement)) {cout<<"数据元素8"<<"后继节点为:"<<nextElement<<endl;}else{cout<<"后继节点不存在"<<endl;}//前驱节点测试ElementType priorElement;if (priorElemForSqList(&sqList, 8, &priorElement)) {cout<<"数据元素8"<<"前驱节点为:"<<priorElement<<endl;}else{cout<<"前驱节点不存在"<<endl;}cout<<"顺序表数据元素下标测试......"<<endl;for (int i = -1; i <= 12; i++) {int location;if (locationElemForSqList(&sqList, i, &location)) {cout<<"数据元素"<<i<<"下标为:"<<location<<endl;}else{cout<<"数据元素不存在"<<endl;}}destroySqList(&sqList);cout<<"顺序表销毁"<<endl;
}

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

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

相关文章

【JAVA进阶篇教学】第十三篇:Java中volatile关键字讲解

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第十三篇&#xff1a;volatile关键字讲解。 在 Java 中&#xff0c;volatile关键字是一种轻量级的同步机制&#xff0c;用于确保变量的可见性和禁止指令重排序。本文将详细解释volatile关键字的工作原理、可见性保证以及…

买卖股票的最佳时机 II(LeetCode 122)

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

react组件渲染性能优化之函数组件-memo使用

函数组件赋值相同的值视图不会渲染&#xff0c;类组件会&#xff0c;因为函数组件默认就阻止了 import {useState} from react export default function App() {const [counter, setCounter] useState(1)console.log(App组件渲染了);return(<div><h1>{counter}&l…

已解决java.lang.AbstractMethodError: 抽象方法错误的正确解决方法,亲测有效!!!

已解决java.lang.AbstractMethodError: 抽象方法错误的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 报错原因 解决思路 解决方法 更新和重新编译依赖 确认类和接口的版本一致性 类加载器配置检查 总结 问题分析 java.lang.…

防城港知识付费系统,教学活动在设计中需要注意什么?如何进行教学设计?

老师们的教学能否让学生学到知识&#xff0c;让学生懂得书本上的道理&#xff0c;那么教学活动很重要&#xff0c;因此在设计的时候&#xff0c;一定要根据教学的目的以及孩子的特点来进行设计。 假设老师为学生进行美术绘画的教学活动设计&#xff0c;那么需要注意以下三个方面…

实现字符串复制(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int i 0;char a[100], b[100];//获取字符串&#xff1b;printf("请为数组a输入字符串…

使用模拟SPI接口驱动串行接口的LCD( STM32F4)

目录 概述 1. 硬件介绍 1.1 ST7796-LCD 1.2 MCU IO与LCD PIN对应关系 2 代码实现 2.1 STM32CubeMX 6.11生成工程 2.2 IO模拟SPI接口 2.3 实现LCD的驱动 3 测试 测试代码下载地址&#xff1a; stm32-f407-lcd-ft6336-proj资源-CSDN文库 gitee下载地址&#xff1a; h…

「PHP系列」PHP AJAX运用之数据库实例/XML实例

文章目录 一、AJAX 数据库实例1. 创建数据库和表2. HTML页面 (index.html)3. PHP脚本 (search.php)4. 配置和运行 二、AJAX XML实例1. PHP 脚本 (get_data.php)2. HTML 页面 (index.html)3. 配置和运行 三、相关链接 一、AJAX 数据库实例 一个PHP和AJAX结合使用来从数据库获取…

【Spring】验证 @ServerEndpoint 的类成员变量线程安全

文章目录 前言猜想来源验证方法Controller 的情况ServerEndpoint 的情况 后记 前言 最近有 websocket 的需求。探索 ServerEndpoint 的类成员变量特点。 这里类比 Controller 讨论 ServerEndpoint 类成员变量是否线程安全。 猜想来源 网上的教程大多数都这么展示程序&#…

祝融传火(试水)

一段时间没写代码了&#xff0c;今天试水一道直接寄了 #include <bits/stdc.h> using namespace std; typedef long long ll; ll n, m, h, w; ll a[1010][1010]; int main() {cin >> n >> m;for (int i 1; i < n; i){for (int j 1; j < m; j){cin &…

HR4988内置转换器和过流保护的微特步进电机驱动芯片

描述 HR4988是一款内部集成了译码器的微特步进电机驱动器&#xff0c;能使双极步进电机以全、半、1/4、1/8、1/16步进模式工作。步进模式由逻辑输入管脚MSx选择。其输出驱动能力达到32V和2A。 译码器是HR4988易于使用的关键。通过STEP管脚输入一个脉冲就可以使电机完成一次步进…

C语言——文件缓冲区

一、用户缓冲区和系统缓冲区 缓冲区的概念确实可以分为多个层次&#xff0c;其中最常见的两个层次是用户缓冲区和系统缓冲区。 这里的用户缓冲区和系统缓冲区都包括输入输出缓冲区。 1、用户缓冲区&#xff08;User-space Buffer&#xff09; 用户缓冲区是指由用户程序&…

202112青少年软件编程(Python)等级考试试卷(二级)

第 1 题 【单选题】 执行以下程序 a=[33,55,22,77]a.sort()for i in a:print(i)运行结果是?( ) A :33 55 22 77 B :22 33 55 77 C :55 33 22 77 D :77 55 33

群辉虚拟机安装openWRT作旁路由

最近在整活旁路由&#xff0c;基本就是要实现adguard和出国留学。openwrt这个的安装比较简单&#xff0c;就是先去找个镜像&#xff0c;然后导入即可。 我这里最后是去github上找了个大佬每天编译的地址链接。我用的是这个版本 1.下载解压得到img 下载完之后解压会得到一个…

paintevent讲解

Qt框架中的paintEvent是Qt中处理绘图的核心机制之一。每个使用Qt绘图的窗口部件&#xff08;QWidget或者从QWidget派生的类&#xff09;都会有一个paintEvent函数。这个函数是在部件需要重绘时被Qt框架自动调用的。 以下是paintEvent的工作原理及其在Qt中绘制过程中的作用&…

GDPU unity游戏开发 角色控制器与射线检测

在你的生活中&#xff0c;你一直扮演着你的角色&#xff0c;别被谁控制了。 小试 1. 创建一个角色控制器&#xff0c;通过键盘控制角色控制器的移动&#xff0c;角色控制器与家具发生碰撞后&#xff0c;通过Debug语句打印出被碰撞物体的信息(搜索OnControllerColliderHit的使用…

Hotcoin Research | 市场洞察:2024年5月6日-5月12日

加密货幣市场表现 加密货幣总市值为1.24万亿&#xff0c;BTC占比53.35%。 本周行情呈现先涨后跌的一种態势&#xff0c;5月6日-9日大盘持续下跌&#xff0c;周末为震荡行情。本周的比特幣现货ETF凈流入&#xff1a;1.1262亿美元&#xff0c;其中&#xff1a;美国ETF流入&…

1分钟快速上手枚举类

在Java中&#xff0c;枚举&#xff08;Enum&#xff09;是一种特殊的类&#xff0c;它包含了一组固定的常量。枚举类型在Java 5及以后的版本中引入&#xff0c;用于表示固定数量的常量集。下面是一个简单的枚举类的示例&#xff1a; public enum DayOfWeek {SUNDAY, MONDAY, …

keras机器学习三种模型典型案例

1, MLP模型预测 使用Keras进行数据预测的详细代码案例&#xff0c;包括模型构建、训练和预测的步骤&#xff0c;以及参数的解释。我们将使用一个简单的全连接神经网络&#xff08;也称为多层感知器&#xff0c;MLP&#xff09;来进行回归任务。这个案例将使用Keras&#xff0c…

数据结构===红黑树

文章目录 概要满足的条件基本思想操作红黑树的插入红黑树的删除遍历操作 代码C小结 概要 这篇说下红黑树 其实&#xff0c;红黑树&#xff0c;对于我来说&#xff0c;比较重要的几点。 满足几个条件基本思想插入删除 这些是很重要的。 满足的条件 红黑树需要满足什么条件呢&…