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

【初阶数据结构篇】单链表的实现(赋源码)

文章目录

  • 单链表的实现
    • 代码位置
    • 概念与结构
      • 概念:
      • 结构:
    • 链表的性质
    • 链表的分类
    • 单链表的实现
      • 单链表的创建和打印及销毁
        • 单链表的创建
        • 单链表的打印
        • 单链表的销毁
      • 单链表的插入
        • 单链表头插
        • 单链表尾插
        • 单链表在指定位置之前插入数据
        • 单链表在指定位置之后插入数据
      • 单链表的删除
        • 单链表的头删
        • 单链表的尾删
        • 单链表在指定位置删除数据
        • 单链表在指定位置之后删除数据
      • 单链表的查找指定位置节点

单链表的实现

代码位置

[Gitee](sllist/sllist · petrichor/2024-summer-c-language - 码云 - 开源中国 (gitee.com))

概念与结构

概念:

​ 链表是⼀种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

​ 类比火车地铁,都是一节一节的

在这里插入图片描述

  • 淡季时车次的车厢会相应减少,旺季时车次的车厢会额外增加几节。只需要将火车里的某节车厢去掉/ 加上,不会影响其他车厢,每节车厢都是独立存在的。

在链表⾥,每节“⻋厢”是什么样的呢?
在这里插入图片描述

结构:

与顺序表不同的是,链表⾥的每节"⻋厢"都是独⽴申请下来的空间,我们称之为“结点/结点”。

结点的组成主要有两个部分:当前结点要保存的数据和保存下⼀个结点的地址(指针变量)。

  • 图中指针变量plist保存的是第⼀个结点的地址,我们称plist此时“指向”第⼀个结点,如果我们希望 plist“指向”第⼆个结点时,只需要修改plist保存的内容为0x0012FFA0。
  • 链表中每个结点都是独立申请的(即需要插⼊数据时才去申请⼀块结点的空间),我们需要通过指针 变量来保存下⼀个结点位置才能从当前结点找到下⼀个结点。

链表的性质

1、链式机构在逻辑上是连续的,在物理结构上不⼀定连续

2、结点⼀般是从堆上申请的

3、从堆上申请来的空间,是按照⼀定策略分配出来的,每次申请的空间可能连续,可能不连续


链表的分类

链表的结构⾮常多样,以下情况组合起来就有8种(2x2x2)链表结构

在这里插入图片描述

链表说明:

在这里插入图片描述

  • 虽然有这么多的链表的结构,但是我们实际中最常⽤还是两种结构:单链表和双向带头循环链表
    1. 无头单向非循环链表:结构简单,⼀般不会单独⽤来存数据。实际种更多是作为其他数据结构的⼦结构,如哈希桶、图的邻接表等等。另外这种结构在笔试⾯试中出现很多。
    2. 带头双向循环链表:结构最复杂,⼀般⽤在单独存储数据。实际中使⽤的链表数据结构,都是带头双向循环链表。但是这个结构虽然结构复杂,但是使⽤代码实现以后会发现结构会带来很多优势,实现反⽽简单了,在下一篇博客我们将进行双向链表的实现。

单链表的实现

即不带头单向不循环链表

单链表的创建和打印及销毁


SList.h(其中方法会一一讲到)

  • 定义链表结构
  • 将存储数据类型重命名(方便之后替换->例如我们要求单链表内存储char类型数据,只用改一行代码即可)
  • 函数的声明,声明的时候参数只需要类型就可以了,名字加不加都一样
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLTDataType;
typedef struct SListNode 
{SLTDataType data;struct SListNode* next;
}SLTNode;void creatlist();
SLTNode* SLTBuyNode(SLTDataType x);
void printlist(SLTNode*);//插入
void SLTPushBack(SLTNode**, SLTDataType);
void SLTPushFront(SLTNode**, SLTDataType);//删除
void SLTPopBack(SLTNode**);
void SLTPopFront(SLTNode**);//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);//指定位置插入数据
void SLTInsert(SLTNode**, SLTDataType, SLTNode*);
void SLTInsertAfter( SLTDataType, SLTNode*);//删除指定节点
void SLTErase(SLTNode**, SLTNode*);
void SLTEraseAfter(SLTNode*);//销毁链表
void SListDestroy(SLTNode**);

test.c

  • 用来测试我们写的函数(函数的调用)
  • 这一部分就是自己写的时候用的测试用例,随便什么都行

养成好习惯,写一个方法测试一次,不然找错误的时候会很痛苦😜

#include "sllist.h"
//实际操作中不会这么去创建链表
void creatlist()
{SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));node1->data = 1;SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));node2->data = 2;SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));node3->data = 3;SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));node4->data = 4;node1->next = node2;node2->next = node3;node3->next = node4;node4->next = NULL;SLTNode* plist = node1;printlist(plist);}void test1(){SLTNode* plist = NULL;//SLTPushBack(&plist, 1);//SLTPushBack(&plist, 2);//SLTPushBack(&plist, 3);//SLTPushBack(&plist, 4);SLTPushBack(NULL, 4);SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 4);SLTPushFront(&plist, 3);//SLTPopBack(&plist);//SLTPopBack(&plist);//SLTPopFront(&plist);//SLTPopFront(&plist);//SLTNode* m=SLTFind(plist, 3);//if (m!= NULL)//{//	printf("找到了\n");//}SLTInsert(&plist, 3, m);//SLTInsertAfter( 6, m);//	SLTErase(&plist, m);//SLTEraseAfter(m);SListDestroy(&plist);printlist(plist);}int main()
{//creatlist();test1();return 0;
}
单链表的创建

可以看到在creatlist中我们是先随便申请几个节点然后将他们首尾相连

但链表的性质是每个节点都是独立申请的,即我们有需要才去申请一块节点的空间,所以我们实际中我们不会这样创建链表,只需一开始创建一个链表结点类型的指针plist,并将其置为空,表示此时链表为空,之后需要的时候我们通过插入一个节点并始终保持plist指向单链表第一个节点即可。

单链表的打印
void printlist(SLTNode* phead)
{assert(phead);SLTNode* p1 = phead;while (p1){printf("%d ", p1->data);p1 = p1->next;}
}
  • 一般情况下,单链表已知的都是指向第一个节点的指针plist,因为我们只是打印不需要改变plist的指向,即不需要改变plist的值,所以我们用一级指针即可。
  • 基本思想仍是遍历

在这里插入图片描述

单链表的销毁
void SListDestroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* p1 = pcur;pcur = pcur->next;free(p1);p1 = NULL;}*pphead = NULL;
}

- 这里我们要改变plist的值了,所以传二级指针(其实也可以传一级,只不过在调用完后别忘了把plist置为空哦(❁´◡`❁))


单链表的插入

单链表头插

既然要插入我们就要先申请一块空间

SLTNode* SLTBuyNode(SLTDataType x)
{SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode));if (node == NULL){perror("malloc fail!");exit(1);}node->data = x;node->next = NULL;return node;
}
  • 将申请新节点的函数分装起来,便于调用
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}
  • 连接新节点和plist
  • 再让plist指向新节点
单链表尾插
void SLTPushBack(SLTNode** pphead , SLTDataType x)
{//申请新节点assert(pphead);SLTNode* newnode = SLTBuyNode(x);if (*pphead==NULL){*pphead = newnode;}else{SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}ptail->next = newnode;}
}
  • 分两种情况
    • 链表为空,plist直接指向新节点
    • 链表不为空,找尾节点再插入
单链表在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTDataType x, SLTNode* pos)
{assert(pphead && pos);if (pos == *pphead){SLTPushFront(pphead,x);}else{SLTNode* newnode = SLTBuyNode(x);SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}newnode->next = pos;prev->next = newnode;}
}
  • 分两种情况
    • 若是pos和plist相同,说明就是头插,调用即可
    • 第二种情况,找到pos之前一个节点,一定要先改newnode的next指针,否则找不到pos下一个节点了
单链表在指定位置之后插入数据
void SLTInsertAfter( SLTDataType x, SLTNode* pos)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}
  • 还是记得先改插入进来newnode的next指针

单链表的删除

单链表的头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}
  • 删除都别忘了判断链表是否为空,即plist是否为空
单链表的尾删
void SLTPopBack(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* ptail = *pphead;SLTNode* prev = NULL;while (ptail->next){prev = ptail;ptail = ptail->next;}if (prev)//处理只有一个节点的情况{prev->next = NULL;prev=NULL;}else*pphead = NULL;free(ptail);ptail = NULL;
}
  • 同样分两种情况

    • 链表多于一个节点时,找尾节点以及其前一个节点,将尾节点释放并把前一个节点next指针置为空

    • 当链表只有一个节点时,不需要将前一个节点next指针置为空,此时需要将plist置为空

单链表在指定位置删除数据
void SLTErase(SLTNode** pphead, SLTNode* pos )
{assert(pos && pphead&&*pphead);if (pos == *pphead){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}
  • 分两种情况
    • pos和plist相同,即为头删
    • 第二种情况,先找到pos之前节点,再进行指针的更改即可
单链表在指定位置之后删除数据
void SLTEraseAfter( SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;	
}
  • 先保存pos之后节点,改变pos的next指针后再释放del

单链表的查找指定位置节点

SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{assert(phead);SLTNode* pcur = phead;while (pcur){if (pcur->data==x){return pcur;}pcur = pcur->next;}return NULL;
}
  • 找到就返回指向节点的指针,否则返回空
  • 老规矩遍历就行了

SList.c(完整版)

#define _CRT_SECURE_NO_WARNINGS 1
#include "sllist.h"
void printlist(SLTNode* phead)
{SLTNode* p1 = phead;while (p1){printf("%d ", p1->data);p1 = p1->next;}
}SLTNode* SLTBuyNode(SLTDataType x)
{SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode));if (node == NULL){perror("malloc fail!");exit(1);}node->data = x;node->next = NULL;return node;
}void SLTPushBack(SLTNode** pphead , SLTDataType x)
{//申请新节点assert(pphead);SLTNode* newnode = SLTBuyNode(x);if (*pphead==NULL){*pphead = newnode;}else{SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}ptail->next = newnode;}
}void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}void SLTPopBack(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* ptail = *pphead;SLTNode* prev = NULL;while (ptail->next){prev = ptail;ptail = ptail->next;}if (prev)//处理只有一个节点的情况prev->next = NULL;else*pphead = NULL;free(ptail);ptail = NULL;
}void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{assert(phead);SLTNode* pcur = phead;while (pcur){if (pcur->data==x){return pcur;}pcur = pcur->next;}return NULL;}void SLTInsert(SLTNode** pphead, SLTDataType x, SLTNode* pos)
{assert(pphead && pos);if (pos == *pphead){SLTPushFront(pphead,x);}else{SLTNode* newnode = SLTBuyNode(x);SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}newnode->next = pos;prev->next = newnode;}
}void SLTInsertAfter( SLTDataType x, SLTNode* pos)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}void SLTErase(SLTNode** pphead, SLTNode* pos )
{assert(pos && pphead&&*pphead);if (pos == *pphead){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}void SLTEraseAfter( SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;	
}void SListDestroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* p1 = pcur;pcur = pcur->next;free(p1);p1 = NULL;}*pphead = NULL;
}

在单链表实现的函数中,特别有两点要注意:

1. 涉及到plist(指向第一个节点的指针)的指向改变时,一定记得传plist的地址,使用二级指针
2. 在尾插/尾删中,都需要依据链表是否为空/链表是否多于一个节点来分情况讨论,目的是避免对空指针进行解引用造成的错误。

以上就是单链表的实现方法啦,各位大佬有什么问题欢迎在评论区指正,您的支持是我创作的最大动力!❤️

请添加图片描述

相关文章:

【初阶数据结构篇】单链表的实现(赋源码)

文章目录 单链表的实现代码位置概念与结构概念&#xff1a;结构&#xff1a; 链表的性质链表的分类单链表的实现单链表的创建和打印及销毁单链表的创建单链表的打印单链表的销毁 单链表的插入单链表头插单链表尾插单链表在指定位置之前插入数据单链表在指定位置之后插入数据 单…...

LeetCode 2844.生成特殊数字的最少操作(哈希表 + 贪心)

给你一个下标从 0 开始的字符串 num &#xff0c;表示一个非负整数。 在一次操作中&#xff0c;您可以选择 num 的任意一位数字并将其删除。请注意&#xff0c;如果你删除 num 中的所有数字&#xff0c;则 num 变为 0。 返回最少需要多少次操作可以使 num 变成特殊数字。 如…...

昇思MindSpore 应用学习-基于 MindSpore 实现 BERT 对话情绪识别

基于 MindSpore 实现 BERT 对话情绪识别 模型简介 BERT全称是来自变换器的双向编码器表征量&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;&#xff0c;它是Google于2018年末开发并发布的一种新型语言模型。与BERT模型相似的预训练语言模…...

【初阶数据结构篇】顺序表和链表算法题

文章目录 顺序表算法题移除元素删除有序数组中的重复项合并两个有序数组 链表算法题移除链表元素反转链表链表的中间结点合并两个有序链表链表分割链表的回文结构 顺序表算法题 不熟悉顺序表的可以先了解一下 顺序表实现方法 移除元素 给你一个数组 nums 和一个值 val&#x…...

使用weex进行APP混合开发

Weex 是一个用于构建高性能原生应用的框架&#xff0c;它使用 Vue.js 的语法和组件模型&#xff0c;允许开发者使用 HTML、CSS 和 JavaScript 来编写应用&#xff0c;同时能够编译成原生应用。Weex 主要由阿里巴巴集团开发&#xff0c;并且已经被多个公司采用。 下面是使用 We…...

C++stl大根堆/小根堆的创建与记忆

priority_queue<int, vector<int>, greater<int>> heap; 这行代码在 C 中声明了一个优先队列 heap&#xff0c;其元素类型为 int&#xff0c;使用 vector<int> 作为其底层容器&#xff0c;并且指定了 greater<int> 作为比较函数对象。 这里的关…...

visual studio性能探测器使用案列

visual studio性能探测器使用案列 在visual studio中&#xff0c;我们可以使用自带的工具对项目进行性能探测&#xff0c;具体如下 1.选择性能探查器 Vs2022/Vs2019中打开方式&#xff1a; Vs2017打开方式&#xff1a; 注意最好将解决方案配置为&#xff1a;Release Debu…...

redis的代码开发

redis是什么? 前提:官网地址https://redis.io 1.Redis是一个开源的,key,value格式的,内存型数据结构存储系统;它可用作数据库、缓存和消息中间件。 value支持多种类型的数据结构如strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglo…...

嗷呜,就问你接不接?

...

避免过拟合,参数大模型强,正则让模型不要走偏

1、加入惩罚项L1【绝对值】 和L2【默认 平方】&#xff0c;降低噪音的影响&#xff0c;减少权重W的值 2、丢弃法 层与层之间加入噪音&#xff0c;只能在全连接层使用 无偏差加入噪音 p为丢弃的概率 x 当概率p是0 否则为除以(1-p) 丢弃概率p 一般为0.1 0.5 def drop_out(x…...

vue+element-ui的列表查询条件/筛选条件太多以下拉选择方式动态添加条件(支持全选、反选、清空)

1、此功能已集成到TQueryCondition组件中 2、最终效果 3、具体源码(新增moreChoose.vue) <template><el-popoverpopper-class"t_query_condition_more":bind"popoverAttrsBind"ref"popover"v-if"allcheckList.length>0"…...

LLM的训练与推断

LLM的训练与推断 目前比较流行的大模型一般都是自回归模型。在推理时&#xff0c;它类似于RNN&#xff0c;每次计算下一个token的概率。也就是说&#xff0c;如果除去最开始的输入情况下&#xff0c;最终推理长度为n的话&#xff0c;就需要计算n次。但是训练却是并行化的。 在…...

uniapp使用WebSocket uniapp使用WebSocket Uniapp整合WebSocket uniapp使用 websocket

uniapp使用WebSocket uniapp使用WebSocket Uniapp整合WebSocket uniapp使用 websocket 前言1、Socket.js2、main.js引入3、组件中调用 前言 代码中的示例只在 H5、APP环境下成功运行&#xff0c;小程序环境下如果无效&#xff0c;需要使用预编译 - 条件性的编译&#xff0c;适…...

SSH Exporter:基于Prometheus的远程系统性能监控神器

SSH Exporter English | 中文 介绍 SSH Exporter 是一个基于 Prometheus 规范的监控工具&#xff0c;通过 SSH 协议远程收集目标服务器的系统性能数据&#xff0c;如 CPU 使用率、内存使用情况、磁盘和网络 I/O 等&#xff0c;并将这些数据暴露为 Prometheus 格式的 metrics…...

Docker基础概念

Docker 是一个流行的容器化平台&#xff0c;它使开发者能够打包他们的应用程序及其依赖项到一个轻量级、可移植的容器中。这有助于确保应用程序无论在哪里运行都能获得一致的结果。以下是 Docker 的几个基础概念的详细解释&#xff1a; 1. Docker 镜像 (Image) 定义: Docker …...

小白进阶为大神

编程已成为当代大学生的必备技能&#xff0c;但面对众多编程语言和学习资源&#xff0c;新生们常常感到迷茫。如何选择适合自己的编程语言&#xff1f;如何制定有效的学习计划&#xff1f;如何避免常见的学习陷阱&#xff1f;今天&#xff0c;我就来分享一下这方面的经验和知识…...

2024最新Python和PyCharm的安装教程

Python和PyCharm的安装教程如下&#xff1a; Python安装教程 一、下载Python安装包 访问Python官方网站&#xff1a;Welcome to Python.org。 点击页面上方的“Downloads”链接。 在下载页面&#xff0c;选择“Windows”系统&#xff08;以Windows系统为例&#xff09;&…...

数据库死锁:深入解析与应对策略

在数据库管理系统中&#xff0c;死锁是一个常见且棘手的问题&#xff0c;它可能导致系统性能下降、事务延迟甚至完全阻塞。本文将深入探讨数据库死锁的概念、产生原因、检测方法以及预防与解决策略&#xff0c;帮助读者更好地理解和应对这一挑战。 一、什么是数据库死锁&#…...

Python入门宝藏《看漫画学Python》,495页漫画带你弄清python知识点!简单易懂 | 附PDF全彩版

华为出品的《看漫画学Python》全彩PDF教程是一本适合Python初学者的学习资料&#xff0c;通过漫画的形式将复杂的Python技术问题简单化&#xff0c;使学习过程更加生动有趣。以下是对该教程的内容简介、本书概要及本书目录的详细解析&#xff1a; 内容简介 《看漫画学Python》…...

Webshell管理工具:AntSword(中国蚁剑)

中国蚁剑是一款开源的跨平台网站管理工具&#xff0c;它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。 通俗的讲&#xff1a;中国蚁剑是 一 款比菜刀还牛的shell控制端软件。 一、中国蚁剑下载 1. 下载 AntSword-Loader https://github.com/AntSwordP…...

Simulink SVPWM模块输出对不上?别慌,可能是这两个参数没设对(附24V电机FOC仿真案例)

Simulink SVPWM模块输出差异排查指南&#xff1a;从参数配置到波形修正 引言 在电机控制系统的仿真与开发过程中&#xff0c;Simulink的SVPWM模块是工程师们常用的工具之一。然而&#xff0c;许多开发者在对比自带模块与自建模型输出时&#xff0c;经常会遇到令人困惑的波形不一…...

Nano-Banana Studio惊艳效果:高分辨率(1024x1024)运动服爆炸图细节展示

Nano-Banana Studio惊艳效果&#xff1a;高分辨率&#xff08;1024x1024&#xff09;运动服爆炸图细节展示 1. 开篇&#xff1a;当AI遇见设计拆解 你有没有遇到过这样的情况&#xff1a;想要展示一件运动服的所有设计细节&#xff0c;却不知道从哪里开始&#xff1f;传统的产…...

壁仞科技上市后首次年报:2025年营收10亿 经调整亏损8.7亿

雷递网 雷建平 3月30日上海壁仞科技股份有限公司&#xff08;股份代号&#xff1a;6082&#xff09;今日发布截至2025年12月31日的财报。财报显示&#xff0c;壁仞科技2025年营收为10.35亿元&#xff0c;较上年同期的3.37亿元增长207.2%。壁仞科技2025年毛利为5.57亿元&#xf…...

2026年的具身智能:不再“讲故事”,而是拼“分数”?

作者&#xff1a;刘致呈编辑&#xff1a;Evin审核&#xff1a;徐徐出品&#xff1a;互联网江湖最近&#xff0c;具身智能行业发生了两件大事:一是行业标杆——宇树科技要IPO了。二是中国信息通信研究院联合40余家单位共同起草的具身智能领域首个行业标准&#xff0c;正式发布了…...

Claude Code 命令和用法

斜杠命令&#xff08;会话内输入 / 触发&#xff09;会话与导航命令说明/clear清除对话历史&#xff0c;释放上下文。别名&#xff1a;/reset、/new/compact [指令]压缩对话&#xff0c;可附加聚焦指令/resume [会话]恢复历史会话。别名&#xff1a;/continue/rename [名称]重命…...

千问3.5-2B镜像实战:免conda/pip安装,网页端直接调用内置视觉语言模型

千问3.5-2B镜像实战&#xff1a;免conda/pip安装&#xff0c;网页端直接调用内置视觉语言模型 1. 镜像介绍与核心能力 千问3.5-2B是Qwen系列中的轻量级视觉语言模型&#xff0c;专为图片理解和文本生成任务优化。这个预置镜像的最大特点是开箱即用——无需任何conda或pip安装…...

Phi-4-reasoning-vision-15B部署教程:开源大模型镜像适配国产GPU方案

Phi-4-reasoning-vision-15B部署教程&#xff1a;开源大模型镜像适配国产GPU方案 1. 模型介绍 Phi-4-reasoning-vision-15B是微软推出的视觉多模态推理模型&#xff0c;具备强大的图像理解和分析能力。这个15B参数规模的模型特别擅长处理需要结合视觉和语言理解的复杂任务。 …...

实战应用:基于快马平台ai,开发并部署一个功能齐全的instagram内容下载web应用

今天想和大家分享一个实战项目&#xff1a;基于InsCode(快马)平台快速开发并部署一个功能完备的Instagram内容下载Web应用。这个项目从需求分析到上线只用了不到半天时间&#xff0c;特别适合想验证产品原型的开发者。 项目需求分析 首先明确核心功能需求&#xff1a;需要支持I…...

MedGemma 1.5新手必看:从安装到问诊,完整使用流程详解

MedGemma 1.5新手必看&#xff1a;从安装到问诊&#xff0c;完整使用流程详解 你是否曾面对一份复杂的化验单&#xff0c;需要快速理解其临床意义&#xff1f;是否在深夜值班时&#xff0c;想快速确认某个药物的相互作用&#xff1f;或者&#xff0c;作为一名医学生&#xff0…...

AD快捷键避坑指南:为什么你的自定义快捷键总是不生效?

AD快捷键避坑指南&#xff1a;为什么你的自定义快捷键总是不生效&#xff1f; 在AD&#xff08;Altium Designer&#xff09;这个功能强大的电子设计自动化软件中&#xff0c;快捷键是提升工作效率的利器。但很多用户都遇到过这样的困扰&#xff1a;明明按照教程设置了自定义快…...