顺序表的实现(头插、尾插、头删、尾删、查找、删除、插入)
目录
一. 数据结构相关概念
二、线性表
三、顺序表概念及结构
3.1顺序表一般可以分为:
3.2 接口实现:
四、基本操作实现
4.1顺序表初始化
4.2检查空间,如果满了,进行增容编辑
4.3顺序表打印
4.4顺序表销毁
4.5顺序表尾插
4.6顺序表头插
4.7顺序表头删
4.8顺序表尾删
4.9顺序表在pos位置插入x
4.10顺序表删除pos位置的值
链表相关知识:
链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入)-CSDN博客
链表基础知识(一、单链表、头插、尾插、头删、尾删、查找、删除、插入)-CSDN博客
一. 数据结构相关概念
什么是数据结构?
数据结构是由“数据”和“结构”两词组合而来。
什么是数据?常见的数值1、2、3、4.....、教务系统里保存的用户信息(姓名、性别、年龄、学历等等)、网页里肉眼可以看到的信息(文字、图片、视频等等),这些都是数据什么是结构?
当我们想要使用大量使用同一类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将大量的数据组织在一起,结构也可以理解为组织数据的方式。
概念:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系
的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。
总结:
1)能够存储数据(如顺序表、链表等结构)
2)存储的数据能够方便查找
2、为什么需要数据结构?
通过数据结构,能够有效将数据组织和管理在一起。按照我们的方式任意对数据进行增删改查等操
作。最基础的数据结构:数组。

【思考】有了数组,为什么还要学习其他的数据结构?
假定数组有10个空间,已经使用了5个,向数组中插入数据步骤:
求数组的长度,求数组的有效数据个数,向下标为数据有效个数的位置插入数据(注意:这里是
否要判断数组是否满了,满了还能继续插入吗).....
假设数据量非常庞大,频繁的获取数组有效数据个数会影响程序执行效率。
结论:最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现。
二、线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使
用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,
线性表在物理上存储时,通常以数组和链式结构的形式存储。

三、顺序表概念及结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存
储。在数组上完成数据的增删查改。
-
顺序表和数组的区别
-
顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口

3.1顺序表一般可以分为:
-
静态顺序表:使用定长数组存储。
// 顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct SeqList
{SLDataType array[N]; // 定长数组size_t size; // 有效数据的个数
}SeqList;

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

3.2 接口实现:
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大
了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态
的分配空间大小,所以下面我们实现动态顺序表。
先解释一下预处理指令
-
#pragma once:这是一个非标准的预处理指令,它告诉预处理器这个头文件只应该被包含一次。如果尝试多次包含,预处理器会忽略后续的包含。尽管它是非标准的,但许多现代编译器(如GCC和Clang)都支持它。
-
#ifndef SEQLIST_H:这是一个条件编译指令。它检查是否定义了一个名为SEQLIST_H的宏。如果没有定义(即这个头文件还没有被包含过),那么接下来的代码会被编译。
-
#define SEQLIST_H:这定义了一个名为SEQLIST_H的宏。当这个头文件首次被包含时,这个宏会被定义,从而标记这个头文件已经被包含过了。
-
#endif:这结束了之前的#ifndef条件编译块。
SeqList.h
//#pragma once
#ifndef _SEQLIST_H_
#define _SEQLIST_H_#include<stdio.h>
#include<string.h>
#include<stdlib.h>#include<assert.h>//增强程序的可维护性
#define MAX_SIZE 10
typedef int SQDataType;
//静态顺序表
//问题:给少了不够用,给多了用不完浪费,不能灵活控制//typedef struct SeqList
//{
// SQDataType a[MAX_SIZE];
// int size;
//}SL;typedef struct SeqList
{SQDataType *a;// 指向动态开辟的数组int size; //有效的数据的个数int capacity;//容量
}SL;//typedef struct SeqList SL;//定义为简写// 基本增删查改接口
// 顺序表初始化//增删查改等接口函数
//void SeqListInit(struct SeqList s);//顺序表初始化
void SeqListInint(SL* ps);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList * psl);
//顺序表打印
void SeqListPrint(SL* ps);
// 顺序表销毁
void SeqListDestory(SL* ps);
//顺序表尾插
void SeqListPushBack(SL* ps, SQDataType x);
//顺序表头插
void SeqListPushFront(SL* ps, SQDataType x);
//顺序表头删
void SeqListPopBack(SL* ps);
//顺序表尾删
void SeqListPopFront(SL* ps);// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SQDataType x);// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos);#endif
四、基本操作实现
4.1顺序表初始化
void SeqListInit(SL* ps)
{ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
4.2检查空间,如果满了,进行增容

这个函数的主要目的是在顺序列表满时自动扩容,以便能够继续添加元素。它首先检查列表是否已满,然后计算新的容量,并使用realloc函数尝试调整数组的大小。如果realloc失败(返回NULL),则打印错误信息并退出程序。如果成功,就更新列表的数组指针和容量。
// 函数定义,传入一个指向顺序列表(SeqList)的指针
void SeqListCheckCapacity(SL* ps)
{ // 检查顺序列表是否已满,即当前大小(size)是否等于容量(capacity) if (ps->size == ps->capacity) { // 如果满了,计算新的容量。如果当前容量为0,则新容量为4;否则,新容量为当前容量的2倍 int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; // 使用realloc函数尝试调整顺序列表的数组大小 // realloc可能会改变原有内存块的位置,因此需要使用一个临时指针来接收结果 SQDataType* tmp = (SQDataType*)realloc(ps->a, newcapacity * sizeof(SQDataType)); // 检查realloc是否成功 if (tmp == NULL) { // 如果失败,打印错误信息并退出程序 printf("realloc fail\n"); exit(-1); } else { // 如果成功,更新顺序列表的数组指针和容量 ps->a = tmp; ps->capacity = newcapacity; } }
}
4.3顺序表打印
这个函数的主要目的是遍历顺序列表,并打印出其中的每一个元素。通过循环,它会依次访问列表中的每个元素,并将其打印。
// 打印顺序列表中的所有元素
void SeqListPrint(SL* ps)
{ // 通过循环遍历顺序列表中的每一个元素 for (int i = 0; i < ps->size; i++) { printf("%d ", ps->a[i]); } // 打印一个换行符,使得每次打印列表后都会换行,输出更清晰 printf("\n");
}
4.4顺序表销毁
SeqListDestroy函数主要目的是释放顺序列表所占用的内存空间
// 销毁顺序列表的函数
void SeqListDestroy(SL* ps)
{ // 断言:确保传入的顺序列表指针ps不为空 assert(ps); // 判断顺序列表的数组指针a是否不为空 if (ps->a != NULL) { // 释放数组指针a所指向的内存空间 free(ps->a); // 将数组指针a设置为NULL,避免野指针 ps->a = NULL; // 将顺序列表的大小设置为0,表示列表已空 ps->size = 0; // 将顺序列表的容量设置为0,表示已没有分配内存空间 ps->capacity = 0; }
}
4.5顺序表尾插
在插入新元素之前,它们都首先检查当前的容量是否足够,如果不够则调用 SeqListCheckCapacity 函数进行扩容。尾插函数SeqListPushBack直接在末尾添加新元素
// 尾插法:在顺序列表的末尾插入一个新元素
void SeqListPushBack(SL* ps, SQDataType x)
{ // 检查当前顺序列表的容量是否足够,如果不够则进行扩容 SeqListCheckCapacity(ps); // 在顺序列表的当前末尾位置插入新元素 ps->a[ps->size] = x; // 更新顺序列表的大小(元素数量) ps->size++;
}
4.6顺序表头插
在插入新元素之前,它们都首先检查当前的容量是否足够,如果不够则调用 SeqListCheckCapacity 函数进行扩容。头插函数SeqListPushFront将现有元素向后移动以腾出空间。

// 头插法:在顺序列表的开头插入一个新元素
void SeqListPushFront(SL* ps, SQDataType x)
{ // 检查当前顺序列表的容量是否足够,如果不够则进行扩容 SeqListCheckCapacity(ps); // 初始化:设定一个变量来追踪当前需要移动的元素的位置 // 结束条件:当所有元素都已移动到它们的新位置时停止 // 迭代过程:从列表的末尾开始,将每个元素向后移动一个位置以腾出空间 int end = ps->size - 1; // 从列表的最后一个元素开始 while (end >= 0) // 当还有元素需要移动时继续循环 { // 将当前位置的元素向后移动一个位置 ps->a[end + 1] = ps->a[end]; --end; // 移动到前一个元素 } // 在顺序列表的开头(现在为空)插入新元素 ps->a[0] = x; // 更新顺序列表的大小(元素数量) ps->size++;
}
4.7顺序表头删
SeqListPopFront`函数用于删除顺序列表的第一个元素。它首先通过断言确保列表不为空,然后通过一个循环将第一个位置之后的所有元素都向前移动一个位置,从而覆盖掉第一个位置的元素,并更新列表的大小。
// 头删:删除顺序列表的第一个元素
void SeqListPopFront(SL* ps)
{ // 断言,确保顺序列表不为空,即其大小大于0 // 如果ps->size <= 0,则触发断言错误,终止程序 assert(ps->size > 0); // 初始化一个变量start,用于从第二个元素开始遍历 int start = 1; // 当start小于列表大小时,执行循环 // 这个循环用于将第一个位置之后的元素都向前移动一个位置,从而覆盖掉第一个位置的元素 while (start < ps->size) { // 将下一个位置的元素移动到当前位置 ps->a[start - 1] = ps->a[start]; // start向后移动一个位置,继续处理下一个元素 start++; } // 因为第一个元素已经被覆盖,所以不需要额外处理 // 更新顺序列表的大小(元素数量),因为删除了一个元素,所以大小减1 ps->size--;
}
4.8顺序表尾删

SeqListPopBack函数用于删除顺序列表的最后一个元素。它首先通过断言确保列表不为空,然后直接更新列表的大小。
// 尾删:删除顺序列表的最后一个元素
void SeqListPopBack(SL* ps)
{ // 断言,确保顺序列表不为空,即其大小大于0 // 如果ps->size <= 0,则触发断言错误,终止程序 assert(ps->size > 0); // 可以选择将最后一个元素的值设置为0或其他默认值,以确保不留下未定义的值 // 但这取决于具体的应用需求,有时可能不需要这样做 //ps->a[ps->size - 1] = 0; // 更新顺序列表的大小(元素数量),因为删除了一个元素,所以大小减1 ps->size--;
}
4.9顺序表在pos位置插入x
SeqListInsert函数的主要作用是在顺序列表的指定位置pos插入一个新元素x。为了达到这个目的,它首先确保插入的位置是有效的(不会超出当前列表的大小),然后检查是否需要扩容。接着,它通过一个循环将pos位置及其之后的元素都向后移动一个位置,以便为新元素腾出空间。最后,它在pos位置插入新元素,并更新列表的大小。

// 在顺序列表的指定位置插入一个元素
void SeqListInsert(SL* ps, int pos, SQDataType x)
{ // 断言,确保插入的位置不会超出当前列表的大小 // 如果pos >= ps->size,则触发断言错误,终止程序 assert(pos < ps->size); // 检查当前顺序列表的容量是否足够,如果不够则进行扩容 SeqListCheckCapacity(ps); // 初始化一个变量end,用于从列表的末尾开始遍历 int end = ps->size - 1; // 当end位置大于或等于要插入的位置pos时,执行循环 // 这个循环用于将pos位置及其之后的元素都向后移动一个位置,为插入新元素腾出空间 while (end >= pos) { // 将当前位置的元素向后移动一个位置 ps->a[end + 1] = ps->a[end]; // end向前移动一个位置,继续处理前一个元素 end--; } // 在腾出的位置pos处插入新元素x ps->a[pos] = x; // 更新顺序列表的大小(元素数量) ps->size++;
}
4.10顺序表删除pos位置的值
SeqListErase函数用于删除顺序列表中指定位置的元素。它首先通过断言确保要删除的位置是有效的,然后通过一个循环将指定位置之后的所有元素都向前移动一个位置,从而覆盖掉指定位置的元素。最后,它更新列表的大小。

// 删除顺序列表中指定位置的元素
void SeqListErase(SL* ps, int pos)
{ // 断言,确保要删除的位置不会超出当前列表的大小 // 如果pos >= ps->size,则触发断言错误,终止程序 assert(pos < ps->size); // 初始化一个变量start,用于从要删除的位置的下一个元素开始遍历 int start = pos + 1; // 当start小于列表大小时,执行循环 // 这个循环用于将pos位置之后的元素都向前移动一个位置,覆盖掉pos位置的元素 while (start < ps->size) { // 将下一个位置的元素移动到当前位置 ps->a[start - 1] = ps->a[start]; // start向后移动一个位置,继续处理下一个元素 start++; } // 更新顺序列表的大小(元素数量),因为删除了一个元素,所以大小减1 ps->size--;
}
今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
相关文章:
顺序表的实现(头插、尾插、头删、尾删、查找、删除、插入)
目录 一. 数据结构相关概念 二、线性表 三、顺序表概念及结构 3.1顺序表一般可以分为: 3.2 接口实现: 四、基本操作实现 4.1顺序表初始化 4.2检查空间,如果满了,进行增容编辑 4.3顺序表打印 4.4顺序表销毁 4.5顺…...
VMware虚拟机安装Ubuntu系统教程
所使用的文件如下: VMware Workstation 17 Pro ubuntu-22.04.3-desktop-amd64.iso 一、ubuntu 命名规则及各版本一览表 1.ubuntu 命名规则: 例如:ubuntu 16.04 LTS 是长期维护版本;ubuntu 17.04 是新特性版本 前两位数字为发…...
41 sysfs 文件系统
前言 在 linux 中常见的文件系统 有很多, 如下 基于磁盘的文件系统, ext2, ext3, ext4, xfs, btrfs, jfs, ntfs 内存文件系统, procfs, sysfs, tmpfs, squashfs, debugfs 闪存文件系统, ubifs, jffs2, yaffs 文件系统这一套体系在 linux 有一层 vfs 抽象, 用户程序不用…...
C++面试宝典第9题:找出第K大元素
题目 给定一个整数数组a,同时给定它的大小N和要找的K(1 <= K <= N),请根据快速排序的思路,找出数组中第K大的数(保证答案存在)。比如:数组a为[50, 23, 66, 18, 72],数组大小N为5,K为3,则第K大的数为50。 解析 这道题主要考察应聘者对于快速排序的理解,以及实…...
“马屁精”李白
“李白一斗诗百篇,长安市上酒家眠。天子呼来不上船,自称臣是酒中仙。”这是诗圣杜甫笔下的李白,也是我们脑海里坚信无二的李白。恃才傲物又狂放不羁的诗仙,怎么会低眉顺眼地去拍人马屁呢? 但我要说的是,人…...
python之glob的用法
目录 获取特定扩展名的所有文件 获取特定目录下的所有文件 递归获取所有文件 转义特殊字符 iglob glob 是 Python 中用于文件模式匹配的一个模块。它使用 Unix shell-style 的通配符来进行匹配,并返回所有匹配的文件路径列表。 下面是一些 glob 的基本用法&am…...
【adb】电脑通过ADB向手机传输文件
具体步骤如下: Step1 下载ADB工具 下载最新版本的 ADB工具 !!! 注意:一定要是最新版本的ADB,否则很可能导致无法识别到手机。 将下载的ADB解压以后的文件如下图所示: Step2 添加环境变量 将 ADB的路径 D:\platformtools &…...
npm的常用使用技巧
npm是一个强大的工具,可以帮助你管理Node.js项目中的依赖项。以下是一些有用的npm使用技巧: 使用npm install命令:这个命令可以安装项目的依赖项。如果你想安装一个特定的版本,你可以使用npm install <package><version…...
【网络奇遇记】揭秘计算机网络的性能指标:速率|带宽|吞吐量|时延
🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 速率1.1 数据量1.2 速率 二. 带宽三. 吞吐量四. 时延4.1 发送时延4.2 传播时延…...
ACM中算法时间约束
ACM中算法时间约束 一般ACM竞赛C/C的时间限制是一秒,因此可以根据题目数据来推断该题所使用的算法。 算法的时间复杂度在 1 0 7 10^7 107左右合适,最多不能超过 1 0 8 10^8 108, O ( n ) O(n) O(n)的极限就在 1 0 8 10^8 108左右。 问题规…...
C++11的列表初始化和右值引用
目录 前言 一、C11的简介 二、C11的小故事。 三、统一的列表初始化 1.列表初始化 2.initializer_list 四、右值引用 1.什么是左值 2.什么是右值 3.右值引用写法 4.右值的分类 5.右值引用的作用 6.STL容器中的右值引用 7.万能引用 总结 前言 C11相较于之C98&…...
千帆起航:探索百度智能云千帆AppBuilder在AI原生应用开发中的革新之路
千帆起航:探索百度千帆AppBuilder在AI原生应用开发中的革新之路 1.揭开帷幕,大模型第二次战役 自从 ChatGPT 横空出世后,一石激起千层浪,人工智能也正在从感知理解走向生成创造,这是一个关键里程碑。生成式大模型完成…...
RevIT™ AAV Enhancer, 提高AAV产量的又一利器!
腺相关病毒 (AAV) 是基因治疗中使用最广泛的传递机制。近年来,基于AAV病毒所开发的基因疗法的研发及临床试验注册数量也呈指数级增长。截止本文撰写之时,美国食品和药物管理局已批准五项AAV疗法,也是全球市场上最为昂贵的药物,其中…...
Kubectl 部署有状态应用(下)
接上文 《Kubectl 部署有状态应用(上)》创建完StatefulSet后,本文继续介绍StatefulSet 扩展、更新、删除等内容。 StatefulSet 中的 Pod 验证序数索引和稳定的网络身份 StatefulSet 中的 Pod 具有唯一的序数索引和稳定的网络身份。 查看 …...
Jmeter 性能 —— 监控服务器!
Jmeter监控Linux需要三个文件 JMeterPlugins-Extras.jar (包:JMeterPlugins-Extras-1.4.0.zip)JMeterPlugins-Standard.jar (包:JMeterPlugins-Standard-1.4.0.zip)ServerAgent-2.2.3.zip 1、Jemter 安装插件 在插件管理中心的搜索Servers Performan…...
离散型制造企业为什么要注重MES管理系统的实施
离散型制造企业经常面临三个核心问题:生产什么、生产多少以及如何生产。尽管许多企业都实施了ERP系统,但仍然绕不开MES管理系统的话题。本文将从三个方面详细解释为什么离散型企业需要实施MES管理系统。 一、生产线经常出现的问题 在离散型企业中&#…...
Linux系统中跟TCP相关的内核参数
1. TCP保活机制 参考 《Nginx(三) 配置文件详解 - 基础模块》3.18章节 net.ipv4.tcp_keepalive_intvl:设置两次相邻探活检测的间隔时间。默认是75秒,单位是秒。net.ipv4.tcp_keepalive_probes:设置探活最多检测次数。默认是9次,单…...
代理模式(Proxy)
代理模式(Proxy Pattern)是一种结构型设计模式,用于为另一个对象提供一个代替品或占位符以控制对这个对象的访问。这个模式主要用于延迟处理操作或者在进行实际操作前后进行其它处理。 代理模式的实现通常涉及以下角色: 抽象主题(Subject):定义了代理和真实对象的共用接…...
在MacOS上Qt配置OpenCV并进行测试
目录 一.Qt环境准备 二.在Qt项目中加载Opencv库并编写代码测试 1.使用Opencv加载图片 (1)在Qt中创建一个新项目 (2)在.pro文件中链接OpenCV库 (3)添加新资源文件 (4)在mainw…...
java数据结构与算法刷题-----LeetCode167:两数之和 II - 输入有序数组
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 思路 题目要求我们找到两个数相加的和,等于target指定的值。而…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
