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

【数据结构】单链表

目录

  • 一、什么是链表?
    • 1、 定义
    • 2、链表的分类
  • 二、无头单向非循环链表
    • 1、结构
    • 2、单链表数据的打印
    • 3、创建结点并初始化
    • 4、尾插
    • 5、头插
    • 6、尾删
    • 7、头删
    • 8、查找
    • 9、在指定位置`pos`之前插入数据
    • 10、在指定位置`pos`之后插入数据
    • 11、删除`pos`结点
    • 12、删除`pos`之后的结点
    • 13、销毁链表

前言:我的上一篇数据结构中给大家讲解了线性表中的一种结构顺序表,它存在一些缺点,比如,我们在扩容的时候总是以二倍的形式扩容这就会造成空间的浪费,再比如,顺序表进行头插的时候,时间复杂度是O(n)。那么这些问题如何解决呢?,本期这篇博客就让我们学习一种新的数据结构单链表

一、什么是链表?

1、 定义

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
你可以把链表理解成一个火车,火车由火车头,及一节节车厢组成,而指针就把一节节车厢连在了一起。
在这里插入图片描述
在火车运行高峰期,我们可以多拉几个车厢,而在人流量少的时候,我们可以摘下几节车厢,链表也可以这样操作,因此链表没有空间浪费的顾虑。

链表中每个结点,也就是每节车厢都是独立申请的,即需要插入数据时才去申请一块节点的空间,我们需要通过指针变量保存下一个结点的位置才能从当前结点找到下一个结点。

2、链表的分类

链表会根据是否带头结点是否是循环链表以及是否是双向链表进行分类组合,因此链表一共分为8种形式,分别是:

  • 不带头结点单向非循环链表
  • 不带头结点双向非循环链表
  • 不带头结点单向循环链表
  • 不带头结点双向循环链表
  • 带头结点单向非循环链表
  • 带头结点双向非循环链表
  • 带头结点单向循环链表
  • 带头结点双向循环链表
    在这里插入图片描述

以上就是链表的全部分类,我们本篇博客主要讲解单链表中的不带头结点单向非循环链表。

二、无头单向非循环链表

在这里插入图片描述

1、结构

typedef int SLTDataType;
typedef struct SListNode
{SLTDataType data;//储存的数据struct SListNode* next;//指向下一个结点
}SLTNode;

这里依旧效仿顺序表对int取别名SLTDataType便于以后的一键修改。
无头单向非循环链表的结构可以只由一个储存数据的变量以及一个指针构成。由于指针所指向的是下一个结构体,所以它的类型是结构体指针类型。这里对struct SListNode取别名SLTNode,方便后面的代码书写。

2、单链表数据的打印

在知晓单链表的结构后,我们就要对链表进行增、删、查、改操作了,在进行它们之前呢,我们要知道如何遍历整个链表。

void SLTPrint(SLTNode* phead)
{SLTNode* pcur = phead;while (pcur)//当当前结点不为空{printf("%d - > ", pcur->data);pcur = pcur->next;//移动到下一个结点}printf("NULL\n");
}

我们看到上面的函数,首先形参接收到链表中第一个结点的地址,然后我们定义一个结构体指针类型的变量pcur来接收它,当pcur指向的结构体指针类型不为NULL,进入循环打印该结点的数据,之后pcur移动到下一个结构体指针,直到pcur指向的结构体指针类型为NULL,结束循环,打印NULL,完成链表的遍历好了,熟悉链表的遍历操作,我们就可以对链表进行增、删、查、改

3、创建结点并初始化

SLTNode* SLTbuyNode(SLTDataType x)
{//根据x创建结点SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail!");return 1;//表示异常返回}newnode->data = x;newnode->next = NULL;return newnode;
}

这样我们根据数据x创建新节点的过程就封装在函数SLTbuyNode中了,后面将会直接调用这个函数进行新节点的创建。

4、尾插

尾插这个部分是很多人深度理解传值传址的地方,为什么这么说呢?因为这里很多人会出错。

错误的尾插示范

void SLTPushBack(SLTNode* phead, SLTDataType x)
{SLTNode* newnode = SLTbuyNode(x);//链表为空if (phead == NULL){phead = newnode;}else{//找尾SLTNode* tail = phead;while (tail->next){tail = tail->next;}tail->next = newnode;}
}

要执行的代码:

#include "SList.h"int main()
{SLTNode* plist = NULL;//首先创建一个链表SLTPrint(plist);//打印空链表SLTPushBack(plist,1);//尾插一个数字1SLTPrint(plist);//再次打印return 0;
}

大家或许认为第一次打印的会是NULL,而第二次打印的结果将会是1->NULL
实际结果:
在这里插入图片描述
函数打印了两个NULL
大家可能会认为这不就是传址调用吗?我们在调试后发现在第一次尾插时形参的链表的首地址的确发生了改变,但实参的链表首地址仍旧是0x00000000(NULL),也就是说这不是传址调用而是传值调用
很多人对此就表示很不理解,他们的观点一般是plist储存的不就是地址吗?所以这不就是传址调用吗?
其实并不是这样,plist它的确储存的确是某一个指针变量的地址,但是它也有它自己的地址!以上错误示范中传递的是指针中的内容,而不是指针的地址,无法改变指针的指向。就像我们在初步学习指针时学习的那样,形参只是实参的一份临时拷贝,你没有获得实参的地址你就不能改变实参

  • 解决方法一
    在以上代码的基础上添加返回值,返回的类型是SLTNode*类型。
SLTNode* SLTPushBack(SLTNode* phead, SLTDataType x)
{SLTNode* newnode = SLTbuyNode(x);//链表为空if (phead == NULL){phead = newnode;}else{//找尾SLTNode* tail = phead;while (tail->next){tail = tail->next;}tail->next = newnode;}return phead;
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);plist=SLTPushBack(plist,1);SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述

  • 解决方法二
    我们在调用时传递一级指针的地址,用二级指针接收它。
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = SLTbuyNode(x);//链表为空if (*pphead == NULL){*pphead = newnode;}else{//找尾SLTNode* tail = *pphead;while (tail->next){tail = tail->next;}tail->next = newnode;}
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述
以上两种方式都可以解决问题,只不过方法一在调用时有些麻烦,所以在本博客中将使用第二种解决方式。

5、头插

头插就是改变头指针存放的地址,无需单独考虑空链表的情况。

void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTbuyNode(x);newnode->next = *pphead;*pphead = newnode;
}

要执行的代码

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述

6、尾删

尾删我们不仅仅需要把尾部的结点删去,还要把尾结点前一个结点的next指针置为NULL,我们要定义一个名为ptail的结构体指针查找尾结点,再定义一个名为prev的结构体指针查找尾结点的前一个结点,这时候我们还要考虑链表中只有一个结点的情况,因为当链表中只有一个结点时,我们不能对prev进行解引用,因为此时它为NULL,会造成错误。

void SLTPopBack(SLTNode** pphead)
{assert(pphead && *pphead);//只有一个结点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLTNode* prev = NULL;//在ptail指针之前SLTNode* ptail = *pphead;while (ptail->next){prev = ptail;ptail = ptail->next;}prev->next = NULL;//将尾指针前一个指针的next指针置为空free(ptail);ptail = NULL;}
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述

7、头删

头删只需要注意链表是否为NULL,当链表为NULL时,是不能进行头删的,进行头删操作时,把头指针指向的下一个结点储存起来,再将头节点释放掉就可以了。

void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* head = (*pphead)->next;free(*pphead);*pphead = head;
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述

8、查找

就是遍历一下链表,如果找到了,就返回当前结点,如果未找到就返回NULL

SLTNode* SLTFind(SLTNode** pphead, SLTDataType x)
{assert(pphead && *pphead);SLTNode* ptr = *pphead;while (ptr){if (ptr->data == x){return ptr;}ptr = ptr->next;}return NULL;
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTNode* find=SLTFind(&plist, 1);if (find){printf("找到了!\n");}else printf("未找到!\n");return 0;
} 

执行结果:
在这里插入图片描述

9、在指定位置pos之前插入数据

只需要定义一个结构体指针变量pcur,并遍历到pcur->nextpos时停止便可,之后,将它的next指针指向我们新创建的结点,再让新建立的结点的next指针指向pos就可以了。当然开头需要处理链表第一个结点就是pos的情况。

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead && pos);if (pos == *pphead){SLTPushFront(pphead, x);//头插}else{SLTNode* newnode = SLTbuyNode(x);SLTNode* pcur = *pphead;while (pcur->next != pos){pcur = pcur->next;}pcur->next = newnode;newnode->next = pos;}
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTNode* find=SLTFind(&plist, 1);SLTInsert(&plist, find, 5);//在数据为1的结点前面插入数据SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述

10、在指定位置pos之后插入数据

pos位置之后插入数据的情况就比较简单,我们只需创建newnode储存新的数据,然后让newnodenext的指针指向posnext指向的结点,再将posnext指针指向newnode即可。

void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = SLTbuyNode(x);newnode->next = pos->next;pos->next = newnode;
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTNode* find=SLTFind(&plist, 1);SLTInsertAfter(find, 5);//在数据为1的后面插入数据SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述

11、删除pos结点

pos可能是头结点的地址,链表的头结点可能发生改变,所以形参要用二级指针。

void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead && pos);if (pos == *pphead){SLTPopFront(pphead);//头删}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}

要执行的代码

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTNode* find=SLTFind(&plist, 1);SLTInsertAfter(find, 5);//在数据为1的后面插入数据SLTPrint(plist);SLTErase(&plist, find);SLTPrint(plist);return 0;
}

执行结果:
在这里插入图片描述

12、删除pos之后的结点

删除pos位置之后的结点注意不能写成这样:pos->next=pos->next->next这样写虽然可以把pos之后的结点剔除出链表,但并没有真正的删除它,因为每个结点都是通过动态内存开辟的,在不使用时要主动free掉,把这块空间还给操作系统,否则可能会导致内存泄漏,上面这样写就会导致无法释放,正确的做法应该是再次申请一个中间结点。

void SLTEraseAfter(SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos->next = del->next;free(del);del = NULL;
}

要执行的代码

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTNode* find=SLTFind(&plist, 1);SLTInsertAfter(find, 5);//在数据为1的后面插入数据SLTPrint(plist);SLTEraseAfter(find);SLTPrint(plist);return 0;
} 

执行结果:
在这里插入图片描述

13、销毁链表

链表的销毁需要从头节点开始,一节一节将后面的结点销毁。

void SListDestroy(SLTNode** pphead)
{SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

要执行的代码:

int main()
{SLTNode* plist = NULL;SLTPrint(plist);SLTPushBack(&plist,1);SLTPrint(plist);SLTPushFront(&plist, 2);SLTPrint(plist);SLTNode* find=SLTFind(&plist, 1);SLTInsertAfter(find, 5);//在数据为1的后面插入数据SLTPrint(plist);SLTEraseAfter(find);SLTPrint(plist);SListDestroy(&plist);SLTPrint(plist);return 0;
} 

执行结果
在这里插入图片描述
今天的分享就是这样啦,如果觉得文章还不错的话可以三连支持一下,你的支持就是我前进最大的动力!

总结:
以上就是本期博客分享的全部内容啦!技术的探索永无止境。
道阻且长,行则将至!后续我会给大家带来更多优质博客内容,欢迎关注我的CSDN账号,我们一同成长!
(~ ̄▽ ̄)~

相关文章:

【数据结构】单链表

目录 一、什么是链表?1、 定义2、链表的分类 二、无头单向非循环链表1、结构2、单链表数据的打印3、创建结点并初始化4、尾插5、头插6、尾删7、头删8、查找9、在指定位置pos之前插入数据10、在指定位置pos之后插入数据11、删除pos结点12、删除pos之后的结点13、销毁…...

UnoCSS极速入门:下一代原子化CSS引擎实战指南

文章目录 一、什么是UnoCSS?二、环境配置(Vite示例)三、核心使用模式3.1 自定义规则3.2 原子化类应用3.3 使用RegExp匹配器 四、高级功能解析4.1 主题系统4.2 响应式与深色模式 五、实战案例:构建现代按钮组件六、性能优化技巧七、…...

Es6进阶

class里的get和set 在 ES6 中,class 里的 get 和 set 是用于定义访问器属性的关键字。get 方法可在访问对象属性时调用,set 方法则在设置对象属性时调用。下面通过一个简单示例来介绍它们的用法: javascript class Person {constructor(nam…...

可发1区的创新思路:​基于K-means聚类的EMD-BiLSTM-CNN-Attention时间序列预测模型(功率预测、寿命预测、流量预测、故障诊断)

首先声明,该模型为原创!原创!原创! 一、应用场景 该模型主要用于时间序列数据预测问题,包含功率预测、电池寿命预测、交通流量预测、电机故障检测等等。 二、模型整体介绍(本文以光伏功率预测为例) 核心架构 ​数据聚类:K-means对风电场机组分组,降低异质性干扰。​…...

Android BLE 权限管理

前言 android 权限一直是比较活跃的 在蓝牙权限这一块又分新版和旧版 新版权限 android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT旧版权限如9.0以下 Manifest.permission.A…...

vue3 ts 注册全局组件

vue3 ts 注册全局组件 register.tsmain.ts register.ts // 注册全局组件 import {App} from "vue" import headerPage from "/headerPage.vue" export default {install(app:App){app.component("headerPage",headerPage)} }main.ts import re…...

Apache Doris学习

https://doris.apache.org/zh-CN/docs/gettingStarted/what-is-apache-doris 介绍 Apache Doris 是一款基于 MPP 架构(大规模并行处理)的高性能、实时分析型数据库。它以高效、简单和统一的特性著称,能够在亚秒级的时间内返回海量数据的查询…...

llama源码学习·model.py[7]Transformer类

一、源码展示 class Transformer(nn.Module):def __init__(self, params: ModelArgs):super().__init__()self.params paramsself.vocab_size params.vocab_sizeself.n_layers params.n_layersself.tok_embeddings VocabParallelEmbedding(params.vocab_size, params.dim,…...

Windows server 2022域控制服务器的配置

Windows server 2022介绍 一、核心特性与改进 安全核心服务器(Secured-Core Server) 硬件级安全:支持基于硬件的安全功能(如TPM 2.0、Secure Boot、基于虚拟化的安全防护VBS),防止固件攻击。受信任的启动链…...

yolo目标检测算法在DJI上的研究分析(大纲)

yolo目标检测算法在DJI上的研究分析 面向边缘计算的实时目标检测系统设计与部署 第一章 绪论 1.1 研究背景与意义 目标检测技术需求: DJI设备(如无人机、摄像头)在安防、巡检、农业等场景中的广泛应用现有YOLO算法在高分辨率图像或资源受限…...

三、重学C++—C语言内存管理

上一章节: 二、重学C—C语言核心-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146191640?spm1001.2014.3001.5502 本章节代码: cPart2 CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/…...

DAY37 动态归化Ⅰ基础题目

509. 斐波那契数 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int fib(int n) {if(n<1) return n;int dp[2];dp[0]0;dp[1]1;int sum0;for(int i2;i<n;i){sum dp[0]dp[1];dp[0]dp[1];dp[1]sum;}return sum;} }; 70. 爬楼梯 - 力扣&#xff08;Lee…...

ABAP Core Data Services (SAP PRESS) (First Edition)

ABAP Core Data Services (SAP PRESS) (First Edition)...

ORM——对象关系映射

对象关系映射&#xff08;ORM&#xff09;深度解析&#xff1a;原理、优势与应用场景 一、什么是ORM&#xff1f; ORM&#xff08;Object-Relational Mapping&#xff09;即对象关系映射&#xff0c;是一种将面向对象编程中的对象与关系型数据库中的表进行映射的技术。简单来…...

【Docker系列五】Docker Compose 简介

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

大语言模型-2.2/3-主流模型架构与新型架构

简介 本博客内容是《大语言模型》一书的读书笔记&#xff0c;该书是中国人民大学高瓴人工智能学院赵鑫教授团队出品&#xff0c;覆盖大语言模型训练与使用的全流程&#xff0c;从预训练到微调与对齐&#xff0c;从使用技术到评测应用&#xff0c;帮助学员全面掌握大语言模型的…...

JAVA组件的利用漏洞 Shlr搜索引擎 shiro身份 Log4j日志

solr组件 1、作用 &#xff1a; 基于http和apache lucene 进行全文搜索服务器 2、识别&#xff1a; 第一个就是图标类似于华为的那个 然后就是端口标识是 8983 3、CVE利用&#xff1a; 1、命令执行&#xff08;CVE-2019-17558&#xff09; Apache Solr 5.0.0版本至8…...

MongoDB未授权访问漏洞

1、连接MongoDB&#xff0c;添加账号密码 mongo 127.0.0.1 use admindb.createUser({user: admin,pwd: MongoDB123%.com,roles:[{role: root,db: admin}] })创建admin用户&#xff0c;密码为&#xff1a;MongoDB123%.com 2、设置完成&#xff0c;可以通过指令 show users 查看…...

CVPR2025 | 对抗样本智能安全方向论文汇总 | 持续更新中~

汇总结果来源&#xff1a;CVPR 2025 Accepted Papers 若文中出现的 论文链接 和 GitHub链接 点不开&#xff0c;则说明还未公布&#xff0c;在公布后笔者会及时添加. 若笔者未及时添加&#xff0c;欢迎读者告知. 文章根据题目关键词搜索&#xff0c;可能会有遗漏. 若笔者出现…...

MyBatis 动态 SQL 优化:标签的实战与技巧

目录 动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL&#xff1f;1.2 动态SQL的优点1.3 动态SQL的常见用途 二、动态SQL的常见用法&#xff08;XML方式&#xff09;2.1 < if > 标签2.2 < trim> 标签2.3 <where>标签2.4<set>标签2.5 <foreach&g…...

自动化机器学习(TPOT优化临床试验数据)

目录 自动化机器学习(TPOT优化临床试验数据)1. 引言2. 项目背景与意义2.1 临床试验数据分析的重要性2.2 自动化机器学习的优势2.3 工业级数据处理与GPU加速需求3. 数据集生成与介绍3.1 数据集构成3.2 数据生成方法4. 自动化机器学习与TPOT4.1 自动化机器学习简介4.2 TPOT在临…...

spring boot3 验证码工具kaptcha使用

1、pom.xml文件&#xff0c;下载验证码工具kaptcha依赖 官网搭建的spring boot项目 <!--验证码工具kaptcha的依赖--> <dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId> </dependency> 阿里云…...

Android 根据Url使用Retrofit框架进行文件下载

一、背景 根据后端返回的url下载地址,去执行文件下载&#xff0c;将文件保存到SD卡。这里使用Retrofit网络框架。 二、代码实现 2.1、定义一个DownloadFileService interface DownloadFileService {StreamingGETsuspend fun downloadFile(Url fileUrl: String):ResponseBody…...

可视化动态表单动态表单界的天花板--Formily(阿里开源)

文章目录 1、Formily表单介绍2、安装依赖2.1、安装内核库2.2、 安装 UI 桥接库2.3、Formily 支持多种 UI 组件生态&#xff1a; 3、表单设计器3.1、核心理念3.2、安装3.3、示例源码 4、场景案例-登录注册4.1、Markup Schema 案例4.2、JSON Schema 案例4.3、纯 JSX 案例 1、Form…...

Java常用类

常用类 1.包 2.String类 3.String注意事项 String是不可变字符串对象。只要是以“ …. ”方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份。但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。String s2 s1 "a"…...

多模态大模型常见问题

1.视觉编码器和 LLM 连接时&#xff0c;使用 BLIP2中 Q-Former那种复杂的 Adaptor 好还是 LLaVA中简单的 MLP 好&#xff0c;说说各自的优缺点&#xff1f; Q-Former&#xff08;BLIP2&#xff09;&#xff1a; 优点&#xff1a;Q-Former 通过查询机制有效融合了视觉和语言特征…...

2025 年大模型排行分析:中美竞争与未来展望

具体排名数据见文章结尾 在人工智能领域&#xff0c;大模型的性能成为衡量机构技术实力的重要标志。以下是根据最新排名的一些主要发现&#xff0c;尤其关注中国模型的发展现状和优势。 全球领先的模型 在本次排名中&#xff0c;美国 OpenAI 的多个版本占据榜首位置。具体而…...

为什么后端路由需要携带 /api 作为前缀?前端如何设置基础路径 /api?

一、为什么后端路由需要携带 /api 作为前缀&#xff1f; 1. 区分 API 端点与其他路由 在 Web 应用程序中&#xff0c;后端不仅需要处理 API 请求&#xff0c;还可能需要处理静态资源&#xff08;如 HTML、CSS、JS 文件&#xff09;或其他服务&#xff08;如 WebSocket&#x…...

Mac:Ant 下载+安装+环境配置(详细讲解)

&#x1f4cc; 下载 Ant 下载地址&#xff1a;https://ant.apache.org/bindownload.cgi &#x1f4cc; 无需安装 Apache官网下载 Ant 压缩包&#xff0c;无需安装&#xff0c;下载解压后放到自己指定目录下即可。 按我自己的习惯&#xff0c;我会在用户 jane 目录下新建了个…...

web客户端存储,IndexDB相关讲解

IndexDB详细讲解 IndexedDB 是浏览器提供的一种底层 API,用于在客户端存储大量结构化数据。相比 Web Storage(localStorage/sessionStorage),它支持更复杂的数据结构、事务处理、索引查询等高级功能。以下是一个系统化的讲解: 一、核心概念 1、​数据库(Database)​ 每…...

使用DeepSeek翻译英文科技论文,以MarkDown格式输出,使用Writage 3.3.1插件转换为Word文件

一、使用DeepSeek翻译英文科技论文&#xff0c;以MarkDown格式输出 以科技论文“Electrical Power System Sizing within the Numerical Propulsion System Simulation”为例。 需要Writage 3.3.1 license key注册码的小伙伴&#xff0c;可发送邮件至邮箱pyengine163.com. 首先…...

Linux 文件操作-文件IO函数2- write向文件写入数据、read从文件读取数据、lseek重定位文件描述符的偏移量的验证

目录 1.write 向文件描述符中写入数据 1.1 向标准输出STDOUT_FILENO (终端屏幕)写入数据 1.2 向文件写入数据 2.read 从文件描述符中读取数据 2.1从标准输入STDIN_FILENO&#xff08;键盘&#xff09;读取数据 2.2从文件读取数据 3.lseek重定位偏移量 1.write 向文件描述…...

`chromadb` 是什么

chromadb 是什么 chromadb 是一个开源的向量数据库,它专门用于存储、索引和查询向量数据。在处理自然语言处理(NLP)、计算机视觉等领域的任务时,通常会将文本、图像等数据转换为向量表示,而 chromadb 可以高效地管理这些向量,帮助开发者快速找到与查询向量最相似的向量数…...

Python 爬虫(4)HTTP协议

文章目录 一、HTTP协议1、HTTP特点2、HTTP工作原理3、HTTP与HTTPS的区别 前言&#xff1a; HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是互联网上应用最为广泛的一种网络协议&#xff0c;用于在客户端和服务器之间传输超文本&#xf…...

Redis 事件机制详解

Redis 事件机制详解 Redis 的事件机制是其高性能和高并发能力的关键之一&#xff0c;它采用Reactor 模型&#xff0c;基于文件事件驱动机制实现高效的 I/O 处理。Redis 的事件机制主要分为以下几类&#xff1a; 文件事件&#xff08;File Event&#xff09; —— 处理网络 I/…...

JMeter对API接口进行压力测试使用教程

1.启动工具&#xff1a;以管理员身份运行 启动成功会有两个窗口&#xff0c;都保留别关闭 2.创建线程组 3.创建http请求 配置 4.添加监听&#xff0c;查看请求结果 5.运行 成功截图 6.接口压力测试&#xff0c;修改线程组参数 7.2000请求&#xff0c;2秒完成...

Vue 3 项目实现国际化指南 i18n

引言 在开发现代 Web 应用时&#xff0c;国际化&#xff08;Internationalization&#xff0c;简称 i18n&#xff09;已经成为一个不可或缺的功能。无论是面向全球用户的商业网站&#xff0c;还是需要支持多语言的企业应用&#xff0c;良好的国际化支持都能显著提升用户体验。本…...

使用Trae 生成的React版的贪吃蛇

使用Trae 生成的React版的贪吃蛇 首先你想用这个贪吃蛇&#xff0c;你需要先安装Trae Trae 官方地址 他有两种模式 chat builder 我使用的是builder模式,虽然是Alpha.还是可以用。 接下来就是按着需求傻瓜式的操作生成代码 他生成的代码不完全正确&#xff0c;比如没有引入…...

HAL库定时器配置

定时器的开启需要手动开启&#xff0c;例如在driver_capature.c开启&#xff0c;该文件主要写了具体的函数实现&#xff0c;与driver_can.c一样&#xff0c;同时还有回调函数等一些高级的自定义函数。 这段代码是 STM32 HAL 库中用于初始化 定时器 2 (TIM2) 的函数 MX_TIM2_In…...

快速部署Linux + Ollama + AnythingLLM + Deepseek

简介 部署的系统&#xff1a;Ubuntu20.04 这里选择AnythingLLM的原因&#xff0c;是因为它自身支持了知识库的功能&#xff0c;其他的还有chatbox、dify等可以选择。 部署流程&#xff08;请务必使用魔法&#xff09; 一、Ollama安装 1、访问ollama官网&#xff1a;https:/…...

人脸表情识别系统分享(基于深度学习+OpenCV+PyQt5)

最近终于把毕业大论文忙完了&#xff0c;众所周知硕士大论文需要有三个工作点&#xff0c;表情识别领域的第三个工作点一般是做一个表情识别系统出来&#xff0c;如下图所示。 这里分享一下这个表情识别系统&#xff1a; 采用 深度学习OpenCVPyQt5 构建&#xff0c;主要功能包…...

Qt 导入TagLib库

文章目录 0. 前言和环境介绍1. 下载TagLib2. 下载zlib3. 修改.pro文件4. 测试代码 0. 前言和环境介绍 最近在使用Qt写一个播放器&#xff0c;需要解析mp3文件&#xff0c;于是研究了一下如何导入TagLib库 Qt构建套件:Desktop Qt6.8.2 MinGW64-bit Qt Creator安装目录: D:\bit…...

LiteratureReading:[2023] GPT-4: Technical Report

文章目录 一、文献简明&#xff08;zero&#xff09;二、快速预览&#xff08;first&#xff09;1、标题分析2、作者介绍3、引用数4、摘要分析&#xff08;1&#xff09;翻译&#xff08;2&#xff09;分析 5、总结分析&#xff08;1&#xff09;翻译&#xff08;2&#xff09;…...

Elasticsearch8.17 生产集群使用优化

一、通用优化建议 避免返回大量文档结果集 Elasticsearch 作为搜索引擎,擅长返回与查询匹配的顶级文档。对于需要检索所有匹配文档的数据库类型操作,建议使用 滚动 API(Scroll API) 或 **搜索后游标(Search After Cursor)**,以避免内存和性能问题。 避免大型文档 默…...

Linux系统管理与编程09:任务驱动综合应用

兰生幽谷&#xff0c;不为莫服而不芳&#xff1b; 君子行义&#xff0c;不为莫知而止休。 [环境] windows11、centos9.9.2207、zabbix6、MobaXterm、Internet环境 [要求] zabbix6.0安装环境&#xff1a;Lamp&#xff08;linux httpd mysql8.0 php&#xff09; [步骤] 5 …...

C++:背包问题习题

1. 货币系统 1371. 货币系统 - AcWing题库 给定 V 种货币&#xff08;单位&#xff1a;元&#xff09;&#xff0c;每种货币使用的次数不限。 不同种类的货币&#xff0c;面值可能是相同的。 现在&#xff0c;要你用这 V 种货币凑出 N 元钱&#xff0c;请问共有多少种不同的…...

Flutter中常用命令

1.检测flutter运行环境 flutter doctor 2.升级flutter flutter upgrade 3.查看flutter 版本 flutter --version 4.查看连接的设备 flutter devices 5.运行flutter项目 flutter run 或者在vscode中按FnF5 6.打包 flutter build apk //默认打release包 7.开…...

数学爱好者写的编程系列文章

作为一个数学爱好者&#xff0c;我大学读的专业却不是数学专业&#xff0c;而是跟计算机有关的专业。原本我对编程一窍不通&#xff0c;平时上课也是在看数学文献&#xff0c;作业基本靠同学&#xff0c;考试及格就行。不过后来因为毕业的压力&#xff0c;我还是拥抱编程了&…...

QT笔记---JSON

QT笔记---JSON JSON1、JSON基本概念1.1、判断.json文件工具 2、生成.json数据3、解析.json数据 JSON 在现代软件开发中&#xff0c;数据的交换和存储格式至关重要。JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&#xff0c;以其简洁易…...

C站算法技能题-题解(javascript)

切面条 const 切面条 (n10)>{return 2 ** n 1; } 切面条(0) 2 切面条(1) 3 切面条(2) 5 切面条(10) 1025大衍数列 const 大衍数列 (n100) > {let ans []for(let i1;i<n;i){if(i%2 0){ans.push((i ** 2 ) / 2)}else{ans.push((i ** 2 - 1) / 2)}}return ans…...