【数据结构】动态顺序表的实现

1.什么是数据结构

数据结构就是把数据元素按照一定的关系组织起来的集合,用来组织和存储数据。通过数据结构,能够有效的将数据组织和管理在一起,按照我们的方式任意对数据进行增删查改等操作。

2.数据结构的分类 

数据结构大概可分为逻辑结构物理结构两大类 。

2.1逻辑结构 

逻辑结构:是从具体问题中抽象出来的模型,是抽象意义的结构。

  • 集合结构:结构中数据元素除了同属于一个集合外,它们之间没有任何关系
  • 线性结构:结构中数据元素之间存在一一对应的关系
  • 树形结构:结构中数据元素之间存在一对多的层次关系
  • 图形结构:结构中数据元素是多对多的关系

2.2物理结构 

物理结构:逻辑结构在计算机中真正的表示方式(又称映像)。

常见的物理结构(存储结构)有顺序存储链式存储索引存储,以及散列存储

  • 顺序存储结构:把数据元素放到地址连续的内存单元里面,其数据间的逻辑关系和物理关系是一致的,比如我们常用的数组就是顺序存储结构。
  • 链式存储结构:是把数据元素存放在任意的存储单元里面,这组存储单元可以是连续的,也可以是不连续的。此时,数据间的物理关系不能反映其逻辑关系。所以每一数据元素均使用一个结点来存储,不仅需要存储数据元素,而且还要存储数据元素之间的逻辑关系(将结点分为两部分,一部分存储数据元素本身,称为数据域;一部分存储下一个结点的地址,称为指针域。
  • 索引存储结构:在索引存储结构中,不仅需要存储所有数据元素(称为主数据表),还需要建立附加的索引表。每个数据元素都由一个唯一的关键字来标识,由该关键字和对应的数据元素的地址构成一个索引项,存入索引表。
  • 散列(哈希)存储结构:散列存储结构是指依据数据元素的关键字,通过事先设计好的哈希函数计算出一个值,再将其作为该数据的存储地址。

2.3总结 


最基础的数据结构:数组

有了数组,为什么还要学习其他的数据结构?

假定数组有10个空间,已经使用了5个,向数组中插入数据步骤:

求数组的有效数据个数,向下标为数据有效个数的位置插入数据。(注意:这里要判断数组是否满了)

假设数据量非常庞大,频繁的获取数组有效数据个数会影响程序执行效率。

结论:最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现。


3.线性表

线性表(linear list)指的是具有部分相同特性的一类数据结构的集合。

线性表的逻辑结构属于线性结构,采用顺序存储结构为顺序表,采用链式存储结构为线性链表顺序表在C语言中一般使用数组去实现,链表使用结构体去实现


3.1顺序表

顺序表的底层结构是数组,通过对数组的封装,实现了常用的增删改查等接口。

3.2顺序表的分类

静态顺序表

概念:使用定长数组存储元素

//静态顺序表
typedef int SLDATATYPE;
#define N 100
typedef struct SeqList
{SLDATATYPE arr[N];//定长数组int size;//顺序表当前有效数据个数
}SL;

静态顺序表缺陷静态顺序表的长度是固定的,因此数组满了需要手动更改N,空间给少了不够用,给多了造成空间浪费。

动态顺序表

//动态顺序表——按需申请  可增容
typedef int SLDATATYPE;
typedef struct SeqList
{SLDATATYPE* arr;//指向动态开辟的数组int size;//顺序表当前有效数据个数int capacity;//记录当前空间大小
}SL;

3.3动态顺序表的实现

3.3.1顺序表的初始化

void SLInit(SL *ps)//注意:这里不可以写成void SLInit(SL ps)//会报错:使用了未初始化的局部变量!这是值传递,对形参的修改不影响实参。要传地址
{ps->arr = NULL;ps->size = ps->capacity = 0;
}

3.3.2顺序表的销毁

顺序表的销毁
void SLDestory(SL* ps)
{if (ps->arr){free(ps->arr);//先释放空间,然后置空}ps->arr = NULL;ps->size = ps->capacity = 0;
}

3.3.3顺序表的插入

尾插

注意:插入数据之前先看空间够不够。初始化后空间容量为0,插入数据之前先申请空间,也可能空间满了,有效数据个数等于空间容量了,也要申请空间。

容量检查函数

void SLCheckCapacity(SL*ps)
{//插入数据之前先看空间够不够if (ps->capacity == ps->size){//申请空间		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//三目表达式SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * 2 * sizeof(SLDataType));//要申请多大空间//若要频繁的增容,则会造成程序的运行效率大大降低,增容通常来说是成倍数的增加,一般是2或者3倍//realloc申请空间失败返回空指针,所以再造一个临时的指针tmpif (tmp == NULL){perror("realloc");exit(1);//直接退出程序}//空间申请成功ps->arr = tmp;ps->capacity = newcapacity;}
}

尾插实现 

void SLPushBack(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;//增加一个数据,有效数据个数+1/*ps->arr[ps->size] = x;++ps->size;*/
}

头插

void SLPushFront(SL* ps, SLDataType x)
{assert(ps);	SLCheckCapacity(ps);//先让顺序表中已有的数据整体往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];//最后一次ps->arr[1]=ps->arr[0]}ps->arr[0] = x;ps->size++;
}

3.3.4顺序表的删除

尾删

void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//判断顺序表是否为空,为空不能执行删除操作//顺序表不为空--ps->size;
}

注意:被删除的数据空间不需要置为0,没有意义,下次访问这块空间时,新的数据会覆盖掉。也不能释放空间,因为free只能从开辟的空间的首地址处释放,不能释放其他地方的空间。


头删

void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//数据整体往前挪动一位for (int i = 0; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];//最后一次ps->arr[size-2] = ps->arr[size-1]}ps->size--;
}

3.3.5在指定位置插入数据

void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);//让pos及之后的数据整体向后挪动一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];//最后一次ps->arr[pos+1]=ps->arr[pos]}ps->arr[pos] = x;ps->size++;
}

3.3.6删除指定位置的数据

void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];//最后一次ps->arr[size-2]=ps->arr[size-1]}ps->size--;
}

3.3.7顺序表的查找

int SLFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] ==x){//找到了!return i;}}//没有找到!return -1;
}

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

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

相关文章

Selenium + Python 自动化测试19(补充-读取各种文件数据操作)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了数据驱动测试中如何完成重复的测试实例&#xff0c;今天我们补充一些读取各种文件的方法。 本篇文章我们讨论一下如何使用读取txt、CSV、Excel文件&#xff0…

14-17岁未成年如何办理能一直用的手机卡?

14-17岁未成年如何办理能一直用的手机卡&#xff1f; 有些姐妹要去外面上学&#xff0c;都想要一张属于自己的手机卡。 但是因为反诈的原因&#xff0c;对于手机卡的申领特别严格。 很多不满18岁的人能申领的卡&#xff0c;都是物联卡或者纯流量卡&#xff0c;只能上网&#x…

如何评估Redis的性能

如果系统中出现了大 key、热 key 等&#xff0c;往往会导致 Redis 变慢&#xff0c;但是这个慢该如何界定&#xff1f;多久算慢&#xff1f;1秒还是3秒&#xff1f; 这个肯定是没有标准答案&#xff0c;因为这个和你的硬件设备有关。 硬件差一些&#xff0c;平时响应时间都是…

css 宫格样式内容上下结构

结构 <div class"sc-content-group"><div class"sc-content-item"><div class"sc-item-img"><el-image :src"src" :preview-src-list"[src]"></el-image></div><div class"s…

前程无忧搜索接口 JS 逆向:阿里系acw_sc__v2和Sign加密

&#x1f4ca; 前程无忧搜索接口 JS 逆向&#xff1a;阿里系acw_sc__v2和Sign加密 &#x1f50d; 观察网页加密规律&#xff1a;阿里系acw_sc__v2 在分析前程无忧的搜索接口时&#xff0c;我们首先需要关注网页的加密规律。特别是阿里系的 acw_sc__v2 加密机制。这个加密机制通…

图论 最短路

文章目录 单源最短路朴素Dijkstra代码 堆优化Dijkstra代码 Bellman-ford代码 spfaspfa求最短路代码 spfa判断负环代码 多源最短路Floyd代码 单源最短路 朴素Dijkstra 给定一个 n n n 个点 m m m 条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c;所有边权均为正…

龙格-库塔法(Matlab实现)

四阶龙格-库塔法介绍 在各种龙格&#xff0d;库塔法当中有一个方法十分常用&#xff0c;以至于经常被称为“RK4”或者就是“龙格&#xff0d;库塔法”。该方法主要是在已知方程导数和初始值时&#xff0c;利用计算机的仿真应用&#xff0c;省去求解微分方程的复杂过程。 令初…

场景库之高精度地图编辑器

一、背景介绍 高精度地图编辑器是场景库生产所需的必要工具&#xff0c;地图编辑器基于JS开发&#xff0c;可对指定的地图进行描绘&#xff0c;生成数字高精度地图。 二、功能介绍 路网元素支持&#xff1a; 类别元素图片交叉口交叉口安全岛交通岛导流岛道路中心圈路口边缘线…

msvcp110.dll丢失修复?教你几招简单易懂的修复msvcp110.dll指南

msvcp110.dll错误通常出现在Windows操作系统中&#xff0c;表明系统缺少或损坏了该msvcp110.dll文件&#xff0c;这是Microsoft Visual C 2012 Redistributable程序包的一部分。下面列出了几种彻底解决此问题的全面方法&#xff0c;以确保解决从简单文件丢失到系统级问题的多种…

使用Intent在活动之间穿梭

文章目录 使用Intent在活动之间穿梭使用显式Intent使用隐式Intent更多隐式Intent的用法 使用Intent在活动之间穿梭 Intent是Android程序中各组件之间进行交互的一种重要方式&#xff0c;它不仅可以指明当前组件想要执行的动作&#xff0c;还可以在不同组件之间传递数据。Inten…

类的构造函数和显式与隐式转化函数

在这个示例中&#xff0c;Iterator类的构造函数是显式的&#xff0c;但通过定义类型转换函数operator Iterator()&#xff0c;你可以通过隐式类型转换来创建Iterator对象。 总之&#xff0c;如果你想要隐式构造一个迭代器对象&#xff0c;你可以将迭代器的构造函数声明为非显式…

Git 的基本使用

1.创建 Git 本地仓库 仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂件进⾏版本控制&#xff0c;就必须先创建⼀个仓库出来&#xff0c;例如下面代码创建了gitcode_linux的文件夹&#xff0c;之后再对其进行初始化。创建⼀个 Git 本地仓库对应的命令为 git init &#xff0c…

Postman接口自动化之postman脚本编写

这是之前搞的接口自动化方案&#xff0c;已经在业务测试中实现了使用postman编写接口脚本&#xff0c;通过GitHubJenkinsemail html report实现了接口自动化&#xff0c;现在分块整理一下。 postman脚本编写 1、创建集合 和 目录&#xff1a; 一条业务线下的接口可以放到一个…

Docker离线安装

概述 Docker既可以在线安装&#xff0c;又可以离线安装。有时服务器不能连接互联网&#xff0c;只能采用离线安装的方式。 Docker的Linux发行包可以在https://download.docker.com/linux/下载。另外&#xff0c;国内有镜像网站&#xff0c;下载速度更快&#xff08;例如https…

联想电脑如何查看ip地址?详细介绍几种方法

随着互联网的普及和技术的飞速发展&#xff0c;IP地址已成为我们日常网络活动中不可或缺的一部分。无论是访问网站、远程办公还是进行网络游戏&#xff0c;IP地址都扮演着重要的角色。对于联想电脑用户来说&#xff0c;了解如何查看自己的IP地址是一项基本技能。虎观代理小二将…

[Linux] 认识系统服务(daemon)

参考&#xff1a;《鸟哥的Linux私房菜》 一、什么是 daemon 与服务&#xff08;service&#xff09; 在英语中的daemon就有守护进程&#xff0c;后台程序的意思。简单来说就是一直在后台运行的进程&#xff0c;我们就称之为服务(service)&#xff0c;或者是守护进程(daemon)。…

Mybatis实现员工管理系统

文章目录 1.案例需求2.编程思路3.案例源码4.小结 1.案例需求 在上次做的父子模块的maven以及Ajax实现人工管理系统的基础上使用Mybatis实现员工管理系统的增删改查&#xff0c;具体运行效果如下&#xff1a; 2.编程思路 Mybatis框架的一般执行流程&#xff1a; 创建MyBati…

Java中的IO流-最全最基础的IO流概述和简介

IO流简介 IO是什么 Java中的IO流是用于处理数据输入和输出的核心机制。通过应用IO流可以使Java程序能够与外部世界&#xff08;如磁盘文件、网络、硬件设备等&#xff09;进行数据交互。IO流的全称为输入/输出流&#xff08;Input/Output Stream&#xff09;&#xff0c;它是…

探索Python性能优化的神秘力量:Line Profiler

文章目录 探索Python性能优化的神秘力量&#xff1a;Line Profiler第一部分&#xff1a;背景第二部分&#xff1a;库简介第三部分&#xff1a;安装指南第四部分&#xff1a;基本使用方法第五部分&#xff1a;实际应用场景场景1&#xff1a;数据分析场景2&#xff1a;机器学习模…

qt-16可扩展对话框--隐藏和展现

可扩展对话框 知识点extension.hextension.cppmain.cpp运行图初始化隐藏展现--点击--详细按钮 知识点 MainLayout->setSizeConstraint(QLayout::SetFixedSize);//固定窗口大小 extension.h #ifndef EXTENSION_H #define EXTENSION_H#include <QDialog>class Extens…