【数据结构初阶】顺序表SeqList

描述

顺序表我们可以把它想象成在一个表格里面填数据,并对数据做调整;

那我们的第一个问题是:怎么样在创建出足够的空间呢?

我们可以去堆上申请,用一个指针指向一块空间,如果申请的空间不够,我们可以再realloc申请出来。

我们的第二个问题是:怎么样标记我们用了多少空间呢?

这时我们就需要一个变量来记录我们当前的用到第几个“格子”(即用了多少空间),我们这里用size来表示:

我们的第三个问题是:怎么样知道我们有空间呢?

这时我们就需要一个变量来记录我们“格子”总数(即拥有多少空间),我们这里用capacity来表示:

所以(在.h文件中)我们线性表的结构体描述为:

typedef int SLDataType;typedef struct SeList
{SLDataType* a;int size;int capacity;
}SL;

组织

  1. 初始化
  2. 释放
  3. 尾插
  4. 尾删
  5. 头插
  6. 头删
  7. 指定位置删除
  8. 指定位置插入
  9. 查找指定元素

1.初始化

把我们描述出来的顺序表结构体里的变量初始化

在.h文件中:

因为要对创建出来的结构体里的内容进行修改,所以函数要进行传址调用

在.c文件中:

我们用malloc来开辟空间,同时注意检查malloc;

因为我们刚刚开辟空间,并没有往顺序表里增删查改 所以此时size为0;

而我们的capacity就是在malloc开辟的空间大小。

void SLInit(SL* ps)
{assert(ps->a);ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (ps->a == NULL){perror("malloc fail");return;}ps->size = 0;ps->capacity = INIT_CAPACITY;
}

2.释放

将描述出来的顺序表结构体里的变量逐个进行释放;

在.h 文件中:

在.c文件中:

首先是指针a,需要使用free函数将其释放,还需要注意的是free后,需要将a置空,避免出现野指针

因为size和capacity是临时变量储存在栈上,函数调用结束后会自动释放,我们这里把它改为0就可以了。

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

3.尾插

向顺序表的尾部插入数据;

在.h 文件中:

在.c文件中:

尾插数据时,首先,需要判断capacity(空间)是否足够,如果不够需要扩容,这里我们写个扩容函数:

扩容我们用realloc函数,最后要返回ps至尾插函数判断是否为空;

接着,才能将数据尾插;

最后别忘了调整size的位置;

SL* SLExpand(SL* ps)
{assert(ps->a);if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType)* ps->capacity*2);if (tmp == NULL){perror("realloc fail");return NULL;}ps->capacity *=2;ps->a = tmp;}return ps;
}void SLPushBack(SL* ps,SLDataType x)
{assert(ps->a);//扩容if (ps->size == ps->capacity){SL* ret = SLExpand(ps);if (ret == NULL){return;}}ps->a[ps->size] = x;ps->size++;}

4.尾删

将顺序表的尾部删除;

在.h 文件中:

在.c 文件中:

因为顺序表是从开始连续存储size个数据,不能单独释放那一块区域,所以我们直接将size--就可以了,如果往后插入的话,就直接把数据覆盖;

assert()如果当capacity为空的时候还尾删时会报错,并且终止程序;

void SLPopBack(SL* ps)
{assert(ps->a);ps->size--;
}

5.头插

向顺序表的头部插入数据;

在.h 文件中:

在.c 文件中:

首先,我们得先判断空间是否足够,如果不够就扩容;

第二步:把数据往后移一位,数据从最后一位开始向后移动;

第三步:进行数据头插,别忘了把size的大小改改;

void SLPushFront(SL* ps, SLDataType x)
{assert(ps->a);//扩容if (ps->size == ps->capacity){SL* ret = SLExpand(ps);if (ret == NULL){return;}}//移动数据for (int i = ps->size; i >0 ; i--){ps->a[i] = ps->a[i - 1];}//头插ps->a[0] = x;ps->size++;}

6.头删

将顺序表的头部数据删除;

在.h 文件中:

在.c 文件中:

我们只需要将从第二位数据开始往前移动,把前一位的数据覆盖就可以达到头删的效果;

void SLPopFront(SL* ps)
{assert(ps->a);assert(ps->size > 0);for (int i = 0; i < ps->size; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}

7.指定位置删除

将顺序表的指定位置数据删除;

在.h 文件中:

在.c 文件中:

首先,要先用assert检查一下空间和size的值是否合理;

如果删除的数据是最后一个就直接尾删;

如果如果删除的数据不是最后一个就需要移动数据覆盖,类似于头删;

void SLErase(SL* ps, int pos)
{assert(ps->a);assert(pos >= 0&&pos<ps->size);//如果pos是最后一个数据,尾删if (pos == ps->size - 1){SLPopBack(ps);}else{for (int i = pos; i < ps->size; i++){ps->a[i] = ps->a[i + 1];}ps->size--;}}

8.指定位置插入

将顺序表的指定位置数据插入;

在.h 文件中:

在.c 文件中:

首先,要先用assert检查一下空间和size的值是否合理;

如果删除的数据是最后一个就直接尾插;

如果如果删除的数据不是最后一个就需要移动数据,再插入数据,类似于头插;

void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps->a);assert(pos >= 0 && pos <= ps->size);//判断容量if (ps->size == ps->capacity){SL* ret = SLExpand(ps);if (ret == NULL){return;}}//尾插if (pos == ps->size - 1){SLPushBack(ps,x);}else{for (int i = ps->size; i > pos; i--){ps->a[i] = ps->a[i - 1];}ps->size++;ps->a[pos] = x;}
}

9.查找指定元素

在顺序表中查找指定数据,并输出其下表,和在该表中的个数;

在.h 文件中:

在.c 文件中:

for循环遍历一下顺序表,如果遍历过程中找到了直接打印其下标,并用一个变量记录它出现的此数。

出循环后打印其和在该表中出现的个数。

void SLFindPoint(SL* ps, SLDataType x)
{assert(ps->a);int cnt = 0;for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){cnt++;printf("找到了第%d个,下标为:%d\n",cnt, i);}}if (cnt == 0){printf("抱歉,无该数据\n");}else{printf("共找到%d个数据\n", cnt);}
}

整个程序

.h文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>typedef int SLDataType;
#define INIT_CAPACITY 4typedef struct SeList
{SLDataType* a;int size;int capacity;
}SL;void SLPrint(SL* ps);void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPushBack(SL* ps,SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
void SLErase(SL* ps,int pos);
void SLInsert(SL* ps, int pos, SLDataType x);
void SLFindPoint(SL* ps, SLDataType x);

.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"void SLPrint(SL* ps)
{assert(ps->a);for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}void SLInit(SL* ps)
{assert(ps->a);ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (ps->a == NULL){perror("malloc fail");return;}ps->size = 0;ps->capacity = INIT_CAPACITY;
}void SLDestroy(SL* ps)
{assert(ps->a);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->size = 0;
}SL* SLExpand(SL* ps)
{assert(ps->a);if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType)* ps->capacity*2);if (tmp == NULL){perror("realloc fail");return NULL;}ps->capacity *=2;ps->a = tmp;}return ps;
}void SLPushBack(SL* ps,SLDataType x)
{assert(ps->a);//扩容if (ps->size == ps->capacity){SL* ret = SLExpand(ps);if (ret == NULL){return;}}ps->a[ps->size] = x;ps->size++;}void SLPopBack(SL* ps)
{assert(ps->a);ps->size--;
}void SLPushFront(SL* ps, SLDataType x)
{assert(ps->a);//扩容if (ps->size == ps->capacity){SL* ret = SLExpand(ps);if (ret == NULL){return;}}//移动数据for (int i = ps->size; i >0 ; i--){ps->a[i] = ps->a[i - 1];}//头插ps->a[0] = x;ps->size++;}void SLPopFront(SL* ps)
{assert(ps->a);assert(ps->size > 0);for (int i = 0; i < ps->size; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}void SLErase(SL* ps, int pos)
{assert(ps->a);assert(pos >= 0&&pos<ps->size);//如果pos是最后一个数据,尾删if (pos == ps->size - 1){SLPopBack(ps);}else{for (int i = pos; i < ps->size; i++){ps->a[i] = ps->a[i + 1];}ps->size--;}}void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps->a);assert(pos >= 0 && pos <= ps->size);//判断容量if (ps->size == ps->capacity){SL* ret = SLExpand(ps);if (ret == NULL){return;}}//尾插if (pos == ps->size - 1){SLPushBack(ps,x);}else{for (int i = ps->size; i > pos; i--){ps->a[i] = ps->a[i - 1];}ps->size++;ps->a[pos] = x;}
}void SLFindPoint(SL* ps, SLDataType x)
{assert(ps->a);int cnt = 0;for (int i = 0; i < ps->size; i++){if (ps->a[i] == x){cnt++;printf("找到了第%d个,下标为:%d\n",cnt, i);}}if (cnt == 0){printf("抱歉,无该数据\n");}else{printf("共找到%d个数据\n", cnt);}
}

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

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

相关文章

便捷Benchmark.sh 自动匹配workload(自用)

​ 因为db_bench选项太多&#xff0c;而测试纬度很难做到统一&#xff08;可能一个memtable大小的配置都会导致测试出来的写性能相关的的数据差异很大&#xff09;&#xff0c;所以官方给出了一个benchmark.sh脚本用来对各个workload进行测试。 该脚本能够将db_bench测试结果中…

Halcon WPF 开发学习笔记:HSmartWindowControlWPF正常加载

文章目录 加载问题相关文章彻底解决 加载问题 我们在WPF中使用Halcon的时候&#xff0c;会出现图片被拉伸的问题&#xff0c;需要拖动才可以解决&#xff0c;我网上找了好久&#xff0c;终于找到了如何成功解决这个问题。 相关文章 3.7 Halcon 窗体显示对象消失问题 【halcon】…

uniapp中picker 获取时间组件如何把年月日改成年月日默认时分秒为00:00:00

如图所示&#xff0c;uniapp中picker组件的日期格式为&#xff1a; 但后端要 2023-11-08 00:00:00格式 如何从2023-11-08转化为 2023-11-08 00:00:00&#xff1a;&#x1f447; const date new Date(e.detail.value);//"2023-11-17" date.setHours(0, 0, 0); // 2…

如何判断从本机上传到服务器的文件数据内容是一致的?用md5加密算法!

问题场景 最近在帮导师做横向&#xff0c;我想把整个项目环境放到服务器中&#xff0c;需要把一个很大的数据文件传到服务器&#xff0c;传上去很方便&#xff0c;但是涉及到文件的压缩上传和服务器内解压环节&#xff0c;不是太确定文件在本机和服务器的数据内容是否一致。 解…

解决游戏找不到x3daudio1_7.dll文件的5个方法,快速修复dll问题

在电脑使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“x3daudio1_7.dll丢失”。这个错误通常会导致软件游戏无法正常启动运行。为了解决这个问题&#xff0c;我们需要采取一些措施来修复丢失的文件。本文将详细介绍解决x3daudio1_7.dll丢失的方法…

线索二叉树(存储结构,线索化,寻找前驱/后继)

目录 1.线索二叉树1.中序线索二叉树2.后序线索二叉树3.先序线索二叉树 2.线索二叉树的存储结构3.二叉树的线索化1.中序线索化2.先序线索化3.后序线索化 4.寻找前驱/后继1.中序线索二叉树找后继2.中序线索二叉树找中序前驱3.先序线索二叉树找先序后继4.先序线索二叉树找先序前驱…

城市内涝积水的原因有哪些?万宾科技内涝积水监测仪工作原理

一旦有暴雨预警出现多地便会立即响应&#xff0c;以防城市内涝问题出现。随着人口迁移&#xff0c;越来越多的人口涌入城市之中&#xff0c;为了完善城市基础设施建设&#xff0c;城市应急管理部门对内涝的监测越来越严格&#xff0c;在信息化时代&#xff0c;城市管理也趋向于…

docker更改存储目录原因及方案

为什么一定要将docker的存储目录挂载到其他目录 docker在安装时默认存储目录在/var/lib/docker&#xff0c;而该目录是在系统盘下的。docker安装后&#xff0c;会使用各种各样的镜像&#xff0c;动辄几个G&#xff0c;那么如此多的镜像文件&#xff0c;装着装着系统盘就撑爆了…

景联文科技提供高质量人像采集服务,助力3D虚拟人提升逼真度

人像采集是一种通过特定设备或技术&#xff0c;对人的相貌、身材等特征信息进行收集和处理的过程&#xff0c;可应用于3D虚拟人领域。通过采集大量的人像数据&#xff0c;可以训练和优化人像识别算法&#xff0c;提高其准确性。 人像采集对于提高3D虚拟人的逼真度、个性化定制以…

矩阵的除法

B/A 如果矩阵A可逆&#xff0c;那么 证明&#xff1a; A/AB 如果矩阵A和B都可逆&#xff0c;那么 证明&#xff1a;

Linux nohup后台启动/ 后台启动命令中nohup 、、重定向的使用

文章目录 一、前言二、nohup&#xff08;不挂断&#xff09;简介三、nohup使用3.1、nohup启动3.2、nohup与&&#xff0c;后台运行3.3、nohup与>&#xff0c;日志重定向3.4、nohup后台启动-综合使用(推荐)2>&1 3.5、nohup后台启动(不生成日志) 四、查看进程五、知…

Web前端—CSS高级(定位、高级技巧、CSS修饰属性、综合案例:购物网站轮播图)

版本说明 当前版本号[20231108]。 版本修改说明20231107初版20231108对知识点&#xff08;圆点&#xff09;进行补充 目录 文章目录 版本说明目录day08-CSS高级01-定位相对定位绝对定位定位居中固定定位堆叠层级 z-index定位总结 02-高级技巧CSS精灵案例-京东服务HTML结构CS…