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

顺序表——“数据结构与算法”

各位CSDN的uu们你们好呀,今天小雅兰的内容是数据结构与算法里面的顺序表啦,在我看来,数据结构总体上是一个抽象的东西,关键还是要多写代码,下面,就让我们进入顺序表的世界吧


线性表

顺序表


线性表

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

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


 顺序表

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

顺序表就是数组,但是在数组的基础上,它还要求数据是从头开始连续存储的,不能跳跃间隔 

顺序表一般可以分为:

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

#define _CRT_SECURE_NO_WARNINGS 1
#define N 7
#include"SeqList.h"
typedef int SLDateType;
typedef struct SeqList
{SLDateType arr[N];//定长数组size_t size;//表示数组中存储了多少数据
}SL;

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

#define _CRT_SECURE_NO_WARNINGS 1
#define N 7
#include"SeqList.h"
typedef int SLDateType;
typedef struct SeqList
{SLDateType* arr;//指向动态开辟的数组size_t size;//表示数组中存储了多少数据size_t capicity;//数组实际能存储数据的空间容量是多大
}SL;

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

在这里,所有函数命名风格都是跟着STL走的,方便小雅兰日后的学习!!! 


顺序表的初始化:

void SeqListInit(SL* ps)//顺序表的初始化
{ps->arr = NULL;ps->size = ps->capacity = 0;
}

注意:在这里,不可以使用传值调用的方式,只能使用传址调用的方式

void SeqListInit(SL ps)//顺序表的初始化
{ps.arr = NULL;ps.size = ps.capacity = 0;
}

万万不能使用这样的方式初始化,因为:在函数传参的时候,形参是实参的一份临时拷贝,对形参的修改并不会影响实参

 顺序表的打印:

void SeqListPrint(SL* ps)//顺序表的打印
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}

扩容:

void SeqListCheckCapacity(SL* ps)//检查空间,如果满了,进行扩容
{//如果没有空间或者空间不足,那么我们就扩容if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDateType* tmp = (SLDateType*)realloc(ps->arr, newcapacity * sizeof(SLDateType));if (tmp == NULL){printf("realloc fail!\n");exit(-1);}ps->arr = tmp;ps->capacity = newcapacity;}
}

顺序表销毁:

void SeqListDestroy(SL* ps)//顺序表销毁
{free(ps->arr);ps->arr = NULL;ps->capacity = ps->size = 0;
}

尾插:

void SeqListPushBack(SL* ps, SLDateType x)//尾插
{SeqListCheckCapacity(ps);ps->arr[ps->size] = x;ps->size++;
}

尾删:

void SeqListPopBack(SL* ps)//尾删
{assert(ps->size > 0);ps->size--;
}

 头插:

void SeqListPushFront(SL* ps, SLDateType x)//头插
{SeqListCheckCapacity(ps);//挪动数据int end = ps->size - 1;while (end >= 0){ps->arr[end + 1] = ps->arr[end];end--;}ps->arr[0] = x;ps->size++;
}

头删:

void SeqListPopFront(SL* ps)//头删
{assert(ps->size > 0);//挪动数据int begin = 0;while (begin < ps->size-1){ps->arr[begin] = ps->arr[begin+1];++begin;}ps->size--;
}
另一种写法:
void SeqListPopFront(SL* ps)//头删
{assert(ps->size > 0);//挪动数据int begin = 1;while (begin < ps->size){ps->arr[begin - 1] = ps->arr[begin];++begin;}ps->size--;
}

 顺序表查找:

//顺序表查找
//找到了返回x位置的下标,没有找到返回-1
int SeqListFind(SL* ps, SLDateType x)
{int i = 0;for (i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}

 指定pos下标位置插入:

// 顺序表指定pos下标位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDateType x)
{温柔的写法//if (pos > ps->size || pos < 0)//{//	printf("pos invalid!\n");//}//粗暴的写法assert(pos <= ps->size || pos >= 0);SeqListCheckCapacity(ps);//挪动数据int end = ps->size - 1;while (end >= pos){ps->arr[end + 1] = ps->arr[end];end--;}ps->arr[pos] = x;ps->size++;
}

 然后,写出了这个函数的功能之后,我们发现:可以对之前写的头插和尾插搞一些事情,下面,我们开始搞事情!!!

头插和尾插:

void SeqListPushBack(SL* ps, SLDateType x)//尾插
{SeqListInsert(ps, ps->size, x);
}
void SeqListPushFront(SL* ps, SLDateType x)//头插
{SeqListInsert(ps, 0, x);
}

 删除pos位置的数据:

//顺序表删除pos位置的数据
void SeqListErase(SL* ps, size_t pos)
{assert(pos < ps->size || pos >= 0);int begin = pos + 1;while (begin < ps->size){ps->arr[begin - 1] = ps->arr[begin];++begin;}ps->size--;
}

写出这个函数的功能之后,我们又可以搞事情啦!!!

头删和尾删:

void SeqListPopBack(SL* ps)//尾删
{SeqListErase(ps, 0);
}
void SeqListPopFront(SL* ps)//头删
{SeqListErase(ps, ps->size - 1);
}

菜单:

void menu()
{printf("#############################################\n");printf("\n");printf("###################1.头插#####################\n");printf("\n");printf("###################2.头删#####################\n");printf("\n");printf("###################3.尾插######################\n");printf("\n");printf("###################4.尾删######################\n");printf("\n");printf("###################5.打印#####################\n");printf("\n");printf("###################0.exit#####################\n");printf("\n");printf("##############################################\n");
}

其实,最好不要一上来就写菜单,先写单元测试,菜单不方便调试

 测试菜单函数:

void MenuTest()
{SL s1;SeqListInit(&s1);int input = 0;int x;while (input != -1){menu();scanf("%d", &input);switch (input){case 1:printf("请输入你要头插的数据,以-1结束:");while (x != -1){SeqListPushFront(&s1, x);scanf("%d", &x);}break;case 2:SeqListPopFront(&s1);break;case 3:printf("请输入你要尾插的数据,以-1结束:");while (x != -1){SeqListPushBack(&s1, x);scanf("%d", &x);}break;case 4:SeqListPopBack(&s1);break;case 5:SeqListPrint(&s1);break;case 0:printf("退出程序\n");break;default:printf("输入错误,请重新输入\n");}}
}

源代码如下:

SeqList.h的内容:

#pragma once
#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
#include<assert.h>
#define N 7
typedef int SLDateType;
//顺序表的动态存储
typedef struct SeqList
{SLDateType* arr;//指向动态开辟的数组size_t size;//表示数组中存储了多少数据size_t capacity;//数组实际能存储数据的空间容量是多大
}SL;
//基本增删查改接口
void SeqListInit(SL* ps);//顺序表的初始化
void SeqListPrint(SL* ps);//顺序表的打印
void SeqListCheckCapacity(SL* ps);//检查空间,如果满了,进行扩容
void SeqListDestroy(SL* ps);//顺序表销毁
void SeqListPushBack(SL* ps, SLDateType x);//尾插
void SeqListPopBack(SL* ps);//尾删
void SeqListPushFront(SL* ps, SLDateType x);//头插
void SeqListPopFront(SL* ps);//头删
//顺序表查找
//找到了返回x位置的下标,没有找到返回-1
int SeqListFind(SL* ps, SLDateType x);
//顺序表指定pos下标位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDateType x);
//顺序表删除pos位置的数据
void SeqListErase(SL* ps, size_t pos);

SeqList.c的内容:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void SeqListInit(SL* ps)//顺序表的初始化
{ps->arr = NULL;ps->size = ps->capacity = 0;
}
void SeqListPrint(SL* ps)//顺序表的打印
{int i = 0;for (i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}
void SeqListCheckCapacity(SL* ps)//检查空间,如果满了,进行扩容
{//如果没有空间或者空间不足,那么我们就扩容if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDateType* tmp = (SLDateType*)realloc(ps->arr, newcapacity * sizeof(SLDateType));if (tmp == NULL){printf("realloc fail!\n");exit(-1);}ps->arr = tmp;ps->capacity = newcapacity;}
}
void SeqListDestroy(SL* ps)//顺序表销毁
{free(ps->arr);ps->arr = NULL;ps->capacity = ps->size = 0;
}
void SeqListPushBack(SL* ps, SLDateType x)//尾插
{SeqListCheckCapacity(ps);ps->arr[ps->size] = x;ps->size++;
}
void SeqListPopBack(SL* ps)//尾删
{assert(ps->size > 0);ps->size--;
}
void SeqListPushFront(SL* ps, SLDateType x)//头插
{SeqListCheckCapacity(ps);//挪动数据int end = ps->size - 1;while (end >= 0){ps->arr[end + 1] = ps->arr[end];end--;}ps->arr[0] = x;ps->size++;
}
void SeqListPopFront(SL* ps)//头删
{assert(ps->size > 0);//挪动数据int begin = 1;while (begin < ps->size){ps->arr[begin - 1] = ps->arr[begin];++begin;}ps->size--;
}
//顺序表查找
//找到了返回x位置的下标,没有找到返回-1
int SeqListFind(SL* ps, SLDateType x)
{int i = 0;for (i = 0; i < ps->size; i++){if (ps->arr[i] == x){return i;}}return -1;
}
// 顺序表指定pos下标位置插入x
void SeqListInsert(SL* ps, size_t pos, SLDateType x)
{温柔的写法//if (pos > ps->size || pos < 0)//{//	printf("pos invalid!\n");//}//粗暴的写法assert(pos <= ps->size || pos >= 0);SeqListCheckCapacity(ps);//挪动数据int end = ps->size - 1;while (end >= pos){ps->arr[end + 1] = ps->arr[end];end--;}ps->arr[pos] = x;ps->size++;
}
//顺序表删除pos位置的数据
void SeqListErase(SL* ps, size_t pos)
{assert(pos < ps->size || pos >= 0);int begin = pos + 1;while (begin < ps->size){ps->arr[begin - 1] = ps->arr[begin];++begin;}ps->size--;
}

好啦,小雅兰今天的内容就到这里啦,数据结构的的确确是一个麻烦的东西,还要加油呀!!!

 

相关文章:

顺序表——“数据结构与算法”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容是数据结构与算法里面的顺序表啦&#xff0c;在我看来&#xff0c;数据结构总体上是一个抽象的东西&#xff0c;关键还是要多写代码&#xff0c;下面&#xff0c;就让我们进入顺序表的世界吧 线性表 顺序表 线性表 线性表&…...

嵌入式Linux从入门到精通之第十六节:U-boot分析

简介 u-boot最初是由PPCBoot发展而来的,可以引导多种操作系统、支持多种架构的CPU,它对PowerPC系列处理器的支持最为完善,而操作系统则对Linux系统的支持最好目前已成为Armboot和PPCboot的替代品。 特点: 主要支持操作系统:Linux、NetBSD、 VxWorks、QNX、RTEMS、ARTOS、L…...

UART 串口通信

第18.1讲 UART串口通信原理讲解_哔哩哔哩_bilibili 并行通信 一个周期同时发送8bit的数据&#xff0c;占用引脚资源多 串行通信 串行通信的通信方式&#xff1a; 同步通信 同一时钟下进行数据传输 异步通信 发送设备和接收设备的时钟不同 但是需要约束波特率&#xff08;…...

【硬件】P沟道和N沟道MOS管开关电路设计

场效应管做的开关电路一般分为两种&#xff0c;一种是N沟道&#xff0c;另一种是P沟道&#xff0c;如果电路设计中要应用到高端驱动的话&#xff0c;可以采用PMOS来导通。P沟道MOS管开关电路PMOS的特性&#xff0c;Vgs小于一定的值就会导通&#xff0c;当Vgs<0,即Vs>Vg,管…...

中移杭研一面经历

文章目录 1、常用的Java元注解@Documented@Target@Retention@Override@Deprecated@Inherited@Repeatable@Native2、Java注解的原理3、spring boot starter开发过程1、原理浅谈2、大概步骤3、项目介绍1、常用的Java元注解 @Documented @Documented 是一个标记注解,没有成员变…...

如何成为一名全栈工程师:专业建议与技能要求

作为一名全栈工程师&#xff0c;你需要拥有跨越前端、后端、数据库等多个领域的技能&#xff0c;并能够将它们整合起来构建出完整的应用程序。因此&#xff0c;成为一名全栈工程师需要你掌握多种技术&#xff0c;具备较强的编程能力和系统设计能力。下面&#xff0c;我将从以下…...

MySQL架构篇

一、进阶学习环境说明 1.1 MySQL服务器环境 Linux虚拟机&#xff1a;CentOS 7 MySQL&#xff1a;MySQL5.7.30 在Linux服务器中安装MySQL&#xff1a; ps.如果有自己的云服务器&#xff0c;可忽略前两步&#xff0c;直接进行第三步 1.2 服务器日志文件说明 MySQL是通过文件系统对…...

Redhat7.6安装weblogic10.3.6(超详细,有图文)

一、环境 linux版本&#xff1a;Redhat 7.6 weblogic版本:WLS10.3.6 jdk版本&#xff1a;jdk1.8.0 下载网址&#xff1a;https://www.oracle.com/technetwork/middleware/weblogic/downloads/index.html 1.安装vsftpd服务&#xff0c;将部署环境使用JDK文件和wls服务文件…...

dashboard疏散主机提示报错:无法疏散主机...处理方法、openstack虚拟机状态卡在重启处理方法、openstack在数据库修改虚拟机状态的方法

文章目录dashboard疏散主机提示报错&#xff1a;无法疏散主机...处理方法报错说明【状态卡在reboot状态】解决方法【登录nova数据库修改虚拟机信息】首先获取nova数据库的密码登录nova数据库并做修改验证信息是否修改成功再次迁移并验证报错说明【虚拟机状态error也会导致疏散失…...

力扣:轮转数组(详解)

前言&#xff1a;内容包括&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读 题目&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3…...

Vue计算属性Computed

30. Vue计算属性Computed 1. 定义 Computed属性是Vue中的一个计算属性&#xff0c;是一种基于其它属性值计算而来的属性值&#xff0c;具有缓存机制&#xff0c;在依赖的属性值发生变化时会重新计算。 使用computed属性可以避免在模板中书写过多的计算逻辑&#xff0c;提高代…...

实验四:搜索

实验四&#xff1a;搜索 1.填格子 题目描述 有一个由数字 0、1 组成的方阵中&#xff0c;存在一任意形状的封闭区域&#xff0c;封闭区域由数字1 包围构成&#xff0c;每个节点只能走上下左右 4 个方向。现要求把封闭区域内的所有空间都填写成2 输入要求 每组测试数据第一…...

本地开发vue项目联调遇到访问接口跨域问题

本地开发vue项目联调遇到访问接口跨域问题 修改本地的localhost 一&#xff1a;按winr打开运行窗口&#xff0c;输入drivers &#xff0c;然后回车 二&#xff1a;打开etc文件夹&#xff0c;然后用记事本的方式打开里面的hosts文件&#xff0c; 三&#xff1a;这时我们就可…...

Vue键盘事件的使用

前言 在vue中&#xff0c;我们经常会用到键盘事件&#xff0c;不管是我们按下某个键&#xff0c;其实都是一次键盘事件的调用&#xff0c;下面就介绍下Vue中的键盘事件 先写一段代码&#xff0c;这里我选择的键盘事件是keyup,当然用keydown也是没问题的 问题来了&#xff0c;…...

抓包工具fiddler详细使用教程

各位做测试的同学想必对抓包工具fiddler并不陌生&#xff0c;但是很多同学可能没有总结过它的用法&#xff0c;下面我总结了fiddler一些常用的用法。 Web端抓包配置 打开Fiddler&#xff0c;Tools -> Fiddler Options -> HTTPS 配置完后记得要重启Fiddler 选中Decrpt …...

raspberry Pi 连接蓝牙(小爱同学)

参数valueraspberry pi MOdel4B&#xff0c;4Gbbluetooth MOdel小爱同学writeTime2023年 2月11日 下午13&#xff1a;14分raspberry System ModelLinux raspberrypi 5.15.61-v8 #1579 SMP PREEMPT Fri Aug 26 11:16:44 BST 2022 aarch64 GNU/Linux 连接蓝牙 请在小爱同学app上…...

解决launch:program .exe does not exist

二. 程序的运行和调试 1.launch.json 复制下列代码至launch.json&#xff0c;并根据指导做出相对/绝对路径修改 用 IntelliSense 了解相关属性。 {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息&#xff0c;请访问: https://go.micros…...

ETL --事实表

每一个事实表通过表的粒度来定义。事实表的粒度是事件度量的定义。我们必须至始至终按照度量如何在 现实世界中理解来规定事实表的粒度。 所有的事实表包含了一组关联到维表的外键&#xff0c;而这些维表提供了事实表度量的上下文。大多数的事实表还 包括了一个或者多个数值型…...

手工数据采集耗时耗力?Smartbi数据填报实现数据收集分析自动化

企业在日常经营管理过程中&#xff0c;往往需要收集很多内外部的信息&#xff0c;清洗整理后再进行存储、分析、呈现、决策支持等各种作业&#xff0c;如何高效收集结构化数据是企业管理者经常要面对的问题。传统手工的数据采集方式不仅耗费了大量人力时间成本&#xff0c;还容…...

应用实战|微信小程序开发示例--多人聊天互动空间

“超能力”数据库&#xff5e;拿来即用&#xff0c;应用开发人员再也不用为撰写API而发愁。MemFire Cloud 为开发者提供了简单易用的云数据库&#xff08;表编辑器、自动生成API、SQL编辑器、备份恢复、托管运维&#xff09;&#xff0c;很大地降低开发者的使用门槛。 本示例是…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...