顺序表详解(接口详解)

顺序表(接口详解)🦖

  • 1.线性表
  • 2.顺序表
    • 2.1 概念及结构
  • 3.接口的实现
    • 3.1 定义SeqList
    • 3.2 初始化
    • 3.3 销毁
    • 3.4 打印
    • 3.5 扩容
    • 3.6 数据插入
      • 1.头插
      • 2.尾插
      • 3.下标插入
    • 3.7 数据删除
      • 1.头删
      • 2.尾删
      • 3.下表删除
    • 3.8 查询数据
    • 3.9 数据修改
  • 4.顺序表存在的部分问题

1.线性表

线性表*(linear list)*是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

在这里插入图片描述

2.顺序表

2.1 概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素
    在这里插入图片描述

  2. 动态顺序表:使用动态开辟的数组存储。
    在这里插入图片描述

3.接口的实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

typedef int SLDataType;
#define INIT_CAPACITY 2
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//定义SeqList :
typedef struct
{SLDataType* a;int size;int capacity;
}SeqList;
//初始化SeqList
void SeqListInit(SeqList* pa);
//销毁SeqList
void SeqListDestory(SeqList* pa);
//打印SeqList
void SeqListPrint(SeqList* pa);
//扩容
void SeqCheckCapacity(SeqList* pa);
//头插
void SLPushFront(SeqList* pa, SLDataType x);
//尾插
void SLPushBack(SeqList* pa, SLDataType x);
//任意位置插入
void SLInsert(SeqList* pa, int pos, SLDataType x);
//头删
void SLPopFront(SeqList* pa);
//尾删
void SLPopBack(SeqList* pa);
//任意位置删除
void SLErase(SeqList* pa);
//查找数据
int SeqListFind(SeqList* pa, SLDataType x);
//修改数据
void SeqListModify(SeqList* pa, int pos, SLDataType x);

3.1 定义SeqList

定义SeqList这里我们是采用结构体来定义,其中a表示的是动态空间首地址、size表示当前存储数据的多少、capacity表示当前开辟空间的大小(容量)。

typedef struct
{SLDataType* a;int size;int capacity;
}SeqList;

3.2 初始化

初始化:a用malloc开辟动态空间,其余设置初始值。

void SeqListInit(SeqList* pa)
{pa->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (pa->a == NULL){perror("malloc error!!");return;}pa->size = 0;pa->capacity = INIT_CAPACITY;
}
//两个便捷操作:
typedef int SLDataType;
#define INIT_CAPACITY 2

两个便捷操作:

  • 1.数据类型默认用SLDataType替代,方便后续数据更改。
  • 2.定义初始化值INIT_CAPACITY,注意define不需要分号(;),不然会有不小麻烦

3.3 销毁

销毁开辟的内存空间,防止内存泄露(实际上是归还访问权限)

void SeqListDestory(SeqList* pa)
{free(pa->a);pa->a = NULL;pa->capacity = pa->size = 0;//从左向右:size赋值0,然后再把size赋值给capacity,size值为0;
}

3.4 打印

//SeqList 打印
void SeqListPrint(SeqList* pa)
{assert(pa);for (int i = 0; i < pa->size; i++){printf("%d ", pa->a[i]);}printf("\n");
}

3.5 扩容

当我们不断添加数据,总会超出默认容量,所以我们就需要扩容,采用realloc函数来对malloc申请的空间进行扩容,但值得注意的是这里要考虑原地扩容与异地扩容,我们最好在后面添加一句代码pa->a = tmp;//原地扩容与异地扩容问题

void SeqCheckCapacity(SeqList* pa)
{assert(pa);if (pa->size == pa->capacity){SLDataType* tmp = (SLDataType*)realloc(pa->a, pa->capacity * sizeof(SLDataType) * 2);if (tmp == NULL){perror("realloc error");}pa->a = tmp;//原地扩容与异地扩容问题pa->capacity = 2 * pa->capacity;}
}

3.6 数据插入

1.头插

这里的头插其实就是采用覆盖,依次从后往前覆盖,每次后一个数据被前一个数据覆盖,最后在将所需插入的值覆盖第一个位置。

void SLPushFront(SeqList* pa, SLDataType x)
{assert(pa);SeqCheckCapacity(pa);int i = pa->size;while (i){pa->a[i] = pa->a[i - 1];i--;}pa->a[i] = x;pa->size++;
}

2.尾插

尾插更简单,增加访问个数,直接插入。

void SLPushBack(SeqList* pa, SLDataType x)
{assert(pa);SeqCheckCapacity(pa);pa->a[pa->size] = x;pa->size++;//pa->a[pa->size++]=x;
}

3.下标插入

根据下标插入,原理其实和头插相近,可以简单的看成初始位置为pos的头插。

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

学会了下标插入,头插和尾插也可以直接调用下表插入!

3.7 数据删除

1.头删

这里原理其实和前面头插差不多,只是整体空间缩小,所以是从前往后覆盖,用后一个数据覆盖前一个数据,然后再缩小访问空间(指size大小,而并非实际容量)。

void SLPopFront(SeqList* pa)
{assert(pa);assert(pa->size > 0);int start = 0;while (start<pa->size-1){pa->a[start] = pa->a[start+1];start++;}pa->size--;
}

2.尾删

直接收回访问空间即可

void SLPopBack(SeqList* pa)
{assert(pa->size > 0);pa->size--;
}

3.下表删除

同下标插入,将pos位置当做起始位置,采取头删操作。

void SLErase(SeqList* pa,int pos)
{assert(pa);assert(pos >= 0 && pos <= pa->size);int begin = pos;while (begin<pa->size-1){pa->a[begin] = pa->a[begin + 1];begin++;}pa->size--;
}
  • 同样这里的头删和尾删都可以用下标删除替代

3.8 查询数据

很简单,遍历访问,找到数据返回下标,未找到数据,则返回-1;

int SeqListFind(SeqList* pa, SLDataType x)
{assert(pa);for (int i = 0; i < pa->size; i++){if (pa->a[i] == x){return i;}}return -1;
}

3.9 数据修改

直接修改即可很简单

void SeqListModify(SeqList* pa, int pos, SLDataType x)
{assert(pa);assert(0 <= pos && pos <= pa->size);pa->a[pos] = x;
}

4.顺序表存在的部分问题

我们可以很容易看出,顺序表在头删与头插部分的空间复杂度比较高,假如插入或删除n个数据,空间复杂度都为O(N^2),所以比较复杂,这是顺序表的劣势,这一点将会在后续的链表得到解决,可以插个眼,关注一下!码字不易,谢谢支持!

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

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

相关文章

工厂设计模式

github&#xff1a;GitHub - QiuliangLee/pattern: 设计模式 概念 根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式&#xff0c;根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。 简单工厂模式、工厂方法模式和抽象工厂模式有何区别&#xff1f; - 知…

【SpringCloudAlibaba】Seata分布式事务使用

文章目录 分布式事务问题示例Seata概述、官网一个典型的分布式事务过程处理过程全局GlobalTransactional分布式交易解决方案流程图 Seata安装下载修改conf目录下的application.yml配置文件dashboard demo 分布式事务问题示例 单体应用被拆分成微服务应用&#xff0c;原来的三个…

【微信小程序开发】一文学会使用视图组件进行界面设计

引言 在小程序开发中&#xff0c;界面设计是非常重要的一环。本文将介绍如何学习使用小程序的视图组件进行界面设计&#xff0c;并提供代码示例。 文章目录 引言1. 小程序视图组件简介2. 视图组件的使用方法2.1. 组件的引入2.2. 组件的使用2.3. 组件的事件绑定2.4. 组件的样式设…

微火资讯快报:共享wifi项目怎么样?

共享WiFi项目一直以来都是一个热门的创业方向&#xff0c;它通过将公共场所的WiFi热点转换成二维码&#xff0c;使用户扫码就可轻松地连接并使用网络&#xff0c;而商家也可以通过该平台实现广告宣传、营销推广等功能。下面就让我们来详细了解一下共享WiFi项目的各个方面。 市场…

推荐10个AI人工智能技术网站(一键收藏,应有尽有)

1、Mental AI MentalAI&#xff08;https://ai.ciyundata.com/&#xff09;是一种基于文心大模型的知识增强大语言模型&#xff0c;专注于自然语言处理&#xff08;NLP&#xff09;领域的技术研发。它具备强大的语义理解和生成能力&#xff0c;能够处理各种复杂的自然语言任务。…

算法通关村第十九关:白银挑战-动态规划高频问题

白银挑战-动态规划高频问题 1. 最少硬币数 LeetCode 322 https://leetcode.cn/problems/coin-change/description/ 思路分析 尝试用回溯来实现 假如coins[2,5,7]&#xff0c;amount27&#xff0c;求解过程中&#xff0c;每个位置都可以从[2,5,7]中选择&#xff0c;因此可以…

iwebsec靶场 文件包含漏洞通关笔记3-session文件包含

目录 1.打开靶场 2.源码分析 &#xff08;1&#xff09;session文件包含漏洞的的工作原理 &#xff08;2&#xff09;sessionstart()做了哪些初始化工作 3.获取session文件位置 4.向session写入webshell 5.访问webshell 1.打开靶场 iwebsec 靶场漏洞库iwebsechttp://iw…

【Blender】Blender入门学习

目录 0 参考视频教程0.1 Blender理论知识0.2 Blender上手实践0.3 FBX模型导入Unity 1 Blender的窗口介绍1.1 主界面1.2 模型编辑窗口 2 Blender的基本操作2.1 3D视图的平移2.2 3D视图的旋转2.3 3D视图的缩放2.4 修改快捷键2.5 使物体围绕选择的物体旋转2.6 四视图的查看2.7 局部…

遥遥领先的内存函数

目录 ​编辑 函数介绍 1.1 strlen 1.2 strcpy 1.3 strcmp 1.4 strcat 1.5 strstr 2.1 memcpy 2.2 memmove 2.3 memcmp 函数实现 1.1 strlen 1.2 strcpy 1.3 strcmp 1.4 strcat 1.5 strstr 2.1 memcpy 2.3 memcmp 函数介绍 1.1 strlen size_t strlen ( const char *…

猫头虎的技术笔记:Spring Boot启动报错解决方案

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

4.3.3 【MySQL】Redundant行格式

现在我们把表demo 的行格式修改为 Redundant &#xff1a; 为了方便大家理解和节省篇幅&#xff0c;我们直接把表 demo 在Redundant 行格式下的两条记录的真实存储数据提供出来&#xff0c;之后我们着重分析两种行格式的不同即可。 下边我们从各个方面看一下 Redundant 行格式有…

市场开始复苏,三星传调涨内存芯片高达20% | 百能云芯

随着行动内存芯片市场迹象显示出复苏迹象&#xff0c;并且最早在第四季度供不应求&#xff0c;三星电子已宣布将提高动态随机存取存储器&#xff08;DRAM&#xff09;和NAND闪存芯片的价格&#xff0c;幅度达到10%~20%。 韩国经济日报报道&#xff0c;知情人士透露&#xff0c;…