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

数据结构之顺序表

大家好,今天我们来给大家分享下数据结构顺序表,以及顺序表增删查改数据的一些的方法。

在这里插入图片描述

顺序表的概念:

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表可分为静态顺序表和动态顺序表:

静态顺序表:使用定长数组存储元素。

#define N 7
typedef int  SLDataType;typedef struct SeqlList
{SLDataType array[N];size_t size;
}SeqList;

动态顺序表:使用动态开辟的数组存储。

typedef int SLDataType;
typedef struct SeqList
{SLDataType* array;size_t size;size_t capicity;
}SeqList;

顺序表的接口实现:

typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;
// 基本增删查改接口
// 顺序表初始化
void SeqListInit(SeqList* psl, size_t capacity);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl);

顺序表初始化:


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

顺序表的检查,容量不够我们就扩容:

void SLCheckCapacity(SL* ps1)
{assert(ps1);if (ps1->size == ps1->capacity){int newCapacity = ps1->capacity == 0 ? 4 : ps1->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps1->a, sizeof(SLDataType) * newCapacity);if (tmp == NULL){perror("relloc fail");return;}ps1->a = tmp;ps1->capacity = newCapacity;}
}

首先我们要确保ps1指针不为空指针,防止出现野指针访问的情况,size是我们保存的数据个数,capacity使是我们数据表的容量,如果二者相等那就代表着我们的顺序表需要扩容。所以我们给tmp开辟空间赋给a,新的容量赋给capacity。

顺序表的打印:

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

顺序表的销毁:

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

注意的是要确保ps1不是空指针,如果为空的话那么就是野指针,野指针访问的话程序就崩溃了。

顺序表头插:

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

在这里插入图片描述

我们要想实现头插的话就拿上面的例子,我们想要在这之前插入数据5,我们就得给后面的数据挪动移位,但是我们在挪动之前我们要检查顺序表是否有容量,如果没有就扩容,保证我们后面可以成功的挪动数据。我们挪动数据之后就把5插入进去就可以了,最后表示数据个数的size++。

顺序表尾插:

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

顺序表头删:

void SLPopFront(SL* ps1)
{assert(ps1);assert(ps1->size > 0);int begin = 1;while (begin < ps1->size){ps1->a[begin-1] = ps1->a[begin ];++begin;}ps1->size--;
}

在这里插入图片描述

我们对头删的理解非常的简单,就是我们将后面的数据给前面的数据覆盖掉,而且我们的size–就行了。但是我们这里一定要注意我们的顺序表一定要有数据。

顺序表尾删:

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

尾删我们只需要减少数据的个数,比如将最后一个数据去掉就可以了,我们size–的话最后一个数据就访问不到了,但是我们要保证我们的顺序表中有数据。

顺序表任意位置插入数据:

void SLInsert(SL* ps1, int pos, SLDataType x)
{assert(ps1);assert(pos >= 0 && pos <= ps1->size);SLCheckCapacity(ps1);int end = ps1->size-1;while (end >= pos){ps1->a[end+1] = ps1->a[end ];--end;}ps1->a[pos] = x;ps1->size++;
}

在这里插入图片描述

pos是我们要插入的数据位置,我们前面的数据保持不变,我们后面的位置要向后挪动一位,我们的end是我们最后一位数据的下标,我们的循环条件使我们的后面数据的坐标大于pos,当我们的end<pos的时候就表明我们pos后面的数据已经向后挪动完数据了,这个时候我们只需要插入数据,再size++就可以了。

顺序表任意位置删除数据:

void SLErase(SL* ps1, int pos)
{assert(ps1);assert(pos >= 0 && pos <= ps1->size);int begin = pos+1;while (begin < ps1->size){ps1->a[begin - 1] = ps1->a[begin];++begin;}ps1->size--;
}

在这里插入图片描述

这里和我们头删的逻辑差不多,只需要我们后面的数据向前挪动移位覆盖前面的数据就行了,这里我们pos后面的数据向前挪动移位,将我们的pos位置的数据覆盖就可以了,最后再size–就可以了。

今天的分享就到这里了,感谢大家的支持。

相关文章:

  • 2.Netty简单应用
  • 用了这款工具,让我效率提升了80%
  • CoDeSys系列-4、基于Ubuntu的codesys运行时扩展包搭建Profinet主从环境
  • JSP 学生成绩查询管理系统eclipse开发sql数据库serlvet框架bs模式java编程MVC结构
  • 深入理解JVM虚拟机第十八篇:JVM种局部变量表结构的认识
  • 设计模式之门面模式
  • 两种MySQL OCP认证应该如何选?
  • 【Spring】spring中存储Bean(对象)的相关注解及相关用法
  • git使用全解析 | git的原理 配置 基础使用 分支 合并
  • uniapp自定义权限菜单,动态tabbar
  • list-watch集群调度
  • 使用腾讯云轻量服务器安装AList
  • k8s提交spark应用消费kafka数据写入elasticsearch7
  • 网速和带宽浅析
  • FL Studio21.2中文高级版数字音乐工作站(DAW)
  • [译]前端离线指南(上)
  • Angular 4.x 动态创建组件
  • php ci框架整合银盛支付
  • python学习笔记 - ThreadLocal
  • React-flux杂记
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • Swift 中的尾递归和蹦床
  • Vue2 SSR 的优化之旅
  • 阿里研究院入选中国企业智库系统影响力榜
  • 构建工具 - 收藏集 - 掘金
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 七牛云假注销小指南
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 写代码的正确姿势
  • 智能合约开发环境搭建及Hello World合约
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 【云吞铺子】性能抖动剖析(二)
  • Java总结 - String - 这篇请使劲喷我
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​什么是bug?bug的源头在哪里?
  • #Linux(Source Insight安装及工程建立)
  • (1)(1.9) MSP (version 4.2)
  • (12)Linux 常见的三种进程状态
  • (算法二)滑动窗口
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .libPaths()设置包加载目录
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .NET中 MVC 工厂模式浅析
  • [145] 二叉树的后序遍历 js
  • [AIGC] 开源流程引擎哪个好,如何选型?
  • [ArcPy百科]第三节: Geometry信息中的空间参考解析
  • [C++]运行时,如何确保一个对象是只读的
  • [CQOI 2010]扑克牌
  • [Docker]十二.Docker consul集群搭建、微服务部署,Consul集群+Swarm集群部署微服务实战
  • [Everyday Mathematics]20150130