目录

  • 一. 前言
  • 二. 顺序表
    • 1. 顺序表的特点
    • 2. 代码实现
  • 三. 链表
    • 1. 单向链表代码实现
    • 2.双向链表代码实现
  • 四. 顺序表与链表的区别
  • 总结

一. 前言

顺序表和链表是最基础的两种线性表实现方式。它们各有特点,适用于不同的应用场景。本文将详细介绍这两种数据结构的实现原理、C语言代码实现以及它们的优缺点对比。


二. 顺序表

顺序表是用一段连续的物理地址依次存储数据元素的线性结构,采用数组存储。
在这里插入图片描述


1. 顺序表的特点

优点:

  • 可以通过下标直接访问元素
  • 不需要额外的空间存储元素之间的关系

缺点:

  • 会造成一定的空间浪费
  • 插入删除效率低

2. 代码实现

  • 申请空间时,在无法确定空间大小时我们需要动态申请空间。
//将int重命名为SLTDatatype
typedef int SLTDatatype;
//顺序表创建一个结构体
typedef struct SeqList
{SLDataType* arr;  //存储数组的指针int size;         //有效个数int capacity;     //最大容量
}SL;
  • 初始化和销毁顺序表
//初始化顺序表
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}//销毁顺序表
void SLDestroy(SL* ps)
{if(ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = ps->capacity = 0;
}
  • 空间不足时开辟空间
//空间为空时开辟四个空间,不为空空间装满时扩大二倍
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//增容SLTDataType* tmp = (SLTDataType*)realloc(ps->arr, newCapacity * sizeof(SLTDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}
}
  • 插入数据

尾插:在判断空间足够时直接size位置插入然后size++;
头插:通过循环把元素全部向后移一位,把插入的数据放在下标为0的位置,size++;

//尾插
void SLPushBack(SL* ps, SLTDataType x)
{assert(ps);//进入函数判断空间是否足够SLCheckCapacity(ps);//空间足够在队尾插入数据,把size加一ps->arr[ps->size++] = x;
}//头插
void SLPushFront(SL* ps, SLTDataType x)
{assert(ps);//进入函数判断空间是否足够SLCheckCapacity(ps);//将数据整体向后挪动一位for (int i = ps->size; i > 0 ; i--){ps->arr[i] = ps->arr[i - 1];}//把数据插入在下标为0的位置上ps->arr[0] = x;ps->size++;
}
  • 删除数据

尾删:通过size–,限制下标访问;
头删:通过循环从下标为1开始向前移动一位,size–;

//尾删
void SLPopBack(SL* ps)
{assert(ps && ps->size);ps->size--;
}//头删
void SLPopFront(SL* ps)
{assert(ps && ps->size);//数据整体向前挪动一位for (int i = 0; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
  • 查找指定值
//通过遍历数组来查找 返回下标
int SLFind(SL* ps, SLTDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){//找到了return i;}}//未找到return -1;
}
  • 指定位置插入数据

pos位置前插入和pos位置后插入都是通过循环把元素后移然后在指定位置下标插入;

//指定位置之前插入数据
//pos为指定位置的下标
void SLInsert(SL* ps, int pos, SLTDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);//判断空间是否足够SLCheckCapacity(ps);//pos及之后数据向后挪动一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}//指定位置之后插入数据
SLInsertAfter(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);//pos之前的数据向后挪动一位for (int i = ps->size;i > pos+1;i--){ps->arr[i] = ps->arr[i-1];}ps->arr[pos+1] = x;ps->size++;
}
  • 删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//pos后面的数据向前挪动一位for (int i = pos; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
  • SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//定义动态顺序表的结构
typedef int SLTDataType;
//顺序表创建一个结构体
typedef struct SeqList 
{SLTDataType* arr;  //存储数据int size;  //有效数据个数int capacity; //空间大小
}SL;//初始化顺序表
void SLInit(SL* ps);
//销毁顺序表
void SLDestroy(SL* ps);void SLPrint(SL* ps);
//尾插
void SLPushBack(SL* ps, SLTDataType x);
//头插
void SLPushFront(SL* ps, SLTDataType x);//尾删
void SLPopBack(SL* ps);
//头删
void SLPopFront(SL* ps);//查找
int SLFind(SL* ps, SLTDataType x);
//指定位置之前插⼊数据
void SLInsert(SL* ps, int pos, SLTDataType x);
//指定位置之后插入数据
void SLInsertAfter(SL* ps, int pos, SLTDataType x);
//删除pos位置的数据
void SLErase(SL* ps, int pos);
  • SeqList.c
#include"SeqList.h"//初始化顺序表
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}//销毁顺序表
void SLDestroy(SL* ps)
{if(ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = ps->capacity = 0;
}//打印顺序表的数据
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}//空间为空时开辟四个空间,不为空空间装满时扩大二倍
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//增容SLTDataType* tmp = (SLTDataType*)realloc(ps->arr, newCapacity * sizeof(SLTDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}
}//队尾插入数据
void SLPushBack(SL* ps, SLTDataType x)
{assert(ps);//进入函数判断空间是否足够SLCheckCapacity(ps);//空间足够在队尾插入数据,把size加一ps->arr[ps->size++] = x;
}//队头插入数据
void SLPushFront(SL* ps, SLTDataType x)
{assert(ps);//进入函数判断空间是否足够SLCheckCapacity(ps);//将数据整体向后挪动一位for (int i = ps->size; i > 0 ; i--){ps->arr[i] = ps->arr[i - 1];}//把数据插入在下标为0的位置上ps->arr[0] = x;ps->size++;
}//通过遍历数组来查找 返回下标
int SLFind(SL* ps, SLTDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){//找到了return i;}}//未找到return -1;
}//指定位置之前插入数据
//pos为指定位置的下标
void SLInsert(SL* ps, int pos, SLTDataType x)
{assert(ps);assert(pos >= 0 && pos < ps->size);//判断空间是否足够SLCheckCapacity(ps);//pos及之后数据向后挪动一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}//指定位置之后插入数据
SLInsertAfter(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);//pos之前的数据向后挪动一位for (int i = ps->size;i > pos+1;i--){ps->arr[i] = ps->arr[i-1];}ps->arr[pos+1] = x;ps->size++;
}//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//pos后面的数据向前挪动一位for (int i = pos; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

三. 链表

链表是一种非连续、非顺序的存储结构,通过指针将一组零散的内存块串联起来。常见的链表有单链表、双向链表和循环链表。
在这里插入图片描述


1. 单向链表代码实现

  • SList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLTDataType;
//定义结构体
typedef struct SListNode
{SLTDataType data;//节点的值struct SListNode *next;//指向下一个节点的指针
}SLTNode;//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);//尾删
void SLTPopBack(SLTNode** pphead);
//头删
void SLTPopFront(SLTNode** pphead);//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* phead, SLTDataType x);//删除指定pos节点位置的数据
void SLTErase(SLTNode** pphead, SLTNode* pos);
//删除指定pos节点位置之后的数据
void SLTEraseAfter(SLTNode* pos);//销毁链表
void SLisDesTroy(SLTNode** pphead);//打印链表
void SLTPrint(SLTNode** pphead);
  • SList.c
#include "SList.h"//申请节点
SLTNode*  STLBuyNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){printf("申请内存失败!");exit(1);}newnode->data = x;newnode->next = NULL;return newnode;
}
//打印链表
void SLTPrint(SLTNode* pphead)
{SLTNode* ptail = pphead;while (ptail){printf("%d->", ptail->data);ptail = ptail->next;}printf("NULL\n");
}

尾插:通过循环遍历到最后一个节点,把最后一个节点指向插入的节点;
头插:将插入的节点指向头节点,再把插入节点改为头节点;

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);//*pphead 是指向第一个节点的指针SLTNode* newnode = STLBuyNode(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 = STLBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}

尾删:循环遍历到最后一个节点,free释放掉节点;
头删:创建一个指向头节点下一节点的位置,再free释放掉节点

//尾删
void SLTPopBack(SLTNode** pphead)
{assert(pphead && *pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLTNode* prev = *pphead;SLTNode* ptail = *pphead;while (ptail->next){prev = ptail;ptail = ptail->next;}free(ptail);ptail = NULL;//prev->next = NULL;}}
//头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode *ptail = *pphead;*pphead = ptail->next;free(ptail);ptail = NULL;
}
//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* pcur = phead;while (pcur){if (pcur->data == x){return pcur;}pcur = pcur->next;}return NULL;
}//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead && pos && *pphead);SLTNode* newnode = STLBuyNode(x);if (pos== *pphead){SLTPushFront(pphead, x);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}newnode->next = pos;prev->next = newnode;}
}//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* phead, SLTDataType x)
{assert(phead);SLTNode* newnode = STLBuyNode(x);newnode->next = phead->next;phead->next = newnode;
}//删除指定pos节点位置的数据
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && pos && *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节点位置之后的数据
void SLTEraseAfter(SLTNode* pos)
{assert(pos&&pos->next);SLTNode* del = pos->next;pos->next = del->next;free(del);del = NULL;
}//销毁链表
void SLisDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

2.双向链表代码实现

这里示例的是双向带头循环链表
双向链表我们在前面加上一个头节点head,next指向下一个节点的指针,prev指向上一个节点的指针。
在这里插入图片描述


  • List.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//定义双向链表结构
typedef int LTDataType;
typedef struct ListNode {LTDataType data;struct ListNode* next; //指向下一个节点的指针struct ListNode* prev; //指向前一个节点的指针
}LTNode;//初始化
LTNode* LTInit();
//销毁---为了保持接口一致性
void LTDesTroy(LTNode* phead);
//在双向链表中,增删改查都不会改变头节点
//尾插
void LTPushBack(LTNode* phead, LTDataType x);
//头插
void LTPushFront(LTNode* phead, LTDataType x);
//尾删
void LTPopBack(LTNode* phead);
//头删
void LTPopFront(LTNode* phead);
//判断是否为空
bool LTEmpty(LTNode* phead);
//打印
void LTPrint(LTNode* phead);
//查找
LTNode* LTFind(LTNode* phead, LTDataType x);
//在pos位置之后插⼊数据
void LTInsert(LTNode* pos, LTDataType x);//删除pos位置的节点
void LTErase(LTNode* pos);

尾插:

phead = 头节点; phead->prev = 尾节点; newnode = 插入节点;
1. newnode->prev = phead->prev; 插入节点的prev指向尾节点
2. newnode->next = phead; 插入节点的next指向头节点
3. phead->prev->next = newnode;改变尾节点next指向插入节点
4. phead->prev = newnode; 改变头节点prev指向插入节点

在这里插入图片描述

//尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);//phead phead->prev newnodenewnode->prev = phead->prev;newnode->next = phead;phead->prev->next = newnode;phead->prev = newnode;
}

头插:

phead = 头节点; newnode = 插入节点 ; phead->next = 尾节点;
1. newnode->next = phead->next; 插入节点的next指向头节点指向的下一个节点
2. newnode->prev = phead; 插入节点的prev指向头节点
3. phead->next->prev = newnode;头节点指向下一个节点的prev指向插入节点
4. phead->next = newnode; 头节点的next指向插入节点

在这里插入图片描述

//头插
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);//phead newnode phead->nextnewnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}

尾删:

1. LTNode* del = phead->prev;创建一个指针指向头节点的prev
2. del->prev->next = phead; 将del上一个的next指向头节点
3. phead->prev = del->prev; 将头节点的prev指向del的prev
4. 最后释放节点free(del)

在这里插入图片描述

//尾删
void LTPopBack(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->prev;del->prev->next = phead;phead->prev = del->prev;free(del);del = NULL;
}

头删:

1. LTNode* del = phead->next;创建一个指针指向头节点的next
2. del->next->prev = phead; 将del下一个的prev指向头节点
3. phead->next = del->next; 将头节点的next指向del的next
4. 最后释放节点free(del)

在这里插入图片描述

//头删
void LTPopFront(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->next;del->next->prev = phead;phead->next = del->next;free(del);del = NULL;
}
  • List.c
#include"List.h"
//申请节点
LTNode* LTBuyNode(LTDataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = newnode->prev = newnode;return newnode;
}//初始化
LTNode* LTInit()
{LTNode* phead = LTBuyNode(-1);return phead;
}
//销毁
void LTDesTroy(LTNode* phead)
{LTNode* pcur = phead->next;while (pcur != phead){LTNode* next = pcur->next;free(pcur);pcur = next;}//销毁头结点free(phead);phead = NULL;
}
//打印
void LTPrint(LTNode* phead)
{LTNode* pcur = phead->next;while (pcur != phead){printf("%d -> ", pcur->data);pcur = pcur->next;}printf("\n");
}
//判断是否为空
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}
//查找
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x){return pcur;}pcur = pcur->next;}//未找到return NULL;
}//在pos位置之后插⼊数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);//pos newnode pos->nextnewnode->prev = pos;newnode->next = pos->next;pos->next->prev = newnode;pos->next = newnode;
}//删除pos位置的节点
void LTErase(LTNode* pos)
{assert(pos);//pos->prev pos pos->nextpos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

四. 顺序表与链表的区别

特性顺序表单向链表双向链表
内存布局连续的空间节点通过指针链接,内存不连续节点通过两个指针链接,内存不连续
访问方式随机访问(通过下标直接访问)O(1)顺序访问(从头节点开始遍历)O(n)随机访问(可以正向和反向遍历)O(n)
插入/删除需要移动元素O(n)只需修改指针指向O(1)只需修改指针指向O(1)
内存占用仅存储数据每个节点存储的数据和指向下一个节点的指针每个节点存储数据和两个指针
适用场景需要频繁的随机访问需要频繁的插入和删除,且不需要随机访问需要频繁插入和删除,且需要双向遍历的场景

总结

本篇文章到这里就结束啦!通过前面的介绍,相信大家对顺序表、单向链表和双向链表都有了更清晰的认识。顺序表凭借其高效的随机访问能力,在对数据快速定位有较高要求的场景中发挥着关键作用;单向链表以其灵活的插入和删除操作,在数据频繁变动且无需随机访问的情境下展现出优势;双向链表则在兼具单向链表灵活性的基础上,通过支持双向遍历,进一步拓展了应用范围。文章中如果大家发现有不对的地方可以直接指出,博主会积极改正。还希望大家多多谅解,最后感谢大家的点赞、收藏、评论和收藏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/92856.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/92856.shtml
英文地址,请注明出处:http://en.pswp.cn/web/92856.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitHub的简单使用方法----(4)

在安装完git之后&#xff0c;桌面右键会出现两个git的选项第一个gui打开是这样的用户界面分别是新建仓库&#xff0c;克隆仓库&#xff0c;打开已经存在的仓库。tips:Git Gui 默认只能操作本地仓库——它本质上是一个图形化的“本地 Git 客户端”。 它本身不内置“下载远程仓库…

蓝桥杯----大模板

在写大模板之前&#xff0c;先讲一个函System_Init()&#xff0c;用于系统初始化关闭所有LED与外设&#xff0c;关闭所有LED就是传入0xff数据打开锁存器&#xff0c;关闭外设就是传入0x00打开锁存器。现在所有底层已经提供给大家了&#xff0c;先提供最简单版本的大模板&#x…

科技写作改革我见:取消参考文献,以点读率取代引证率!

科技写作改革我见&#xff1a;综述应取消参考文献&#xff0c;学术成就评估以点读下载率取代参考文献引证率&#xff01;李升伟 张君飞 韩若兰引言在当今信息爆炸的时代&#xff0c;科技写作作为知识传播的核心载体&#xff0c;其形式与评价体系正面临前所未有的挑战。传统…

【Altium designer】快速建立原理图工程的步骤

快速建立原理图工程的步骤产品规格书分析 整理产品需求&#xff0c;明确主控芯片、外围接口类型、总线频率、电源需求及隔离要求、PCB尺寸等关键信息。使用文本清单列出所有需求&#xff0c;确保无遗漏。硬件需求架构图绘制 根据需求说明书和收集的信息&#xff0c;使用VISIO绘…

Origin2025b安装包免费,附Origin 2025安装教程

老规矩先放链接&#xff1a;origin2025b安装包 有位小粉丝问我有没有Origin2025b的安装包&#xff0c;有的兄弟有的&#xff0c;只有你想不到&#xff0c;没有小兔找不到的软件。 这个origin是OriginLab公司开发的一个科学绘图、数据分析的软件&#xff0c;Origin支持各种各样…

【C++语法】输出的设置 iomanip 与 std::ios 中的流操纵符

文章目录【C语法】输出的设置 iomanip 与 std::ios 中的流操纵符1. iomanip 中的流操纵方法1.1 位宽操作类1.1.1 std::setw(x)1.1.2 std::setfill(c)1.1.3 std::left1.1.4 std::right1.1.5 std::internal1.2 小数操作类1.2.1 std::fixed1.2.2 std::setprecision(x)1.2.3 std::s…

go语言学习笔记-Map

map 是一种无序的基于 key-value 的数据结构&#xff0c;Go 语言中的 map 是引用类型&#xff0c;必须初始化 才能使用。 Go 语言中 map 的定义语法如下map[KeyType]ValueType常见两种创建方法1 使用map初始化var scoreMap make(map[string]int, 8) scoreMap["陈翔"…

芯片安全标准驱动库,筑牢芯片功能安全基石

随着整车控制器功能日益复杂&#xff0c;为满足越发严格的功能安全认证要求&#xff0c;项目开发人员需要采取相应的安全措施对系统中电子元器件的单点故障&#xff08;Singel Point Fault&#xff09;和潜在故障&#xff08;Latent Fault&#xff09;进行检测和管理&#xff0…

rn相关ScrollView

一&#xff1a;ScrollView的style和contentContainerStyle二&#xff1a;flex:1,和flexGrow:1用处内容将纵向空间占满

Spark Core 3.3.2 略讲~

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;大数据、Java、测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/…

智能家居Agent:物联网设备的统一控制与管理

智能家居Agent&#xff1a;物联网设备的统一控制与管理 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0c;每一个特性都是我放飞的…

汉高携手SAP推出AI驱动的退换货与争议管理解决方案

2025年8月12日&#xff0c;SAP宣布与全球知名的胶黏剂、密封剂及消费品制造商汉高&#xff08;Henkel AG & Co. KGaA&#xff09;联合开发了一套基于SAP AI Services的定制化解决方案&#xff0c;用于优化退换货及争议管理流程。该方案旨在通过人工智能自动化索赔相关文件的…

[SC]SystemC中的SC_FORK和SC_JOIN用法详细介绍

SystemC中的SC_FORK和SC_JOIN用法详细介绍 摘要:SystemC是一个开源的C++库(由Accellera和IEEE标准化,IEEE 1666-2011),用于系统级建模、硬件描述和仿真。它扩展了C++以支持硬件概念,如模块(sc_module)、端口(sc_port)、信号(sc_signal)和进程(SC_METHOD、S…

工作流调度(草稿)

串行回复当我加上第三条分支&#xff0c;此时的输出就很混乱了&#xff0c;按理来说最后输出的第二波输出反而先结束了&#xff0c;调用LLM结果的第一波输出最后才输出&#xff0c;这是为什么&#xff1f;当我把LLM节点改为一个不耗时的节点的时候&#xff1a;初步猜测&#xf…

AI不再停留在概念阶段,而是在各行业核心业务场景产生实际价值。随着大模型、边缘计算等技术的突破,AI应用将向实时化、自主化、普惠化方向深度演进。

一、金融领域&#xff1a;智能风控与欺诈检测案例&#xff1a;某银行使用AI实时拦截信用卡欺诈交易&#xff0c;每年减少损失$2400万python# 使用XGBoost构建欺诈检测模型&#xff08;Python&#xff09; import pandas as pd from xgboost import XGBClassifier from sklearn.…

GStreamer中解复用器(Demuxer)

在 GStreamer 中,解复用器(Demuxer) 用于分离容器格式(如 MP4、MKV、AVI 等)中的 视频、音频、字幕等流。不同的容器格式需要不同的 Demuxer 元素。 一、常见的 GStreamer Demuxer 元素 1. MP4 / QuickTime 格式 qtdemux 用于解析 MP4(.mp4)、MOV(.mov) 等基于 Quic…

MySQL 存储过程终止执行的方法

在 MySQL 存储过程&#xff08;PROCEDURE&#xff09;开发中&#xff0c;我们常常遇到这样的需求&#xff1a; 在执行过程中&#xff0c;如果某些条件不满足&#xff0c;就要立即终止剩余逻辑&#xff0c;避免无效或错误的操作。不同于 Java、Python 等编程语言直接 return 退出…

鲲鹏arm服务器安装neo4j社区版,实现图书库自然语言检索基础

我在dify实施中&#xff0c;发现采用自然语言进行数据库检索效果还不错&#xff0c;我就想起来了图数据库的自然语言检索&#xff0c;以前图书库的算法我不熟悉&#xff0c;这次打算采用这种方式完成。我才用但是鲲鹏920&#xff0c;泰山服务器&#xff0c;2280主机&#xff0c…

小八的学习日记 -- 为什么kafka吞吐量大

1. 「顺序读写」—— 像开高速公路一样爽&#xff01;​​​​传统硬盘的痛点&#xff1a;​​ 普通硬盘&#xff08;HDD&#xff09;像在热闹的菜市场找东西&#xff0c;磁头要来回移动&#xff08;寻道&#xff09;&#xff0c;随机读写特别慢。​​Kafka 的妙招&#xff1a;…

5G NTN 卫星测试产品

5G NTN 卫星测试产品非地面网络测试解决方案卫星射频节点测试测量相控阵天线应对卫星基础设施测试挑战适用于 5G NTN 卫星测试的高性能解决方案卫星基础设施测试解决方案的优势5G NTN 卫星测试产品FSW 信号与频谱分析仪R&SSMW200A 矢量信号发生器非地面网络测试解决方案 透…