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

【数据结构】实现顺序表

目录

    • 一.介绍顺序表
    • 二.实现顺序表
      • 1.创建多文件
      • 2.顺序表的存储方式
      • 3.函数的声明
      • 4.初始化顺序表
      • 5.清理顺序表
      • 6.打印顺序表
      • 7.扩容
      • 8.尾插
      • 8.尾删
      • 9.头插
      • 10.头删
      • 11.查找
      • 12.修改
      • 13.在pos位置插入
      • 13.在pos位置删除
    • 三.全部代码
      • 1.SeqList.h
      • 2.SeqList.c
      • 3.Test.c

一.介绍顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储
在这里插入图片描述
顺序表与通讯录类似,可以完成增删查改等功能。在此基础上,还可以实现头插、头删、尾插、尾删以及某位置的插入和删除

二.实现顺序表

1.创建多文件

用多文件的好处在通讯录一文中已经说明过了,所以这里直接进入正题:

SeqList.h——函数和类型的声明
SeqList.c——函数的实现
Test.c——测试顺序表

注:为了方便测试,所以没有Test.c没有菜单,直接进行测试

2.顺序表的存储方式

顺序表可以采用两种存储方式:静态存储和动态存储
本文使用的是动态存储,因为静态存储只适用于确定知道需要存多少数据的场景,空间开多了浪费,开少了不够用。现实中基本都是使用动态顺序表,根据需要动态的分配空间大小。

typedef int SLDataType;//重定义方便类型的修改
typedef struct SeqList
{SLDataType* a;//指向动态开辟的数组int size;//数据的个数int capacity;//容量的大小
}SL;

3.函数的声明

该顺序表要实现的函数有:
1.初始化顺序表
2.清理顺序表
3.打印顺序表
4.扩容
5.尾插
6.尾删
7.头插
8.头删
9.查找
10.修改
11.在pos位置插入
12.在pos位置删除

//初始化
void SLInit(SL* ps);
//清理
void SLDestroy(SL* ps);
//打印
void SLPrint(SL* ps);
//扩容
void SLCapacity(SL* ps);
//尾插
void SLPushBack(SL* ps, SLDataType x);
//尾删
void SLPopBack(SL* ps);
//头插
void SLPushFront(SL* ps, SLDataType x);
//头删
void SLPopFront(SL* ps);
//查找
void SLFind(SL* ps, SLDataType x);
//修改
void SLModify(SL* ps, int pos, SLDataType x);
//在pos位置插入
void SLInsert(SL* ps, int pos, SLDataType x);
//在pos位置删除
void SLErase(SL* ps, int pos);

4.初始化顺序表

刚开始要对传过来的指针进行断言,防止为空(后面的也是)
使用malloc函数为数组开辟一块空间(容量大小自己定),数据个数初始化为0

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

5.清理顺序表

程序结束前,要对内存进行清理,因为使用了动态开辟函数,所以必须对使用的空间进行释放,防止内存泄漏

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

6.打印顺序表

因为顺序表是连续的空间,所以打印顺序表的数据用for循环遍历出来就可以了

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

7.扩容

当顺序表的数据满了(等于刚开始开辟的空间大小),就要进行扩容。使用realloc函数,可以对容量进行修改。

void SLCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){SLDataType* ptr = (SLDataType*)realloc(ps->a, 2 * ps->capacity * sizeof(SLDataType));if (ptr == NULL){perror("realloc fail");exit(-1);}else{ps->a = ptr;ps->capacity *= 2;}}
}

8.尾插

进入尾插这个函数,首先要对检查容量是否已满,满了就扩容。
size是数据个数,数组a[ps->size]是下一个数据的下标,尾插一个数把这个数赋给a[ps->size]就行了,然后size++
在这里插入图片描述

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

8.尾删

将最后一个元素置为0,然后size减1

注意:当size为0时就不能再减了,所以对size的范围要断言

在这里插入图片描述

void SLPopBack(SL* ps)
{assert(ps);assert(ps->size > 0);ps->a[ps->size - 1] = 0;ps->size--;
}

9.头插

头插数据,先要检查容量;定义一个变量end,指向的是最后一个元素的下一个位置,然后利用while循环,end的范围>=0(把原来的首元素挪动才能头插),将最后一个元素放进它的下个位置,循环一次end减1,依次将前一个元素置到后一个元素的地址去,直到将首元素的位置变成空的状态,然后头插,size加1
在这里插入图片描述

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

10.头删

定义一个变量begin等于0,指向首元素。用while循环,将后一个元素覆盖前一个元素,每次循环begin加1,直到最后一个元素向前覆盖完就结束,为头的元素就删除了,然后size减1

注意:当size为0时就不能再减了,所以对size的范围要断言

在这里插入图片描述

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

11.查找

用for循环遍历顺序表,有与x相同的数就找到了,否则没找到

void SLFind(SL* ps, SLDataType x)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){if (ps->a[i] == x){printf("找到了\n");return;}}printf("没找到\n");
}

12.修改

pos的值经过断言如果是在范围内就直接将pos位置的值修改为x,否则报错

void SLModify(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->a[pos] = x;
}

13.在pos位置插入

首先对pos的值进行断言,确定其是否在范围内。插入数值,要考虑容量是否已满,所以要检查容量。接下来与头插类似,把pos位置的数据和后面的数据往后挪动,然后在pos位置插入x,size加1

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

13.在pos位置删除

与头删类似,直到最后一个元素向前覆盖完就结束

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

三.全部代码

1.SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;//重定义方便类型的修改
typedef struct SeqList
{SLDataType* a;//指向动态开辟的数组int size;//数据的个数int capacity;//容量的大小
}SL;
//初始化
void SLInit(SL* ps);
//清理
void SLDestroy(SL* ps);
//打印
void SLPrint(SL* ps);
//扩容
void SLCapacity(SL* ps);
//尾插
void SLPushBack(SL* ps, SLDataType x);
//尾删
void SLPopBack(SL* ps);
//头插
void SLPushFront(SL* ps, SLDataType x);
//头删
void SLPopFront(SL* ps);
//查找
void SLFind(SL* ps, SLDataType x);
//修改
void SLModify(SL* ps, int pos, SLDataType x);
//在pos位置插入
void SLInsert(SL* ps, int pos, SLDataType x);
//在pos位置删除
void SLErase(SL* ps, int pos);

2.SeqList.c

#include "SeqList.h"
//初始化
void SLInit(SL* ps)
{assert(ps);ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);if (ps->a == NULL){perror("malloc fail");exit(-1);}ps->size = 0;ps->capacity = 4;
}
//清理
void SLDestroy(SL* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->size = 0;
}
//打印
void SLPrint(SL* ps)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}
//扩容
void SLCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){SLDataType* ptr = (SLDataType*)realloc(ps->a, 2 * ps->capacity * sizeof(SLDataType));if (ptr == NULL){perror("realloc fail");exit(-1);}else{ps->a = ptr;ps->capacity *= 2;}}
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);SLCapacity(ps);ps->a[ps->size] = x;ps->size++;
}
//尾删
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size > 0);ps->a[ps->size - 1] = 0;ps->size--;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCapacity(ps);int end = ps->size;while (end >= 0){ps->a[end] = ps->a[end - 1];end--;}ps->a[0] = x;ps->size++;
}
//头删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size > 0);int begin = 0;while (begin < ps->size){ps->a[begin] = ps->a[begin + 1];begin++;}ps->size--;
}
//查找
void SLFind(SL* ps, SLDataType x)
{assert(ps);int i = 0;for (i = 0; i < ps->size; i++){if (ps->a[i] == x){printf("找到了\n");return;}}printf("没找到\n");
}
//修改
void SLModify(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->a[pos] = x;
}
//在pos位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);SLCapacity(ps);int end = ps->size;while (end >= pos){ps->a[end] = ps->a[end - 1];end--;}ps->a[pos] = x;ps->size++;
}
//在pos位置删除
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int begin = pos;while (begin < ps->size){ps->a[begin] = ps->a[begin + 1];begin++;}ps->size--;
}

3.Test.c

#include "SeqList.h"
void test()
{SL s1;SLInit(&s1);//初始化SLPushBack(&s1, 1);SLPushBack(&s1, 2);SLPushBack(&s1, 3);SLPushBack(&s1, 4);SLPushBack(&s1, 5);//测试尾插SLPrint(&s1);SLPopBack(&s1);SLPopBack(&s1);//测试尾删SLPrint(&s1);SLPushFront(&s1, 10);SLPushFront(&s1, 20);SLPushFront(&s1, 30);SLPushFront(&s1, 40);//测试头插SLPrint(&s1);SLPopFront(&s1);SLPopFront(&s1);//测试头删SLPrint(&s1);SLFind(&s1, 100);//测试查找SLModify(&s1, 2, 99);//测试修改SLPrint(&s1);SLInsert(&s1, 3, 77);//测试pos位置插入SLPrint(&s1);SLErase(&s1, 1);//测试pos位置删除SLPrint(&s1);SLDestroy(&s1);}
int main()
{test();return 0;
}

~ ~
在这里插入图片描述
感谢观看

相关文章:

【数据结构】实现顺序表

目录 一.介绍顺序表二.实现顺序表1.创建多文件2.顺序表的存储方式3.函数的声明4.初始化顺序表5.清理顺序表6.打印顺序表7.扩容8.尾插8.尾删9.头插10.头删11.查找12.修改13.在pos位置插入13.在pos位置删除 三.全部代码1.SeqList.h2.SeqList.c3.Test.c 一.介绍顺序表 顺序表是用…...

【嵌入式环境下linux内核及驱动学习笔记-(19)LCD驱动框架2-FrameBuffer】

目录 1、 Frmebuffer(帧缓冲&#xff09;操作介绍1.1 显示设备的抽象1.2 内存映像1.3 输出画面数据1.4 用户态下操作屏显1.4.1 用文件I / O 操作屏显1.4.2 mmap() 函数1.4.3 ioctl()函数1.4.5 用命令操作屏1.4.6 测试程序 2、Framebuffer总体框架2.1 框架要点2.2 fbmem.c分析2.…...

自己动手写数据库系统:实现一个小型SQL解释器(中)

我们接上节内容继续完成SQL解释器的代码解析工作。下面我们实现对update语句的解析&#xff0c;其语法如下&#xff1a; UpdateCmd -> INSERT | DELETE | MODIFY | CREATE Create -> CreateTable | CreateView | CreateIndex Insert -> INSERT INTO ID LEFT_PARAS Fie…...

HTML 与 XHTML 二者有什么区别

HTML 与 XHTML 二者有什么区别&#xff0c;你觉得应该使用哪一个并说出理由。 HTML 与 XHTML 之间的差别&#xff0c;主要分为功能上的差别和书写习惯的差别两方面。 关于功能上的差别&#xff0c;主要是 XHTML 可兼容各大浏览器、手机以及 PDA&#xff0c;并且浏览器也能快速正…...

fiddler抓包问题记录,支持https、解决 tunnel to 443

fiddler下载安装步骤及基本配置 fiddler抓包教程&#xff0c;如何抓取HTTPS请求&#xff0c;详细教程 可能遇到的问题及解决方案 1. 不能正常访问页面&#xff08;所有https都无法访问&#xff09; 解决方案&#xff1a;查看下面配置是否正确 Rules-customization 找到 OnB…...

Kubesphere中DevOps流水线无法部署/部署失败

摘要 总算能让devops运行以后&#xff0c;流水线却卡在了deploy这一步。碰到了两个比较大的问题&#xff0c;一个是无法使用k8sp自带的kubeconfig认证去部署&#xff1b;一个是部署好了以后但是没有办法解析镜像名。 版本信息 k8s&#xff1a;v1.21.5 k8sp&#xff1a;v3.3.…...

使用Nginx解决跨域问题

前言&#xff1a; 项目是公司的老项目&#xff0c;只有部署在服务器上的时候&#xff0c;项目才可以正常运行&#xff08;接口是通的&#xff09;&#xff1b;现在需求&#xff1a;在现有的项目代码上进行修改&#xff0c;请求接口是第三方给的。接口是正常的&#xff0c;通过A…...

在 OpenCV 中使用深度学习进行年龄检测-附源码

文末附完整源码和模型文件下载链接 在本教程中,我们将了解使用 OpenCV 创建年龄预测器和性别分类器项目的整个过程。 年龄检测 我们的目标是创建一个程序,使用图像来预测人的性别和年龄。但预测年龄可能并不像你想象的那么简单,为什么呢?您可能会认为年龄预测是一个回归问…...

【BASH】回顾与知识点梳理(三十一)

【BASH】回顾与知识点梳理 三十一 三十一. 进程的管理31.1 给进程发送讯号kill -signal PIDlinux系统后台常驻进程killall -signal 指令名称 31.2 关于进程的执行顺序Priority 与 Nice 值nice &#xff1a;新执行的指令即给予新的 nice 值renice &#xff1a;已存在进程的 nice…...

Linux 终端命令之文件浏览(3) less

Linux 文件浏览命令 cat, more, less, head, tail&#xff0c;此五个文件浏览类的命令皆为外部命令。 hannHannYang:~$ which cat /usr/bin/cat hannHannYang:~$ which more /usr/bin/more hannHannYang:~$ which less /usr/bin/less hannHannYang:~$ which head /usr/bin/he…...

【精通性能优化:解锁JMH微基准测试】一基本用法

文章目录 1. 什么是JMH1.1 用JMH进行微基准测试1. JmhExample01.java2. 程序输出JmhExample01.java 2.2 JMH的基本用法2.1 Benchmark标记基准测试方法2.2 Warmup以及Measurement1. 设置全局的Warmup和Measurement&#xff08;一&#xff09;2. 设置全局的Warmup和Measurement&a…...

.Net程序调试时接受外部命令行参数方式

1.对项目右键&#xff0c;属性 2.在调试中打开常规&#xff0c;打开调试启动配置文件UI 3.输入需要的命令行参数...

Mariadb高可用MHA (四十二)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 1.1 概念 1.2 组成 1.3 特点 1.4 工作原理 二、构建MHA 2.1 ssh免密登录 2.2 主从复制 2.3 MHA安装 2.3.1所有节点安装perl环境 2.3..2 node 2.3.…...

Vue3 setup中使用$refs

在 Vue 3 中的 Composition API 中&#xff0c;$refs 并不直接可用于 setup 函数。这是因为 $refs 是 Vue 2 的实例属性&#xff0c;而在 Vue 3 中&#xff0c;setup 函数是与模板实例分离的&#xff0c;不再使用实例属性。 实际工作中确实有需求&#xff0c;在setup 函数使用…...

什么是React的上下文(Context)?如何使用和传递上下文信息?

1、什么是React的上下文(Context)&#xff1f;如何使用和传递上下文信息&#xff1f; React上下文(Context)是React提供的一种功能&#xff0c;允许你在组件之间传递数据和状态。通过使用上下文&#xff0c;你无需通过props一层一层地传递数据&#xff0c;从而减少了代码的复杂…...

CentOS Linux 78安全基线检查

阿里云标准-CentOS Linux 7/8安全基线检查 检查项类别描述加固建议等级密码复杂度检查身份鉴别检查密码长度和密码是否使用多种字符类型编辑/etc/security/pwquality.conf&#xff0c;把minlen(密码最小长度)设置为8-32位&#xff0c;把minclass(至少包含小写字母、大写字母、数…...

Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断】

Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断】 一、分布式系统遇到的问题1、服务挂掉的一些原因 二、解决方案三、Sentinel&#xff1a;分布式系统的流量防卫兵1、Sentinel是什么2、Sentinel和Hystrix对比3、Sentinel快速开发4、通过注解的方式来控流5、启动Sen…...

Kubernetes 企业级高可用部署

目录 1、Kubernetes高可用项目介绍 2、项目架构设计 2.1、项目主机信息 2.2、项目架构图 2.3、项目实施思路 3、项目实施过程 3.1、系统初始化 3.2、配置部署keepalived服务 3.3、配置部署haproxy服务 3.4、配置部署Docker服务 3.5、部署kubelet kubeadm kubectl工具…...

8.1 C++ STL 变易拷贝算法

C STL中的变易算法&#xff08;Modifying Algorithms&#xff09;是指那些能够修改容器内容的算法&#xff0c;主要用于修改容器中的数据&#xff0c;例如插入、删除、替换等操作。这些算法同样定义在头文件 <algorithm> 中&#xff0c;它们允许在容器之间进行元素的复制…...

攻击LNMP架构Web应用

环境配置(centos7) 1.php56 php56-fpm //配置epel yum install epel-release rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm//安装php56&#xff0c;php56-fpm及其依赖 yum --enablereporemi install php56-php yum --enablereporemi install php…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...