数据结构——lesson2线性表和顺序表

目录

前言

 一、顺序表是什么?

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

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

二、接口实现

1.动态顺序表存储

2.基本增删查改接口

(1)初始化顺序表

(2)顺序表摧毁

(3)检查空间

(4)顺序表打印

(5)顺序表尾插

(6)顺序表尾删

(7)顺序表头插

(8)顺序表头删

(9)顺序表在pos位置插入x

(10)顺序表在pos位置删除x

(11)顺序表查找

3.代码运行结果如下:



前言

在学习顺序表之前我们要了解什么是线性表?

1.线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
2.线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

 一、顺序表是什么?


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

顺序表一般可以分为:

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

//顺序表的静态存储
#define N 7
typedef int SLDataType;//防止数组类型改变时麻烦typedef struct SeqList
{SLDataType arry[N];//定长数组size_t size;//有效数据个数}SeqList;

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

//顺序表的动态存储
typedef struct SeqList
{SLDataType* arry;//指向动态开辟的数组size_t size;//有效数据个数size_t capacity;//容量空间的大小
}SeqList;//空间不够则增容
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致 N 定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用 动态顺序表 ,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

二、接口实现

1.动态顺序表存储

:相较于静态顺序表动态顺序表arry表示的指针数据,不再是定长数组,从而可以使用mallo,realloc函数开辟动态内存空间,此外还增加了capacity变量来记录容量大小

typedef struct SeqList
{SLDataType* arry;//指向动态开辟的数组size_t size;//有效数据个数size_t capacity;//容量空间的大小
}SeqList;//空间不够则增容

①SLDataType:其实是int被typedef的

typedef int SLDataType;//防止数组类型改变时麻烦

②size_t:无符号位的整型

2.基本增删查改接口

(1)初始化顺序表

:(1)asert断言防止传入指针为空;

       (2)使用malloc函数给数组开4个SLDataType(typedef为int,避免修改数据的麻烦)大小的空间;

void SeqListInit(SeqList* psl)//顺序表初始化
{assert(psl);//asert断言防止传入指针为空psl->arry = (SLDataType*)malloc(sizeof(SLDataType) * 4);//给数组开4个SLDataType大小的空间if (psl == NULL){perror("malloc fail");//如果开辟没成功则返回错误return;}psl->size = 0;psl->capacity = 4;
}

(2)顺序表摧毁

:使用动态内存函数(malloc、realloc等函数)后记得要用free释放空间;

void SeqListDestory(SeqList* psl)//顺序表销毁
{assert(psl);//assert断言free(psl->arry);//使用动态内存函数后记得要用free释放空间psl->arry = NULL;//指针置空psl->capacity = 0;psl->size = 0;
}

(3)检查空间

:①如果空间满了使用realloc函数来增加空间;

        ②需要人为的将capacity增加到相应的容量(只是内存容量增加了,我们要将capacity与内存链接需要自己动手);

void CheckCapacity(SeqList* psl)
{assert(psl);//断言if (psl->size == psl->capacity)//判断空间是否满了{SLDataType* tmp = realloc(psl->arry, sizeof(SLDataType) * 2 * (psl->capacity));//增容每次扩展为上一次的2倍if (tmp == NULL)//判断是否开辟成功{perror("realloc fail");return;}psl->arry = tmp;psl->capacity *= 2;//开辟成功指示容量的capacity要相应的增加}
}

(4)顺序表打印

for循环逐一打印即可;

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

(5)顺序表尾插

:①尾插数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

        ②相应元素加进去后,顺序表指向有效数据个数(size)要增加(类似于增加容量时capacity也要增加);

        ③后续等学习了在特定位置(pos)插入相应元素后即可使用SeqListInsert函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为size的地方插入x;

void SeqListPushBack(SeqList* psl, SLDataType x)
{assert(psl);//断言CheckCapacity(psl);//检查容量psl->arry[psl->size] = x;psl->size++;//顺序表个数要相应增加//SeqListInsert(psl,ps->size,x);//在特定位置插入元素x
}

(6)顺序表尾删

:①要先判断顺序表中是否储存了元素,如果没有则没有继续的必要;

        ②因为顺序表是通过数组下标访问,所以只要将最大的下标减一即可,这样就访问不到最后的元素了,可以看成删掉了一个元素;

        ③后续等学习了在特定位置(pos)删除相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为size-1的地方删除;

void SeqListPopBack(SeqList* psl)
{assert(psl);//断言if (psl->size == 0)//判断顺序表是否有元素{return;//没有直接返回}psl->size--;//顺序表个数-1//SeqListErase(ps,ps->size-1);//在顺序表末尾删除元素
}

(7)顺序表头插

:①头插数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

        ②头插数据之前的数据下标要整体+1;顺序表个数也要+1;

        ③后续等学习了在特定位置(pos)插入相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的首端也就是下标为0的地方插入x;

void SeqListPushFront(SeqList* psl, SLDataType x)//顺序表头插
{assert(psl);CheckCapacity(psl);//检查容量for (int i = psl->size-1; i >= 0; i--)//顺序表整体向后移{psl->arry[i + 1] = psl->arry[i];}psl->size++; //顺序表个数+1psl->arry[0] = x;//SeqListInsert(ps,0,x);//在下标为0的位置插入x
}

(8)顺序表头删

:①要先判断顺序表中是否储存了元素,如果没有则没有继续的必要;

        ②删除第一个元素,顺序表下标都要-1;

        ③顺序表元素个数(size)也要-1;

        ④后续等学习了在特定位置(pos)删除相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为0的地方删除;

void SeqListPopFront(SeqList* psl)//顺序表头删
{assert(psl);//断言if (psl->size == 0)//判断是否为空return;for (int i = 1; i < psl->size; i++)//顺序表数据整体都要前移{psl->arry[i - 1] = psl->arry[i];}psl->size--;//顺序表个数-1//SeqListErase(ps,0);//在下标为0位置删除
}

(9)顺序表在pos位置插入x

:①在特定位置插入数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

        ②判断插入下标pos是否合理(要小于size);

        ③插入pos位置的数据,其后的数据下标都要整体+1;

        ④顺序表元素个数(size)要+1;

void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)//在pos位置插入x
{assert(psl);//断言assert(pos <= psl->size);//判断pos是否小于最大的下标CheckCapacity(psl);//检查容量for (int i = psl->size - 1; i >= pos; i--)//下标在pos之后的要整体+1{psl->arry[i + 1] = psl->arry[i];}psl->arry[pos] = x;//将x插入pos位置psl->size++;//顺序表元素个数+1
}

(10)顺序表在pos位置删除x

:①删除元素size要-1;

        ②在pos位置删除元素,pos之后的下标都要-1;

void SeqListErase(SeqList* psl, size_t pos)//在特定位置删除元素
{assert(psl);//断言for (int i = pos + 1; i < psl->size; i++)//pos之后下标-1{psl->arry[i - 1] = psl->arry[i];}psl->size--;//顺序表元素个数-1;
}

(11)顺序表查找

int SeqListFind(SeqList* psl, SLDataType x)//顺序表查找
{assert(psl);//断言if (psl->size == 0)//判断是否为空return -1;for (int i = 0; i < psl->size; i++)//循环逐一查找{if (psl->arry[i] == x){printf("%d\n", i);return i;//找到了返回下标}}printf("没找到\n");return -1
}

3.代码运行结果如下:

以上就是顺序表的所以内容啦,欢迎三连回访,有问题可以后台私信我或者打在评论区哦~ 

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

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

相关文章

深入了解JavaScript混淆工具:jsjiami.v6

JavaScript混淆工具在前端开发中发挥着重要的作用&#xff0c;帮助开发者保护源代码&#xff0c;减少代码被轻易破解的风险。其中&#xff0c;jsjiami.v6 是一款备受开发者关注的混淆工具之一。本文将深入介绍jsjiami.v6的基本原理和使用方法&#xff0c;并通过案例代码演示其效…

网站怎么接入qq互联(vue+springboot前后端)

准备工作 互联的方式有多种&#xff0c;包含了微信&#xff0c;qq,github,gitee等等。 平常自己设计一个网站都要设计一个登录注册的网页给用户去进行登录注册使用。我们可以使用更加加单的方式方便用户去登录注册。不要让用户去自己输入信息&#xff0c;可以通过认证授权这样的…

Java 三大并大特性-可见性介绍(结合代码、分析源码)

目录 ​编辑 一、可见性概念 1.1 概念 二、可见性问题由来 2.1 由来分析 三、可见性代码例子 3.1 代码 3.2 执行结果 四、Java 中保证可见性的手段 4.1 volatile 4.1.1 优化代码 4.1.2 测试结果 4.1.3 volatile原理分析 4.1.3.1 查看字节码 4.1.3.2 hotspot 层面…

netstat命令

netstat 是一个计算机网络命令行工具&#xff0c;用于显示网络连接、路由表和网络接口等网络相关信息。netstat 命令可以在各种操作系统上使用&#xff0c;包括 Windows、Linux 和 macOS 等。 在使用 netstat 命令时&#xff0c;可以提供不同的选项来显示不同类型的网络信息。…

(AtCoder Beginner Contest 334) --- F - Christmas Present 2 -- 题解

F - Christmas Present 2 F - Christmas Present 2 题目大意&#xff1a; 思路解析&#xff1a; 因为他是顺序前往每个孩子的家&#xff0c;前往时必须要带一个礼物&#xff0c;并且最多只能带k个礼物&#xff0c;所以它每次前往最多k个孩子之后就要回到初始点重新出发。…

哈工大计算机网络考试经验及资源分享

如果你觉得资源对你有用&#xff0c;在收藏的同时不要忘记点个赞(●◡●)&#xff0c;你的支持&#xff0c;是我坚持创作的最佳动力。 哈工大计算机网络是一门重要的课程&#xff0c;对于学习计算机网络知识非常有帮助。在学习这门课程时&#xff0c;我选择了中科大zq老师的网…

二叉树的垂直遍历

1.题目 这道题是2024-2-13的签到题&#xff0c;题目难度为困难。 考察的知识点是DFS算法和自定义排序。 题目链接&#xff1a;二叉树的垂直遍历 给你二叉树的根结点 root &#xff0c;请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言&#xff…

VTK 正交投影 透视投影

1.VTK默认透视投影&#xff08;近大远小&#xff09;&#xff1b; 1.调用vtkCamera的ParallelProjectionOn函数开启 2.通过vtkCamera的SetParallelScale缩放 3.通过vtkCamera的SetClippingRange设置前后裁剪平面 2.正交投影&#xff08;平行投影&#xff0c;远近一样&#xf…

openGauss学习笔记-218 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-I/O

文章目录 openGauss学习笔记-218 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-I/O218.1 查看I/O状况218.2 性能参数分析 openGauss学习笔记-218 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-I/O 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&#xf…

LeetCode:83和82.删除排序链表中的重复元素I,II

这两题算是链表的基础题&#xff0c;就遍历删除没啥特点&#xff0c; 83甚至不需要考虑第一个结点的特殊情况&#xff0c;属实是名副其实的easy了 LeetCode&#xff1a;21.合并两个有序链表之第一次的特殊情况-CSDN博客 83. 删除排序链表中的重复元素 - 力扣&#xff08;Lee…

第三百二十二回

文章目录 1. 概念介绍2. 使用方法2.1 基本用法2.2 缓冲原理 3. 示例代码4. 内容总结 我们在上一章回中介绍了"FadeInImage组件"相关的内容&#xff0c;本章回中将介绍CachedNetworkImage组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…

渗透测试练习题解析 3(CTF web)

1、[网鼎杯 2020 朱雀组]phpweb 1 考点&#xff1a;反序列化漏洞利用 进入靶场&#xff0c;查看检查信息&#xff0c;发现存在两个参数 func 和 p 查看页面源代码 payload&#xff1a;funcfile_get_contents&pphp://filter/resourceindex.php 整理后&#xff0c;就是 PHP 代…