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

数据结构入门:详解顺序表的实现与操作

目录

1.线性表

2.顺序表

2.1概念与结构

2.2分类

2.2.1静态顺序表

2.2.2动态顺序表 

3.动态顺序表的实现

3.1.SeqList.h

3.2.SeqList.c

3.2.1初始化

 3.2.2销毁

3.2.3打印

3.2.4顺序表扩容 

3.2.5尾部插入及尾部删除 

3.2.6头部插入及头部删除 

3.2.7特定位置插入及删除 

3.2.8查找元素,返回下标 

 4.顺序表算法题

1.力扣:移除元素

核心思想

算法步骤

 2.力扣:删除有序数组的重复项

核心思想

算法步骤

 3.力扣:合并两个有序数组

核心思想

算法步骤


1.线性表

在讲顺序表之前,我们首先要介绍一个概念,线性表。

线性表(Linear List)是数据结构中最基础、最常用的一种结构,它的特点是数据元素之间按线性顺序排列,每个元素最多有一个前驱和一个后继。

线性表有两种实现方式,其一是顺序表,其二是链表。以下我们来为他们做一个简单区分:

顺序表(顺序存储)链表(链式存储)
实现方式数组存储元素,内存连续分配结点存储元素和指针,内存非连续分配
特点
  • 支持随机访问(通过下标直接访问元素,时间复杂度 O(1))。

  • 插入/删除可能需要移动大量元素(时间复杂度 O(n))。

  • 存储空间固定(需预先分配,可能浪费或不足)。

  • 插入/删除高效(时间复杂度 O(1),仅需修改指针)。

  • 不支持随机访问(查找需从头遍历,时间复杂度 O(n))。

  • 存储空间动态分配,更灵活。

适用场景元素数量固定、频繁查询、少增删。频繁增删、元素数量变化大。

表格内容暂时看不明白没有关系,这里只是做一个简介,相信等你看完博客之后会有一个新的体会。

今天我们着重介绍的是顺序表,链表会放在下一篇博客中精讲。


2.顺序表

2.1概念与结构

概念:顺序表是⽤⼀段物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采⽤数组存储。

顺序表和数组的区别? 

顺序表是数据结构中线性表的一种实现方式,本质是基于数组的封装,通过数组实现元素的连续存储,并添加了对数据操作的逻辑(如插入、删除、扩容等)。

2.2分类

2.2.1静态顺序表

定义与特点

  • 固定容量:在创建时分配固定大小的内存空间,无法动态扩展或收缩

  • 内存分配:通常在编译阶段确定(如全局数组)或在栈上分配(如局部数组),内存管理由系统自动完成。

  • 操作限制:仅支持基本的读写操作,插入和删除需手动移动元素,效率较低。

#define SLDataType int   // 定义顺序表元素类型为int(便于后期类型修改)
#define N 7              // 定义顺序表容量为7(固定大小)// 静态顺序表结构体定义
typedef struct Seqlist { // 类型重命名为SLSLDataType arr[N];   // 固定大小的数组存储元素int size;            // 记录当前有效元素个数(核心状态标识)
} SL;                    // 类型重命名简化

2.2.2动态顺序表 

 定义与特点

  • 可变容量:支持运行时动态调整容量(扩展或收缩),通过重新分配内存实现。

  • 内存分配:通常在堆上动态分配,由程序逻辑管理(如 malloc 或 new)。

  • 高级操作:封装了插入、删除、扩容等复杂逻辑,用户无需手动处理内存。

// 定义顺序表存储的元素类型为int
// 使用宏定义方便后续修改元素类型(例如改为float或自定义结构体)
#define SLDataType int  // 动态顺序表结构体定义
typedef struct Seqlist {SLDataType* arr;   // 指向动态分配数组的指针(存储元素)int size;          // 当前顺序表中有效元素的数量int capacity;      // 当前顺序表的总容量
} SL;  // 使用typedef将结构体重命名为SL,简化代码

将静态顺序表和动态数据表做一个对比:

特性静态顺序表动态顺序表
存储方式固定大小数组(栈内存/全局区)动态分配数组(堆内存)
容量编译时确定(#define N 7),不可变运行时动态调整(通过malloc/realloc
内存分配自动分配和释放(无需手动管理)需手动管理(malloc/free
扩容/缩容不支持,大小固定支持,可动态调整(如capacity不足时扩容)

经过比对,我们发现 

  • 静态顺序表简单但僵化,适合确定性的小规模数据。

  • 动态顺序表复杂但强大,是现代编程语言中动态数组的基础实现。

本文将以实现动态顺序表为主,详细讲述动态顺序表的扩容,头插,尾插,删除等操作。


3.动态顺序表的实现

3.1.SeqList.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLDataType;// 动态顺序表 -- 按需申请
typedef struct SeqList
{SLDataType* arr;int size; // 有效数据个数int capacity; // 空间容量
}SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);//扩容
void SLCheckCapacity(SL* ps);//头部插⼊删除 / 尾部插⼊删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);//指定位置之前插⼊/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);int SLFind(SL * ps, SLDataType x);

一个动态顺序表至少应该能够实现以上功能,下面我们来逐一实现。

3.2.SeqList.c

3.2.1初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->capacity = 0;ps->size = 0;
}
 3.2.2销毁
void SLDestroy(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->capacity = 0;ps->size = 0;
}

注意:这里释放空间需要判断指针是否为空,如果是空指针直接释放会报错,同时我们要检查的是ps->arr,并不是ps,需要额外注意,不要释放ps的空间和将ps置空指针

3.2.3打印
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}
3.2.4顺序表扩容 
void SLCheckCapacity(SL* ps)
{// 检查是否需要扩容(当前元素数 == 当前容量)if (ps->capacity == ps->size){// 计算新容量:如果当前容量为0(初始状态)则设为4,否则扩容2倍int new_capacity = ps->capacity == 0 ? 4 : 2 * (ps->capacity);// 尝试重新分配内存SLDataType* tem = realloc(ps->arr, new_capacity * sizeof(SLDataType));// 处理内存分配失败的情况if (tem == NULL){perror("realloc");  // 打印错误信息exit(EXIT_FAILURE); // 终止程序(EXIT_FAILURE是标准错误退出码)}// 更新顺序表结构ps->arr = tem;           // 指向新分配的内存ps->capacity = new_capacity; // 更新容量值}
}

关键点说明:

  1. 扩容时机

    • size == capacity时触发扩容,这是为了防止下一次插入操作导致溢出

  2. 扩容策略

    • 初始容量设为4(常见设计,避免初期频繁扩容)

    • 之后每次按2倍扩容(标准库常用策略,均摊时间复杂度为O(1))

  3. 内存管理

    • 使用realloc而不是malloc,可以保留原有数据

    • 必须检查返回值是否为NULL(内存分配可能失败)

  4. 错误处理

    • 使用perror输出错误信息(会显示系统级的错误原因)

    • EXIT_FAILURE是标准库定义的错误退出码(通常值为1)

  5. 安全性

    • 先将realloc结果赋给临时变量tem,确认成功后再赋给ps->arr

    • 避免直接ps->arr = realloc(...)导致内存泄漏

3.2.5尾部插入及尾部删除 
/*** @brief 在顺序表尾部插入一个元素* @param ps 指向顺序表结构的指针(必须非空)* @param x 要插入的元素值*/
void SLPushBack(SL* ps, SLDataType x) {assert(ps);              // 确保顺序表指针有效(若ps为NULL则终止程序)SLCheckCapacity(ps);     // 检查并扩容(若容量不足)ps->arr[ps->size++] = x; // 在尾部插入元素,并更新size
}/*** @brief 删除顺序表尾部元素(逻辑删除)* @param ps 指向顺序表结构的指针(必须非空且arr有效)*/
void SLPopBack(SL* ps) {assert(ps && ps->arr);  // 确保顺序表指针和内部数组指针均有效ps->size--;             // 减少size,忽略最后一个元素(逻辑删除)
}
3.2.6头部插入及头部删除 
/*** @brief 在顺序表头部插入一个元素* @param ps 指向顺序表结构的指针(必须非空且内部数组已初始化)* @param x 要插入的元素值* @note 时间复杂度 O(n),需要移动所有元素*/
void SLPushFront(SL* ps, SLDataType x) {// 1. 参数校验assert(ps && ps->arr);  // 确保顺序表指针和内部数组指针有效// 2. 容量检查(必要时扩容)SLCheckCapacity(ps);    // 检查并处理容量不足的情况// 3. 移动元素:从后往前逐个后移for (int i = ps->size; i > 0; i--) {ps->arr[i] = ps->arr[i - 1];  // 将元素向后移动一位}// 4. 插入新元素到头部ps->arr[0] = x;  // 在数组头部放入新元素// 5. 更新元素计数ps->size++;      // 顺序表长度+1
}/*** @brief 删除顺序表头部元素* @param ps 指向顺序表结构的指针(必须非空且顺序表不为空)* @note 时间复杂度 O(n),需要移动剩余所有元素*/
void SLPopFront(SL* ps) {// 1. 参数校验assert(ps && ps->size > 0);  // 确保顺序表有效且不为空// 2. 移动元素:从前往后逐个前移for (int i = 0; i < ps->size - 1; i++) {ps->arr[i] = ps->arr[i + 1];  // 将元素向前移动一位}// 3. 更新元素计数ps->size--;  // 顺序表长度-1/* 可选:清零最后一个元素位置的值ps->arr[ps->size] = 0;  // 防止脏数据*/
}
3.2.7特定位置插入及删除 
/*** @brief 在顺序表指定位置前插入元素* @param ps 指向顺序表结构的指针(必须非空)* @param pos 要插入的位置索引(0 ≤ pos ≤ ps->size)* @param x 要插入的元素值* @note 时间复杂度 O(n),需要移动元素* @note 边界情况:*       - pos=0:相当于头部插入*       - pos=size:相当于尾部追加*/
void SLInsert1(SL* ps, int pos, SLDataType 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;  // 在pos位置插入新元素ps->size++;        // 更新元素数量
}/*** @brief 在顺序表指定位置后插入元素* @param ps 指向顺序表结构的指针(必须非空)* @param pos 参考位置索引(0 ≤ pos < ps->size)* @param x 要插入的元素值* @note 时间复杂度 O(n),需要移动元素* @note 边界情况:*       - pos=0:在第一个元素后插入*       - pos=size-1:相当于尾部追加*/
void SLInsert2(SL* ps, int pos, SLDataType x) {assert(ps);  // 确保顺序表指针有效assert(pos >= 0 && pos < ps->size);  // 检查位置合法性SLCheckCapacity(ps);  // 检查并扩容// 从后往前移动元素,腾出pos+1位置for (int i = ps->size; i > pos + 1; i--) {ps->arr[i] = ps->arr[i - 1];  // 元素后移}ps->arr[pos + 1] = x;  // 在pos+1位置插入新元素ps->size++;            // 更新元素数量
}/*** @brief 删除顺序表指定位置的元素* @param ps 指向顺序表结构的指针(必须非空且顺序表非空)* @param pos 要删除的位置索引(0 ≤ pos < ps->size)* @note 时间复杂度 O(n),需要移动元素* @note 边界情况:*       - pos=0:删除头部元素*       - pos=size-1:删除尾部元素*/
void SLErase(SL* ps, SLDataType pos) {assert(ps && ps->size > 0);  // 确保顺序表有效且非空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--;  // 更新元素数量/* 可选:清除残留数据(防止脏数据)ps->arr[ps->size] = 0;*/
}
3.2.8查找元素,返回下标 
/*** @brief 在顺序表中查找指定元素的位置* @param ps 指向顺序表结构的指针(必须非空)* @param x 要查找的元素值* @return 如果找到,返回元素的索引(0 ≤ index < size);*         如果未找到,返回 -1* @note 时间复杂度 O(n),需要遍历数组*/
int SLFind(SL* ps, SLDataType x) {assert(ps);  // 确保顺序表指针有效// 遍历顺序表查找元素for (int i = 0; i < ps->size; i++) {if (ps->arr[i] == x) {return i;  // 找到元素,返回索引}}return -1;  // 未找到元素
}

 4.顺序表算法题

1.力扣:移除元素

核心思想

使用 双指针技巧

  • src(源指针):遍历原始数组,检查每个元素。

  • dst(目标指针):记录非 val 元素的存储位置。

算法步骤

  1. 初始化 src 和 dst 为 0。

  2. 遍历数组:

    • 如果 nums[src] == val:跳过该元素(src++)。

    • 如果 nums[src] != val:将其复制到 nums[dst],然后 src++ 和 dst++

  3. 最终 dst 的值即为新数组的长度。

代码:

int removeElement(int* nums, int numsSize, int val) {int src = 0,dst = 0;while(src<numsSize){if(nums[src]==val)src++;else{nums[dst] = nums[src];dst++;src++;}}return dst;
}

 2.力扣:删除有序数组的重复项

核心思想

使用 双指针技巧

  • dst(目标指针):记录唯一元素的存储位置。

  • src(源指针):遍历数组,寻找与 dst 不同的元素。

算法步骤

  1. 初始化 dst = 0(第一个元素必定唯一),src = 1

  2. 遍历数组:

    • 如果 nums[dst] == nums[src]:跳过重复元素(src++)。

    • 如果 nums[dst] != nums[src]:将 nums[src] 复制到 nums[++dst],然后 src++

  3. 最终 dst + 1 即为新数组的长度(因为索引从 0 开始)。

 代码:

int removeDuplicates(int* nums, int numsSize) {int dst = 0,src = 1;while(src<numsSize){if(nums[dst]==nums[src]){src++;}else{nums[++dst] = nums[src++];}}return dst+1;
}

 3.力扣:合并两个有序数组

核心思想

使用 逆向双指针法 从后向前合并,避免覆盖 nums1 中的未处理元素。

算法步骤

  1. 初始化指针

    • l1 = m - 1:指向 nums1 的最后一个有效元素。

    • l2 = n - 1:指向 nums2 的最后一个元素。

    • l3 = m + n - 1:指向 nums1 的末尾(合并后的位置)。

  2. 逆向遍历合并

    • 比较 nums1[l1] 和 nums2[l2],将较大的值放入 nums1[l3],并移动对应指针。

    • 重复直到 nums1 或 nums2 遍历完毕。

  3. 处理剩余元素

    • 如果 nums2 有剩余元素(l2 >= 0),直接复制到 nums1 的前端。

代码:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int l1 = m-1,l2 = n-1,l3 = m+n-1;while(l1>=0 && l2>=0){if(nums1[l1]>nums2[l2]){nums1[l3] = nums1[l1];l3--;l1--;}else{nums1[l3] = nums2[l2];l2--;l3--;}}while(l2>=0){nums1[l3] = nums2[l2];l2--;l3--;}
}

相关文章:

数据结构入门:详解顺序表的实现与操作

目录 1.线性表 2.顺序表 2.1概念与结构 2.2分类 2.2.1静态顺序表 2.2.2动态顺序表 3.动态顺序表的实现 3.1.SeqList.h 3.2.SeqList.c 3.2.1初始化 3.2.2销毁 3.2.3打印 3.2.4顺序表扩容 3.2.5尾部插入及尾部删除 3.2.6头部插入及头部删除 3.2.7特定位置插入…...

Reactor框架介绍

Reactor(反应器模式)是一种事件驱动的设计模式,广泛用于高性能网络编程和异步I/O处理。它的核心思想是将事件分发与业务逻辑解耦,通过统一的机制处理多路I/O事件。 这个在android蓝牙中大量使用,如果这里不懂,那么很难看懂底层的逻辑,所以我们在这片文章中做一个介绍 …...

Nacos 3.0 正式发布:MCP Registry、安全零信任、链接更多生态

Nacos 3.0 正式版本发布啦&#xff01;升级 MCP Registry&#xff0c;围绕着 MCP 服务管理&#xff0c;MCP 多种类型注册&#xff0c;包含 MCP Server 注册、编排、动态调试和管理&#xff0c;并且提供 Nacos-MCP-Router 可以进行 MCP 动态发现&#xff0c;可以自动安装、代理 …...

前端安全中的XSS(跨站脚本攻击)

XSS 类型 存储型 XSS 特征&#xff1a;恶意脚本存储在服务器&#xff08;如数据库&#xff09;&#xff0c;用户访问受感染页面时触发。场景&#xff1a;用户评论、论坛帖子等持久化内容。影响范围&#xff1a;所有访问该页面的用户。 反射型 XSS 特征&#xff1a;恶意脚本通过…...

go单向链表

需求 实现单向链表的节点顺序添加、顺序遍历。 实现 package mainimport ("fmt" )type zodiac_sign struct {number intdizhi stringanimal stringyear intnext *zodiac_sign }// 添加 // func add_node_by_order(previous_node zodiac_sign, current_node z…...

Python小程序:上班该做点摸鱼的事情

系统提醒 上班会忘记一些自己的事&#xff0c;所以你需要在上班的的时候突然给你弹窗&#xff0c;你就知道要做啥了 源码 # -*- coding:utf-8 -*- """ 作者:杨桃清 日期: 2025年04日29 21:51:24 """ import datetime import time import thre…...

uni-app中使用RenderJs 使用原生js

RenderJs运行的层叫【视图层】&#xff0c;Uniapp原生Script叫【逻辑层】&#xff0c;逻辑层要调用视图层需要使用一个叫【watcher】&#xff0c;具体怎么调用呢 为了实现这两层之间的通信&#xff0c;uniapp提供了一些特定的机制。以下是对这些通信机制的详细解释&#xff0c…...

51c自动驾驶~合集37

我自己的原文哦~ https://blog.51cto.com/whaosoft/13878933 #DETR->DETR3D->Sparse4D 走向长时序稀疏3D目标检测 一、DETR 图1 DETR架构 DETR是第一篇将Transformer应用到目标检测方向的算法。DETR是一个经典的Encoder-Decoder结构的算法&#xff0c;它的骨干网…...

uniapp 小程序 安卓苹果 短视频解决方案

需求 要做类似抖音小程序的功能 思路 uniapp 使用swiper滑块 实现滑动 使用video播放视频 遇到的问题 1 video组件在小程序可以使用 uni.createVideoContext api控制 2 但是在app端会有层级问题&#xff08;因为使用的原生组件具体看官方文档&#xff09;导致无法正常滑动…...

LeetCode58_最后一个单词的长度

LeetCode58_最后一个单词的长度 标签&#xff1a;#字符串Ⅰ. 题目Ⅱ. 示例 0. 个人方法 标签&#xff1a;#字符串 Ⅰ. 题目 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、…...

深入理解Spring AI框架的核心概念

深入理解Spring AI框架的核心概念 前言 在当今人工智能飞速发展的时代&#xff0c;将AI技术集成到应用程序中已成为众多开发者关注的焦点。Spring AI框架为Java开发者提供了便捷的途径来实现这一目标。理解其核心概念对于充分发挥框架的潜力至关重要。本文将详细探讨Spring A…...

技术驱动与模式创新:开源AI大模型与S2B2C商城重构零售生态

摘要&#xff1a;在移动互联网与人工智能技术深度融合的背景下&#xff0c;零售行业正经历从“人找货”到“货找人”的范式转移。本文以开源AI大模型、AI智能名片、S2B2C商城小程序源码为核心技术要素&#xff0c;结合无人便利店、盒马鲜生、王府井二次元业态等商业实践&#x…...

精益数据分析(30/126):电商商业模式的深度剖析与关键指标解读

精益数据分析&#xff08;30/126&#xff09;&#xff1a;电商商业模式的深度剖析与关键指标解读 在创业与数据分析的漫漫征途中&#xff0c;我们都在不断探寻如何更好地理解和运用商业数据&#xff0c;以实现业务的蓬勃发展。今天&#xff0c;我依旧带着和大家共同进步的初心…...

玩玩OCR

一、Tesseract: 1.下载windows版&#xff1a; tesseract 2. 安装并记下路径&#xff0c;等会要填 3.保存.py文件 import pytesseract from PIL import Image def ocr_local_image(image_path):try:pytesseract.pytesseract.tesseract_cmd rD:\Programs\Tesseract-OCR\tesse…...

gradle 下载的tencent的镜像

distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-5.4.1-all.zip distributionUrlhttps://mirrors.aliyun.com/gradle/distributions/v5.4.1/gradle-5.4.1-all.zip 参考&#xff1a; gradle 镜像地址,解决 AS 下载缓慢或者下不下来的问题-CSDN博客...

【含文档+PPT+源码】基于微信小程序的乡村振兴民宿管理系统

项目介绍 本课程演示的是一款基于微信小程序的乡村振兴民宿管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该…...

【Redis——数据类型和内部编码和Redis使用单线程模型的分析】

文章目录 Redis的数据类型和内部编码单线程模型的工作过程Redis虽然是一个单线程模型&#xff0c;为啥效率那么高&#xff0c;速度快呢&#xff1f; 总而言之&#xff0c;Redis提供的哈希表容器并不一定真的是真的哈希表&#xff0c;而是在特点的场景下&#xff0c;用别的容器去…...

leetcode day37 474

474 一和零 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。 示例 1&#xff1a; 输入&#xff1a;s…...

【计算机视觉】目标检测:深度解析YOLOv9:下一代实时目标检测架构的创新与实战

深度解析YOLOv9&#xff1a;下一代实时目标检测架构的创新与实战 架构演进与技术创新YOLOv9的设计哲学核心创新解析1. 可编程梯度信息&#xff08;PGI&#xff09;2. 广义高效层聚合网络&#xff08;GELAN&#xff09;3. 轻量级设计 环境配置与快速开始硬件需求建议详细安装步骤…...

Android Studio Profiler

1.我们想要查看自己方法的调用链&#xff0c;或者分析方法耗时的情况&#xff0c;可以选择Android Studio的Profiler&#xff0c;比较方便快捷。如下&#xff1a; 2.基本的面板参数讲解&#xff1a; 3.可以通过搜索&#xff0c;查看对应的方法&#xff0c;以及方法的调用链…...

Android Studio for Platform(ASFP)真机调试

连接设备 由于ubuntu连接adb设备每次都需要配置usb权限&#xff0c;很麻烦。并且每次换设备还要重新配置&#xff0c;我多数设备都是用wifi的adb方式连接。 开发板显示 连接显示器配合usb鼠标或者遥控器操作&#xff08;因为开发板默认开启了adb&#xff0c;我这里是使用有线…...

如何个人HA服务器地址和长期密钥

下面分两步说明如何获取你的 Home Assistant 服务器地址以及创建“长期访问令牌”&#xff08;Long-Lived Access Token&#xff09;&#xff0c;并给出一个简单的 Python 调用示例。 一、获取 Home Assistant 服务器地址 默认域名/端口 如果你在本机或局域网内安装并使用默认设…...

生物化学笔记:神经生物学概论04 视觉通路简介视网膜视网膜神经细胞大小神经节细胞(视错觉)

视觉通路简介 神经节细胞的胞体构成一明确的解剖层次&#xff0c;其外邻神经纤维层&#xff0c;内接内丛状层&#xff0c;该层在鼻侧厚约10&#xff5e;20μm&#xff0c;最厚在黄斑区约60&#xff5e;80μm。 全部细胞数约为120万个(1000000左右)。 每个细胞有一轴突&#xff…...

C++——调用OpenCV和NVIDIA Video Codec SDK库实现使用GPU硬解码MP4视频文件

系列文章目录 参考博客 参考博客 参考博客 文章目录 系列文章目录前言一、下载安装NVIDIA Video Codec SDK1、下载NVIDIA Video Codec SDK2、安装NVIDIA Video Codec SDK 二、下载编译安装OpenCV1、下载OpenCV2、编译安装OpenCV3、配置环境变量4、报错解决报错一&#xff1a; …...

dify升级最新版本(保留已创建内容)

dify安装参考文章&#xff1a; DeepSeek&#xff0b;Dify本地部署私有化知识库 如果之前安装的时候&#xff0c;是通过docker镜像的方式。 从网上下载最新的dify包&#xff0c;下载地址&#xff1a; https://github.com/langgenius/dify 下载完成后&#xff0c;把文件覆盖原…...

4、RabbitMQ的七种工作模式介绍

目录 一、Simple(简单模式) 1.1 概念 1.2 代码实现 消费者 运行结果 二、Work Queue&#xff08;工作队列&#xff09; 2.1 概念 1.2 代码实现 生产者 消费者 运行结果 三、Publish/Subscribe&#xff08;发布/订阅模式&#xff09; 3.1 概念 3.2 代码实现 生产者…...

React Three Fiber 详解:现代 Web3D 的利器

React Three Fiber 详解:现代 Web3D 的利器 随着 Web 技术的发展,3D 场景与交互已经不再是游戏开发者的专利。越来越多的网站、产品页、交互动画,开始大量引入 3D 元素。要在 React 项目中高效使用 WebGL,React Three Fiber(简称 R3F)成为了目前最主流的选择。 今天这篇…...

同步与互斥(同步)

线程同步 条件变量 当⼀个线程互斥地访问某个变量时&#xff0c;它可能发现在其它线程改变状态之前&#xff0c;它什么也做不了。 例如⼀个线程访问队列时&#xff0c;发现队列为空&#xff0c;它只能等待&#xff0c;只到其它线程将⼀个节点添加到队列中。这种情况就需要⽤到条…...

C语言教程(二十一):C 语言预处理器详解

一、预处理器概述 C语言预处理器是一个文本替换工具&#xff0c;它会对源代码进行扫描&#xff0c;处理以 # 开头的预处理指令。这些指令可以控制预处理器的行为&#xff0c;实现宏定义、文件包含、条件编译等功能。预处理器的主要作用是为后续的编译过程准备代码。 二、常见的…...

grafana/loki 设置日志保留时间

loki:limits_config:retention_period: 189h参考官网 Configuring the retention period...

Spring Boot × K8s 监控实战-集成 Prometheus 与 Grafana

在微服务架构中&#xff0c;应用的可观测性至关重要。Kubernetes 已成为容器化部署的标准&#xff0c;但其自身的监控能力有限&#xff0c;需要与其他工具集成才能实现详细的运行数据采集与分析。 本文将通过 Spring Boot Kubernetes Prometheus Grafana 实战&#xff0c;打…...

SpringBoot+Mybatis通过自定义注解实现字段加密存储

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBootMybatis实现字段加密 ⏱️ 创作时间&#xff1a; 2025年04月…...

Vue3调度器错误解析,完美解决Unhandled error during execution of scheduler flush.

目录 Vue3调度器错误解析&#xff0c;完美解决Unhandled error during execution of scheduler flush. 一、问题现象与本质 二、七大高频错误场景与解决方案 1、Setup初始化陷阱 2、模板中的"幽灵属性" 3、异步操作的"定时炸弹" 4、组件嵌套黑洞 5…...

第35周Zookkeeper+Dubbo Zookkeeper

第35周ZooKeeperDubbo ZooKeeper 一、周介绍 本周主要内容包括ZooKeeper、Dubbo以及面试三部分。 1.1 ZooKeeper 节点介绍 ZooKeeper的数据结构核心是每个node节点。节点具有属性、特点和功能&#xff0c;其数据结构为树形结构&#xff0c;类似于多叉树&#xff0c;分隔符是…...

基于tabula对pdf中多个excel进行识别并转换成word中的优化(四)

对上一节进行优化&#xff1a; 1、识别多个excel 2、将表格中的nan替换成空字符串 一、示例中的pdf内容 二、完整代码参考&#xff1a; import tabula import numpy as np from docx import Document from docx.oxml.ns import qn from docx.oxml import OxmlElementdef get_t…...

Electron-vite中ELECTRON_RENDERER_URL环境变量如何被设置的

近期我专注于前端技术栈 Electron 与 Vue3 的学习实践&#xff0c;依照教程网站 快速开始 | electron-vite 的快速入门指引&#xff0c;搭建了一个示例项目。成功完成项目下载&#xff0c;并通过 npm run dev 命令启动项目后&#xff0c;在研读项目 main 目录下的 index.ts 文件…...

Electron Forge【实战】桌面应用 —— 将项目配置保存到本地

最终效果 定义默认配置 src/initData.ts export const DEFAULT_CONFIG: AppConfig {language: "zh",fontSize: 14,providerConfigs: {}, };src/types.ts export interface AppConfig {language: zh | enfontSize: numberproviderConfigs: Record<string, Recor…...

gem5-gpu 安装过程碰到的问题记录 关于使用 Ruby + Garnet

如何使用Garnet? 这并不像一组命令行参数那么简单。要使用gem5-gpu+garnet,您可能需要修改python配置脚本。 问题是配置文件gem5-gpu/configs/gpu_protocol/VI_hammer_fusion.py指定了链接的intBW和extBW。 看来Garnet不支持这一点。然而,似乎所有的链路都是相同的带宽,所…...

全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars

一、基本介绍 MobileIMSDK是一套全平台原创开源IM通信层框架&#xff1a; 超轻量级、高度提炼&#xff0c;lib包50KB以内&#xff1b;精心封装&#xff0c;一套API同时支持UDP、TCP、WebSocket三种协议&#xff08;可能是全网唯一开源的&#xff09;&#xff1b;客户端支持iOS…...

《阿里Qwen3开源:AI新纪元的破晓之光》

《阿里Qwen3开源:AI新纪元的破晓之光》 惊爆!阿里释放 Qwen3 “大杀器” 在人工智能的星辰大海中,每一次新模型的诞生都如同点亮一颗新星,而阿里巴巴此次发布并开源 Qwen3,无疑是投下了一枚震撼弹,瞬间吸引了全球 AI 领域的目光。这不仅是阿里在 AI 征程上的一座重要里程…...

前端防护利器:disable-devtool 使用指南 - 保护你的Web应用安全

文章目录 前端防护利器:disable-devtool 使用指南 - 保护你的Web应用安全为什么需要禁用开发者工具?什么是 disable-devtool?安装与引入通过npm/yarn安装通过CDN引入ES6模块引入配置选项详解完整使用示例检测模式说明最佳实践在线考试系统防护敏感数据保护注意事项更多资源前…...

万物皆可执行:多功能机器人正在定义新生产力法则

引言 当波士顿动力的Atlas完成高难度体操动作&#xff0c;当特斯拉Optimus在工厂精准分拣零件&#xff0c;当小鹏Iron机器人以拟态双手递上咖啡——这些场景不再只是科幻电影的桥段&#xff0c;而是多功能机器人&#xff08;Polyfunctional Robots&#xff09;带来的真实变革…...

从车道检测项目入门open cv

从车道检测项目入门open cv 前提声明&#xff1a;非常感谢b站up主 嘉然今天吃带变&#xff0c;感谢其视频的帮助。同时希望各位大佬积积极提出宝贵的意见。&#x1f60a;&#x1f60a;&#x1f60a;(❁◡❁)(●’◡’●)╰(▽)╯ github地址&#xff1a;https://github.com/liz…...

Vue3取消网络请求的方法(AbortController)

在 Vue3 中&#xff0c;已经发出的请求是否可以被取消&#xff0c;取决于你使用的 HTTP 客户端库。Vue3 本身不直接处理 HTTP 请求&#xff0c;但通常搭配 Axios 或原生 fetch 使用。以下是两种主流方案的取消方法&#xff1a; 1. 使用 Axios CancelToken Axios 提供了 Cance…...

深度解析Qwen3:性能实测对标Gemini 2.5 Pro?开源大模型新标杆的部署挑战与机遇

大语言模型&#xff08;LLM&#xff09;的浪潮持续席卷技术圈&#xff0c;性能天花板不断被刷新。以 Gemini 2.5 Pro 为代表的闭源模型展现了惊人的能力&#xff0c;但其高昂的成本和有限的可访问性也让许多开发者望而却步。与此同时&#xff0c;开源力量正以前所未有的速度崛起…...

AI遇见端动态神经网络:Cephalon(联邦学习+多模态编码)认知框架构建

前引&#xff1a; 在数字化浪潮席卷全球的今天&#xff0c;数据爆炸与算力需求的指数级增长正推动着云计算向更智能、更高效的方向演进。面对海量终端设备的实时响应需求、复杂AI模型的分布式训练挑战&#xff0c;以及多场景数据的协同处理难题&#xff0c;传统云架构逐渐显露出…...

机器学习之五:基于解释的学习

正如人们有各种各样的学习方法一样&#xff0c;机器学习也有多种学习方法。若按学习时所用的方法进行分类&#xff0c;则机器学习可分为机械式学习、指导式学习、示例学习、类比学习、解释学习等。这是温斯顿在1977年提出的一种分类方法。 有关机器学习的基本概念&#xff0c;…...

高翔视觉slam中常见的OpenCV和Eigen的几种数据类型的内存布局及分配方式详解

vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> 内存布局及分配方式详解 1. 内存对齐的必要性 Eigen 的固定大小类型(如 Eigen::Vector2d、Eigen::Matrix4d 等)需要 16 字节内存对齐,以支持 SIMD 指令(如 SSE/AVX)的并行计算。若未对…...

电子电器架构 --- 人工智能、固态电池和先进自动驾驶功能等新兴技术的影响

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...

【C++11】类的新功能

前言 上文我们学习了包装器&#xff1a;function和bind。function可以包装一切可调用对象&#xff0c;并用统一的调用方式调用不同的可调用对象。bind则可以控制函数参数个数【C11】包装器&#xff1a;function与bind-CSDN博客 本文我们来学习C11的类中新增的一些功能 默认的移…...