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

二.线性表之顺序表

文章目录

  • 前言
  • 一.顺序表的概念及结构
  • 二.顺序表的接口实现
    • 1.顺序表的动态存储
    • 2.顺序表的初始化
    • 3.顺序表尾插
    • #封装:扩容函数
    • 4.顺序表尾删
    • 5.顺序表头插
    • 6.顺序表头删
    • 7.顺序表查找
    • 8.顺序表在pos位置插入x
    • 9.顺序表删除pos位置的值
    • 10.顺序表销毁
    • 11.顺序表打印
  • 三.源
    • 1.Seqlist.h
    • 2.Seqlist.c
  • 四.顺序表的问题及思考

前言

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

一.顺序表的概念及结构

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

  1. 静态顺序表:使用定长数组存储元素。
#define N 7
typedef int SlDataType;
typedef struct Seqlist
{SlDataType array[N];  //定长数组size_t size;   //有效数据个数
}Seqlist;

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

二.顺序表的接口实现

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

1.顺序表的动态存储

typedef int SLDataType;  //可以是int,double,结构体,按照要求来
#define INIT_CAPACITY 4  //初始化大小为4typedef struct Seqlist
{SLDataType* a;   //指向存放数据的每一个内存空间int size;        //有效数据个数int capacity;    //空间容量
}SL;

顺序表的长度是不固定的,可增容的,所以要用指针指向每一块信息空间。

2.顺序表的初始化

void SLInit(SL* pc)
{assert(pc);//1.强制转化类型 2.分配的是字节:sizeof(SLDataType) * INIT_CAPACITYpc->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);  //刚开始分配4个if (pc->a == NULL){perror("malloc");return;}pc->size = 0;pc->capacity = INIT_CAPACITY;
}

采用动态分配内存的方式,进行初始化

3.顺序表尾插

void SLPushBack(SL* pc, SLDataType x)
{assert(pc);//检查是否扩容if (pc->size == pc->capacity){SLDataType* tmp = (SLDataType*)realloc(pc->a, sizeof(SLDataType) * pc->capacity * 2);if (tmp == NULL){printf("realloc");return;}pc->a = tmp;pc->capacity *= 2;}//pc->size记录的是当前表中数据的下一位,直接赋值给该位赋值即可pc->a[pc->size++] = x;  
}

注意:

  1. realloc函数是按照字节调整大小,所以一定要记得用sizeof 计算类型的字节大小。
  2. pc->a[pc->size++] = x的具体含义如下:
    在这里插入图片描述

改进:上面尾插数据时我们需要检查是否扩容,不如就把扩容函数单独封装,后面再需要检查扩容的时候直接调用该函数即可:

#封装:扩容函数

void SLCheckCapacity(SL* pc)
{assert(pc);//检查是否扩容if (pc->size == pc->capacity){//有可能异地扩容,再新定义一个指针SLDataType* tmp = (SLDataType*)realloc(pc->a, sizeof(SLDataType) * pc->capacity * 2);if (tmp == NULL){printf("relloc");return;}pc->a = tmp;pc->capacity *= 2;}
}

这样尾插函数就可以简化为:

void SLPushBack(SL* pc, SLDataType x)
{//assert(pc);检查是否扩容//if (pc->size == pc->capacity)//{//	//有可能异地扩容,再新定义一个指针//	SLDataType* tmp = (SLDataType*)realloc(pc->a, sizeof(SLDataType) * pc->capacity * 2);//	if (tmp == NULL)//	{//		printf("relloc");//		return;//	}//	pc->a = tmp;  //	pc->capacity *= 2;//}SLCheckCapacity(pc);pc->a[pc->size++] = x;
}

4.顺序表尾删

void SLPopBakc(SL* pc)
{//暴力的检查//assert(pc->size > 0);//温柔的检查if (pc->size == 0)return;pc->size--;
}

注意:

  1. 当size删到0的时候,我们就没法再删除元素了,否则会出问题,所以在删除元素的时候需要特判一下size的大小,可以用断言assert,也可以用if语句。
  2. **pc->size- -;**的意思是顺序表中元素数量减一,也就是删掉了尾部元素。

5.顺序表头插

//头插
void SLPushFront(SL* pc,SLDataType x)
{assert(pc);SLCheckCapacity(pc);int end = pc->size - 1;  while (end >= 0){//从最后一位开始,整体把数据后移一位pc->a[end + 1] = pc->a[end];--end;}pc->a[0] = x;pc->size++;
}

为了给开头腾出位置,需要将数据整体先向后移动一位:

从最后一位开始移动,防止数据被覆盖

6.顺序表头删

//头删
void SLPopFront(SL* pc)
{assert(pc);assert(pc->size > 0); //保证有数据int begin = 1;while (begin < pc->size){pc->a[begin - 1] = pc->a[begin];}pc -> size--;
}

删除头部数据前先判断表中是否有数据,表里没东西固然不能硬删。删头元素时是把头元素后面的数据全部往前挪一位,整体覆盖前一个数据,相当于删除了头部元素:
在这里插入图片描述
从第二个开始往前挪,防止提前被覆盖。

7.顺序表查找

//查找
int SLFind(SL* pc, SLDataType x)
{assert(pc);for (int i = 0; i < pc->size; i++){if (pc->a[i] == x){return i;}}return -1;
}

直接遍历一遍查找即可

8.顺序表在pos位置插入x

//任意位置插入
void SLInsert(SL* pc, int pos, SLDataType x)
{assert(pc);assert(pos >= 0 && pos <= pc->size);SLCheckCapacity(pc);int end = pc->size - 1;while (end >= pos){pc->a[end + 1] = pc->a[end];end--;}pc->a[pos] = x;pc->size++;
}

与头插法想法类似,把pos后面的数据整体向后挪动一位,给pos腾出位置来,放入新的值x:
在这里插入图片描述
改进:当pos=0的时候其实就是头插,当pos=pc->size的时候就是尾插
所以我们可以只用一个在任意位置插入的SLInsert函数实现所有位置的数据插入:
①尾插:

void SLPushBack(SL* pc, SLDataType x)
{//assert(pc);检查是否扩容//if (pc->size == pc->capacity)//{//	//有可能异地扩容,再新定义一个指针//	SLDataType* tmp = (SLDataType*)realloc(pc->a, sizeof(SLDataType) * pc->capacity * 2);//	if (tmp == NULL)//	{//		printf("relloc");//		return;//	}//	pc->a = tmp;  //	pc->capacity *= 2;//}/*SLCheckCapacity(pc);pc->a[pc->size++] = x;*/SLInsert(pc, pc->size, x);
}

②头插

void SLPushFront(SL* pc, SLDataType x)
{//assert(pc);//SLCheckCapacity(pc);//int end = pc->size - 1;  //while (end >= 0)//{//	//从最后一位开始,整体把数据后移一位//	pc->a[end + 1] = pc->a[end];//	--end;//}//pc->a[0] = x;//pc->size++;SLInsert(pc, 0, x);
}

这又能进一步使代码变得简洁

9.顺序表删除pos位置的值

//任意位置删除
void SLErase(SL* pc, int pos)
{assert(pc);assert(pc >= 0 && pos < pc->size);  //size指向当前数据的下一位,还没有存放数据,所以没东西可删,要注意与任意位置插入的代码区分int begin = pos + 1;while (begin < pc->size){pc->a[begin - 1] = pc->a[begin];begin++;}pc->size--;
}

与头删法类似,采用从pos后往前覆盖的思想,把pos存的数据覆盖住:
在这里插入图片描述
改进:当pos=0时就是头删,当pos=pc->size-1时就是尾删,这样我们可以只用该函数实现任意位置的删除
①尾删:

void SLPopBakc(SL* pc)
{//assert(pc);暴力的检查//assert(pc->size > 0);//温柔的检查//if (pc->size == 0)//	return;//pc->size--;SLErase(pc, pc->size - 1);
}

②头删

//头删
void SLPopFront(SL* pc)
{//assert(pc);//assert(pc->size > 0); //保证有数据//int begin = 1;//while (begin < pc->size)//{//	pc->a[begin - 1] = pc->a[begin];//}//pc -> size--;SLErase(pc, 0);
}

使代码更简洁。

10.顺序表销毁

void SLDestory(SL* pc)
{free(pc->a);pc->a = NULL;pc->capacity = pc->size = 0;
}

由于空间都是动态分配的,所以销毁的时候直接free掉,free后的指针记得置空。

11.顺序表打印

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

三.源

1.Seqlist.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//typedef int SLDataType;
//#define N 100000
//
 静态顺序表 -- 开少了不够用 开多了浪费
//struct SeqList
//{
//	SLDataType a[N];
//	int size;
//};typedef int SLDataType;
#define INIT_CAPACITY 4// 动态顺序表 -- 按需申请
typedef struct SeqList
{SLDataType* a;int size;     // 有效数据个数int capacity; // 空间容量
}SL;// 增删查改
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
void SLCheckCapacity(SL* ps);void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);

2.Seqlist.c

#include"SeqList.h"
//初始化
void SLInit(SL* ps)
{assert(ps);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);free(ps->a);ps->a = NULL;ps->capacity = ps->size = 0;
}
//打印数据
void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; ++i){printf("%d ", ps->a[i]);}printf("\n");
}
//检查扩容
void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity *= 2;}
}//尾插
void SLPushBack(SL* ps, SLDataType x)
{//assert(ps); 扩容//SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;//ps->a[ps->size++] = x;SLInsert(ps, ps->size, x);
}
//尾删
void SLPopBack(SL* ps)
{//assert(ps); 暴力检查//assert(ps->size > 0); 温柔的检查if (ps->size == 0)//	//return;ps->a[ps->size - 1] = 0;//ps->size--;SLErase(ps, ps->size-1);
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{/*assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];--end;}ps->a[0] = x;ps->size++;*/SLInsert(ps, 0, x);
}
//头删
void SLPopFront(SL* ps)
{//assert(ps);//assert(ps->size > 0);//int begin = 1;//while (begin < ps->size)//{//	ps->a[begin - 1] = ps->a[begin];//	++begin;//}//ps->size--;SLErase(ps, 0);
}
//任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];--end;}ps->a[pos] = x;ps->size++;
}
//任意位置删除
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];++begin;}ps->size--;
}
//查找
int SLFind(SL* ps, SLDataType x)
{assert(ps);for(int i = 0; i < ps->size; ++i){if (ps->a[i] == x){return i;}}return -1;
}

四.顺序表的问题及思考

  1. 中间或头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

要解决上述问题,就要用到链表的知识了,我们下一篇再见!!


码文不易,还请多多支持哦!!

相关文章:

二.线性表之顺序表

文章目录前言一.顺序表的概念及结构二.顺序表的接口实现1.顺序表的动态存储2.顺序表的初始化3.顺序表尾插#封装&#xff1a;扩容函数4.顺序表尾删5.顺序表头插6.顺序表头删7.顺序表查找8.顺序表在pos位置插入x9.顺序表删除pos位置的值10.顺序表销毁11.顺序表打印三.源1.Seqlist…...

ElasticSearch - SpringBoot整合ElasticSearch实现文档的增删改

文章目录1. ElasticSearch和kibana的安装和配置2. SpringBoot 项目环境搭建3. 创建索引4. 索引文档5. 更新文档6. 删除文档https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.htmlhttps://www.elastic.co/guide/cn/elasticsearch/guide/curre…...

JavaScript 库

文章目录JavaScript 库JavaScript 框架&#xff08;库&#xff09;jQueryPrototypeMooTools其他框架CDN -内容分发网络引用 jQuery使用框架JavaScript 库 JavaScript 库 - jQuery、Prototype、MooTools。 JavaScript 框架&#xff08;库&#xff09; JavaScript 高级程序设计…...

云解析DNS为什么要配置默认线路?

传统解析技术不会判断访客IP&#xff0c;而是会随机选择一个IP返回给访问者&#xff0c;这样就有可能造成移动用户访问电信服务器IP&#xff0c;北京用户访问深圳服务器IP这种跨域跨网访问的情况&#xff0c;产生非常大的延迟&#xff0c;带来很不好的访问体验。 而云解析DNS会…...

Linux命令之awk

awk是一个有强大的文本格式化能力的linux命令&#xff0c;早期是在Unix上实现的&#xff0c;linux后来也可以使用了&#xff0c;我们在Linux上使用的awk是gawk&#xff08;GNU awk的意思&#xff09; 语法 awk [option] 模式{动作} file option表示awk的可选参数&#xff0c;可…...

实战-缓存数据一致+binlog初始+cannel监听+数据迁移,数据一致性架构设计

前言 一. 解决缓存不命中&#xff08;高并发操作击穿打挂DB的风险&#xff09; 当并发量打的时候&#xff0c;当我们的缓存过期时&#xff0c;就算到数据库的比例偏小的时候&#xff0c;我们的请求时比较大的。那也会存在数据库崩掉的情况。解决方案想法如下&#xff08;总体…...

nginx配置中proxy_pass反向代理502的bug

记录一个坑人的bug&#xff0c; 我今天在一台新的liunx上运行nginx来进行反向代理时候&#xff0c;发现怎么测都是502 我把配置全部删了从头开始配置&#xff0c;发现80端口正常&#xff0c;80端口index.html正常&#xff0c;反向代理转向http://127.0.0.1/也正常&#xff0c;…...

JavaScript 两种方案打开文件对话框

JavaScript 两种方案打开文件对话框 文章目录JavaScript 两种方案打开文件对话框一、文件对话框二、传统方案表单元素&#x1f308;三、文件系统访问API&#x1f4a6;四、更进一步使用六、代码仓库&#x1f310;七、参考资料&#x1f498;七、推荐博文&#x1f357;一、文件对话…...

Pycharm远程服务器常见问题

2023年02月23日 问题描述&#xff1a;Pycharm远程服务器跑代码时&#xff0c;不小心把Pycharm关掉了&#xff0c;但服务器代码还在运行&#xff1f; 解决办法&#xff1a;kill进程 先用watch -n 0.5 nvidia_smi查看进程&#xff0c;然后kill -9 <进程> 1、nvidia-smi…...

内容团队如何快速出稿

对于内容团队而言&#xff0c;每个内容选题就相当于一个小项目&#xff0c;它们并非简单的线性工作流&#xff0c;相反其复杂程度不亚于一个小型工厂。一个内容选题会涉及内容形式&#xff0c;选题类型等多个变量&#xff0c;这些变量因素组合起来就是十几种不同类型的工作流。…...

es-08索引的批量操作

索引的批量操作 批量查询和批量增删改 批量查询 GET /_mget#批量查询 GET product/_search GET /_mget {"docs": [{"_index": "product","_id": 2},{"_index": "product","_id": 3}] }GET product/_mge…...

诈金花的概率

游戏使用一副除去大小王的扑克牌&#xff0c;共4个花色52张牌。 1、豹子&#xff08;AAA最大&#xff0c;222最小&#xff09;。2、同花顺&#xff08;AKQ最大&#xff0c;A23最小&#xff09;。3、同花&#xff08;AKQ最大&#xff0c;352最小&#xff09;。4、顺子&#xff…...

ESP32设备驱动-MLX90393磁场传感器驱动

MLX90393磁场传感器驱动 文章目录 MLX90393磁场传感器驱动1、MLX90393介绍2、硬件准备3、软件准备4、驱动实现1、MLX90393介绍 MLX90393 磁场传感器可以在运行时重新编程为不同的模式和不同的设置。 该传感器使用 Melexis 专有的 Triaxis 技术提供与沿 XYZ 轴感应的磁通密度成…...

Java面试题-Spring框架

Spring框架 1. BeanFactory和ApplicationContext有何区别 BeanFactory是Spring最底层的接口&#xff0c;是IoC的核心&#xff0c;定义IoC的基本功能。 ​ BeanFactory具有&#xff1a;延迟实例化的特性。在启动的时候&#xff0c;不会实例化Bean&#xff0c;只有有需要从容器…...

【计算机物理模拟】-力矩、转动惯量和角速度之间的关系

力矩和角速度之间的关系可以通过牛顿第二定律和角动量定理来描述。 牛顿第二定律表明&#xff0c;物体的加速度与作用在物体上的合力成正比&#xff0c;加速度的方向与合力的方向相同。而对于旋转运动的物体&#xff0c;其加速度可以表示为半径 rrr 乘以角加速度 α\alphaα&a…...

async和await用法理解和快速上手 , 同步任务和异步任务顺序安排和轻松理解 , js代码执行顺序表面知道

学习关键语句 : async , await 用法 await 怎么使用 同步任务和异步任务 微任务和宏任务 js中代码执行顺序 写在前面 虽然说 async 和 await 是 Promise 的语法糖 , 但是用惯了Promise 的人(我) , 还真不能超快速使用上这个语法糖 , 所以赶紧写一篇文章出来让各位了解了解这个…...

Linux下java服务占用cpu过高如何处理

Linux下java服务占用cpu过高如何处理 top命令查看进程信息 top按下shiftp,按cpu使用率排行,可见进程1932占用最高,并且是一个java服务 使用jps命令确认java服务 [rootVM-16-16-centos ~]# jps 1011 Jps 9462 yuan_back-0.0.1-SNAPSHOT.jar 1932 spigot-1.18.jar查找异常进程中…...

ros下用kinectv2运行orbslam2

目录 前提 创建工作空间 orbslam2源码配置、测试&#xff1a; 配置usb_cam ROS功能包 配置kinect 前提 vim 、 cmake 、 git 、 gcc 、 g 这些一般都装了 主要是Pangolin 、 OpenCV 、 Eigen的安装 18.04建议Pangolin0.5 创建工作空间 我们在主目录下创建一个catkin_…...

MVP简单模型搭建【架构】

MVP简介 MVP是一种项目架构设计模式&#xff08;说白了就是我们产品的一种设计方案&#xff09; 其实MVP本质 就是将View和Model完全隔离&#xff0c;通过Presenter统一调度管理&#xff08;Presenter扮演着中介的角色&#xff09;传统的设计思路是我们直接跟房东谈&#xff0…...

若依ruoyi框架实现目录树与查询页面联动

目录1、业务场景2、前端api.js修改index.vue修改template修改script修改3、后端controllerserviceimpldomainentitytreeselect1、业务场景 后管页面实现目录数与查询页面的联动&#xff0c;类似若依框架用户管理页面。 2、前端 api.js修改 在原有的js文件里配置目录树的查…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...