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

【数据结构】-- 栈和队列

在这里插入图片描述

🐇

🔥博客主页: 云曦
📋系列专栏:数据结构

💨吾生也有涯,而知也无涯
💛 感谢大家👍点赞 😋关注📝评论

文章目录

  • 前言
  • 一、栈
    • 📙1.1 栈的概念及结构
    • 📙1.2 栈的实现
      • 📜1.2.1 栈的结构
      • 📜1.2.2 初始化栈
      • 📜1.2.3 入栈
      • 📜1.2.4 出栈
      • 📜1.2.5 获取栈顶元素
      • 📜1.2.6 获取栈中有效元素个数
      • 📜1.2.7 检测栈是否为空
      • 📜1.2.8 销毁栈
      • 📜1.2.9 栈所有接口的测试
  • 二、队列
    • 📙2.1 队列的概念及结构
    • 📙2.2 队列的实现
      • 📜2.2.1 队列的结构
      • 📜2.2.2 初始化队列
      • 📜2.2.3 队尾入队列
      • 📜2.2.4 检测队列是否为空
      • 📜2.2.5 队头出队列
      • 📜2.2.6 获取队列头部元素
      • 📜2.2.7 获取队列尾部元素
      • 📜2.2.8 获取队列中有效元素个数
      • 📜2.2.9 销毁队列
      • 📜2.2.10 队列所有接口的测试
  • 完整代码
    • 📙**Stack.h**
    • 📙**Stack.c**
    • 📙**Queue.h**
    • 📙**Queue.c**
    • 📙**test.c**

前言

在上期中我们把双向链表学完了,这期我们要开始新的一章 “栈和队列” 的讲解,栈和队列基本都是拿我们之前所学的顺序表或链表来实现,可谓是新瓶装旧酒,有了对顺序表和链表的认识,实现栈和队列并不是难事!

一、栈

📙1.1 栈的概念及结构

概念:栈也是一种特殊的线性表,其次栈只允许在固定一端插入删除,进行数据插入或删除操作的一端叫作栈顶,另一端为栈底。 栈中的数据元素遵守后进先出LIFO的原则。

  • 压栈:栈插入数据的操作叫作进栈/入栈/压栈,且入数据是在栈顶。
  • 出栈:栈删除数据的操作叫作出栈,出数据也在栈顶。

结构:
栈结构
注意:栈如果用链表实现的话要考虑找前一个节点的问题,因为栈的插入删除都是在栈顶,所以实现栈时推荐用顺序表来实现,因为顺序表在尾部插入数据的代价比较小。

📙1.2 栈的实现

📜1.2.1 栈的结构

既然用顺序表实现那么栈的结构就是顺序表的结构

typedef int STDataType;typedef struct Stack
{int* arr;int top;//栈顶int capacity;//容量
}ST;

📜1.2.2 初始化栈

因为在栈的结构里,插入数据只能在栈顶插入,所有只需要实现一个插入的接口即可,把malloc改到插入接口(push)里即可.

void STInit(ST* ps)
{assert(ps);ps->arr = NULL;ps->capacity = 0;ps->size = 0;
}

📜1.2.3 入栈

void STPush(ST* ps, STDataType x)
{assert(ps);//检测容量if (ps->top == ps->capacity){//使用三目操作符来解决扩容问题int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->arr, sizeof(STDataType)*newcapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->arr = tmp;ps->capacity = newcapacity;}//入栈ps->arr[ps->top] = x;ps->top++;
}

需要注意的是:realloc有一个特性,如果传入的参数是NULL,则会像malloc一样开辟一个空间出来,相当于调用了malloc。

📜1.2.4 出栈

出栈很简单让栈顶减1即可。

void STPop(ST* ps)
{assert(ps);//栈为空就不能再删了assert(ps->top > 0);ps->top--;
}

需要注意的是:插入的指针有可能为空或者栈有可能为空,两个情况都要检查一下

📜1.2.5 获取栈顶元素

top是有效数据个数后一个的位置,减1就为栈顶的元素

STDataType STTop(const ST* ps)
{assert(ps);return ps->arr[ps->top-1];
}

📜1.2.6 获取栈中有效元素个数

top就是有效数据的个数,直接返回top即可

int STSize(const ST* ps)
{assert(ps);return ps->top;
}

📜1.2.7 检测栈是否为空

返回top是否等于0,等于返回真,不等于返回假

bool STEmpty(const ST* ps)
{assert(ps);return ps->top == 0;
}

📜1.2.8 销毁栈

注意:这里的销毁指得是把这块空间还给操作系统。

void STDestroy(ST* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->capacity = 0;ps->top = 0;
}

📜1.2.9 栈所有接口的测试

void TestStack()
{ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);STPush(&s, 5);printf("栈的有效元素个数%d\n", STSize(&s));while (!STEmpty(&s)){printf("%d ", STTop(&s));STPop(&s);}//STPop(&s);printf("\n栈的有效元素个数%d\n", STSize(&s));STDestroy(&s);}

测试1

当栈为空还在删除时:
测试2

二、队列

📙2.1 队列的概念及结构

概念:队列也是一种只允许在一端插入数据,在另外一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO。

  • 入队列:进行插入操作的一端称为队尾
  • 出队列:进行删除操作的一端称为队头

结构:
结构图解
注意:队列也能用顺序表和链表实现,但使用链表的结构实现更优一些,因为如果是顺序表的话,头删要挪移数据才能完成,效率比链表低,所以实现队列推荐用链表来实现。

📙2.2 队列的实现

📜2.2.1 队列的结构

既然使用队列实现,那么结构自然是链表的形式。

typedef int QueDataType;typedef struct QueueNode
{QueDataType data;struct QueueNode* next;
}QNode;typedef struct Queue
{QNode* phead;QNode* tail;int size;
}Que;

因为是单链表,出队列是头删,入队列是尾插,导致需要一个头指针和尾指针,且单链表计算长度要遍历一遍数组,这样下来:

  1. 要传头和尾的参数
  2. 计算链表长度要遍历链表,复杂度为O(N)
  • 不如直接把头尾指针和定义一个存储链表元素个数的变量整合为一个结构体这样就方便多了

📜2.2.2 初始化队列

void QueueInit(Que* pq)
{pq->phead = NULL;pq->tail = NULL;pq->size = 0;
}

只有一个插入的接口,那么就直接在插入接口获取节点就行。

📜2.2.3 队尾入队列

首先获取并初始化节点,然后就是尾插,尾插分为两种情况:

  1. 链表为空,特殊处理。
  2. 链表不为空,正常尾插。
void QueuePush(Que* pq, QueDataType x)
{//获取并初始化节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("newnode fail");exit(-1);}newnode->data = x;newnode->next = NULL;//入队列if (pq->phead == NULL){//链表为空pq->phead = newnode;pq->tail = newnode;}else{//链表不为空pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}

📜2.2.4 检测队列是否为空

直接返回pq->phead == NULL,等于返回真,不等于返回假

bool QueueEmpty(Que* pq)
{assert(pq);return pq->phead == NULL;
}

📜2.2.5 队头出队列

单链表头删很简单,但要注意:链表为空时,不能再删了,否则会出问题

void QueuePop(Que* pq)
{assert(pq);//检测链表是否为空,为空就不能再删了assert(!QueueEmpty(pq));//出队列QNode* Next = pq->phead->next;free(pq->phead);pq->phead = Next;pq->size--;
}

📜2.2.6 获取队列头部元素

phead指向的就是头节点,返回头节点的元素即可,但要注意:链表有可能为空,所以要检测一下

QueDataType QueueFront(Que* pq)
{assert(pq);//检测链表是否为空assert(!QueueEmpty(pq));return pq->phead->data;
}

📜2.2.7 获取队列尾部元素

tail指向的就是尾节点,直接返回尾节点的元素即可,但要注意:链表有可能为空,所以要检测一下

QueDataType QueueBack(Que* pq)
{assert(pq);//检测链表是否为空assert(!QueueEmpty(pq));return pq->tail->data;
}

📜2.2.8 获取队列中有效元素个数

size存储的就是队列的有效元素个数,返回size即可。

int QueueSize(Que* pq)
{assert(pq);return pq->size;
}

📜2.2.9 销毁队列

  • 这里的销毁指的也是把这片空间还给操作系统
  • 遍历一遍队列,记录下一个节点的位置,释放掉当前节点,最后将头尾指针置空,size置为0即可。
void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* Next = cur->next;free(cur);cur = Next;}pq->phead = NULL;pq->tail = NULL;pq->size = 0;
}

📜2.2.10 队列所有接口的测试

TestQueue()
{Que obj;QueueInit(&obj);QueuePush(&obj, 1);QueuePush(&obj, 2);QueuePush(&obj, 3);QueuePush(&obj, 4);QueuePush(&obj, 5);printf("队尾元素:%d\n", QueueBack(&obj));printf("队列的有效数据个数:%d\n", QueueSize(&obj));while (!QueueEmpty(&obj)){printf("%d ", QueueFront(&obj));QueuePop(&obj);}//QueuePop(&obj);printf("\n队列的有效数据个数:%d\n", QueueSize(&obj));QueueDestroy(&obj);
}

测试1

当队列为空还在删时:
测试2

完整代码

*

《栈》

📙Stack.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//栈
typedef int STDataType;typedef struct Stack
{int* arr;int top;//栈顶int capacity;//容量
}ST;//初始化栈
void STInit(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//获取栈顶元素
STDataType STTop(const ST* ps);
//获取栈中有效元素的个数
int STSize(const ST* ps);
//检测栈是否为空
bool STEmpty(const ST* ps);
//销毁栈
void STDestroy(ST* ps);

📙Stack.c

#include "Stack.h"void STInit(ST* ps)
{assert(ps);ps->arr = NULL;ps->capacity = 0;ps->top = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);//检测容量if (ps->top == ps->capacity){//使用三目操作符来解决扩容问题int newcapacity = ps->capacit==0 ? 4 : ps->capacity*2;STDataType* tmp = (STDataType*)realloc(ps->arr, sizeof(STDataType)*newcapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->arr = tmp;ps->capacity = newcapacity;}//入栈ps->arr[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);//栈为空就不能再删了assert(ps->top > 0);ps->top--;
}STDataType STTop(const ST* ps)
{assert(ps);return ps->arr[ps->top-1];
}int STSize(const ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(const ST* ps)
{assert(ps);return ps->top == 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->capacity = 0;ps->top = 0;
}

*

《队列》

📙Queue.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//队列
typedef int QueDataType;typedef struct QueueNode
{QueDataType data;struct QueueNode* next;
}QNode;typedef struct Queue
{QNode* phead;QNode* tail;int size;
}Que;//初始化队列
void QueueInit(Que* pq);
//入队列
void QueuePush(Que* pq, QueDataType x);
//检测队列是否为空
bool QueueEmpty(Que* pq);
//出队列
void QueuePop(Que* pq);
//获取队列头部元素
QueDataType QueueFront(Que* pq);
//获取队列尾部元素
QueDataType QueueBack(Que* pq);
//获取队列中有效元素的个数
int QueueSize(Que* pq);
//销毁队列
void QueueDestroy(Que* pq);

📙Queue.c

#include"Queue.h"void QueueInit(Que* pq)
{assert(pq);pq->phead = NULL;pq->tail = NULL;pq->size = 0;
}void QueuePush(Que* pq, QueDataType x)
{assert(pq);//获取并初始化节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("newnode fail");exit(-1);}newnode->data = x;newnode->next = NULL;//入队列if (pq->phead == NULL){//链表为空pq->phead = newnode;pq->tail = newnode;}else{//链表不为空pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}bool QueueEmpty(Que* pq)
{assert(pq);return pq->phead == NULL;
}void QueuePop(Que* pq)
{assert(pq);//检测链表是否为空,为空就不能再删了assert(!QueueEmpty(pq));//出队列QNode* Next = pq->phead->next;free(pq->phead);pq->phead = Next;pq->size--;
}QueDataType QueueFront(Que* pq)
{assert(pq);//检测链表是否为空assert(!QueueEmpty(pq));return pq->phead->data;
}QueDataType QueueBack(Que* pq)
{assert(pq);//检测链表是否为空assert(!QueueEmpty(pq));return pq->tail->data;
}int QueueSize(Que* pq)
{assert(pq);return pq->size;
}void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* Next = cur->next;free(cur);cur = Next;}pq->phead = NULL;pq->tail = NULL;pq->size = 0;
}

*

《测试》

📙test.c

#include"Stack.h"
#include"Queue.h"void TestStack()
{ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);STPush(&s, 5);printf("栈的有效元素个数%d\n", STSize(&s));while (!STEmpty(&s)){printf("%d ", STTop(&s));STPop(&s);}//STPop(&s);printf("\n栈的有效元素个数%d\n", STSize(&s));STDestroy(&s);}TestQueue()
{Que obj;QueueInit(&obj);QueuePush(&obj, 1);QueuePush(&obj, 2);QueuePush(&obj, 3);QueuePush(&obj, 4);QueuePush(&obj, 5);printf("队尾元素:%d\n", QueueBack(&obj));printf("队列的有效数据个数:%d\n", QueueSize(&obj));while (!QueueEmpty(&obj)){printf("%d ", QueueFront(&obj));QueuePop(&obj);}//QueuePop(&obj);printf("\n队列的有效数据个数:%d\n", QueueSize(&obj));QueueDestroy(&obj);
}int main()
{TestStack();TestQueue();return 0;
}

相关文章:

【数据结构】-- 栈和队列

&#x1f407; &#x1f525;博客主页&#xff1a; 云曦 &#x1f4cb;系列专栏&#xff1a;数据结构 &#x1f4a8;吾生也有涯&#xff0c;而知也无涯 &#x1f49b; 感谢大家&#x1f44d;点赞 &#x1f60b;关注&#x1f4dd;评论 文章目录 前言一、栈&#x1f4d9;1.1 栈…...

使用SpringAop切面编程通过Spel表达式实现Controller权限控制

目录 参考一、概念SpEL表达式 二、开发引入包定义注解定义切面定义用户上下文 三、测试新建Service在方法上注解新建Service在类上注解运行 参考 SpringBoot&#xff1a;SpEL让复杂权限控制变得很简单 一、概念 对于在Springboot中&#xff0c;利用自定义注解切面来实现接口…...

Flutter:简单搞一个内容高亮

内容高亮并不陌生&#xff0c;特别是在搜索内容页面&#xff0c;可以说四处可见&#xff0c;就拿掘金这个应用而言&#xff0c;针对某一个关键字&#xff0c;我们搜索之后&#xff0c;与关键字相同的内容&#xff0c;则会高亮展示&#xff0c;如下图所示&#xff1a; 如上的效果…...

2023/08/10

文章目录 一、计算属性传参二、小程序、h5跳转其他平台授权三、封装popup弹窗四、实现保存海报五、下载图片和复制分享链接 一、计算属性传参 计算属性的值往往通过一个回调函数返回&#xff0c;但是这个回调函数是无法传递参数的&#xff0c;要想实现计算属性传参可以通过闭包…...

LeetCode 1289. 下降路径最小和 II:通俗易懂地讲解O(n^2) + O(1)的做法

【LetMeFly】1289.下降路径最小和 II&#xff1a;通俗易懂地讲解O(n^2) O(1)的做法 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-falling-path-sum-ii/ 给你一个 n x n 整数矩阵 arr &#xff0c;请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下…...

Coin Change

一、题目 Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money. For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-c…...

2023 8 -14链表OJ

&#x1f495;人面只今何处去&#xff0c;桃花依旧笑春风&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;详解链表OJ题 题目一&#xff1a;环形链表&#xff08;判断链表是否带环&#xff09; 题目描述&#xff1a; 画图分析&#xff1a; 代码实现&#x…...

大数据必回之LSM树

LSM树&#xff08;Log-Structured-Merge-Tree&#xff09;并不像B、红黑树一样是一颗严格的树状数据结构&#xff0c;它其实是一种存储结构&#xff0c;像HBase、RocksDB这些NoSQL存储都是采用LSM树。它是一种分层、有序、面向磁盘的数据结构&#xff0c;核心思想是顺序写性能远…...

Vue中的Object.defineProperty详解

Vue中的Object.defineProperty是一个比较重要的方法&#xff0c;它是可以定义对象中属性的一个方法&#xff0c;相比于在对象中直接定义的对象&#xff0c;它更具有灵活性。 直接定义对象中的属性是这样的&#xff1a; let person {name:张三,address:广东,age:12,} 而Object.…...

MySQL高阶知识点(一)一条SQL【更新】语句是如何执行的

一条SQL【更新】语句是如何执行的 首先&#xff0c;可以确定的说&#xff0c;【查询】语句的那一套流程&#xff0c;【更新】语句也是同样会走一遍&#xff0c;与查询流程不一样的是&#xff0c; 更新语句涉及到【事务】&#xff0c;就必须保证事务的四大特性&#xff1a;ACID&…...

threejs实现模型gltf的动画效果

确保加载模型后模型有animations属性。加载完模型后&#xff0c;在模型中定义mixer的变量值。 // 4、加入加载器 const loader new GLTFLoader(); loader.load("./model/gltf/RobotExpressive/RobotExpressive.glb", function (gltf) {// 赋值动画给mixermixer ne…...

Harmony创建项目ohpm报错

Harmony创建FA模型的项目时报如下错&#xff1a; The registry is empty - edit .ohpmrc file or use "ohpm config set registry your_registry" command to set registry.解决方法&#xff1a; File -> Settings -> Build,Execution,Deployment -> Ohpm …...

44 | 酒店预订及取消的数据分析

1.背景介绍 数据集来自Kaggle网站上公开的Hotel booking demand项目 该数据集包含了一家城市酒店和一家度假酒店的预订信息,包括预订时间、入住时间、成人、儿童或婴儿数量、可用停车位数量等信息。 数据集容量约为12万32 本次数据分析主要包含如下内容: 总览数据,完成对…...

物联网和不断发展的ITSM

物联网将改变社会&#xff0c;整个技术行业关于对机器连接都通过嵌入式传感器、软件和收集和交换数据的电子设备每天都在更新中。Gartner 预测&#xff0c;全球将有4亿台互联设备投入使用。 无论企业采用物联网的速度如何&#xff0c;连接设备都将成为新常态&#xff0c;IT服务…...

加了ComponentScan,但是feign接口无法注入的原因

正文 正确的注入 如果发现无法注入&#xff1a;看看启动类Application是否有加入注解&#xff1a;EnableFeignClients(AppConstant.BASE_PACKAGES) 注意&#xff1a;EnableFeignClients和ComponentScan是两个独立的扫描&#xff0c;所以&#xff0c;如果只配置了ComponentSca…...

C#Winform中DataGridView控件显示行号实例

本文演示C#Winform中如何给DataGridView控件显示行号。 首先创建winform项目,添加DataGridView控件,给控件添加两列。 修改CS代码: using System.Windows.Forms;namespace DataGridviewDemo {public partial class Form1 : Form{public Form1(){InitializeComponent();//添…...

Stable Diffusion WebUI安装和使用教程(Windows)

目录 下载Stable Diffusion WebUI运行安装程序&#xff0c;双击webui.bat界面启动插件安装&#xff08;github&#xff09;模型下载(有些需要魔法&#xff09;安装过程遇到的大坑总结参考的博客 整个过程坑巨多&#xff0c;我花了一个晚上的时间才全部搞定,本教程针对有编程基础…...

LeetCode 35题:搜索插入位置

题目 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2:…...

Linux系统中常见的几种软件包管理器

软件包管理器 DPKGAPT&#xff08;APT-GET&#xff09;RPMYUMDNF Linux软件包管理工具是一组命令的集合&#xff0c;其作用是在操作系统中提供安装、更新、删除及卸载软件的方法&#xff0c;同时提供对系统中所有软件状态信息的查询。不同的Linux发行版会有不同的包管理器&…...

python异步IO完全指南

原地址&#xff1a;https://flyingbyte.cc/post/async_io/ python异步IO完全指南 做为一种并行编程的範式&#xff0c;异步IO在Python中非常受重视&#xff0c;从Python3.4到3.7快速演进。 我们已经有多线程&#xff0c;多进程&#xff0c;并发&#xff08;concurrency&#x…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

表单设计器拖拽对象时添加属性

背景&#xff1a;因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...