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

【数据结构】线性表,顺序表

一. 线性表

1. 线性表(linear list)是n个具有相同特性的数据元素的有限序列。

2. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

3. 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

二. 顺序表 

1. 静态顺序表与动态顺序表

1. 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。

2. 顺序表一般可以分为:

静态顺序表:使用定长数组存储元素。

#define N 10
typedef int SLDataType;
typedef struct SeqList
{SLDataType array[N]; //定长数组size_t size;         //有效数据个数
}SeqList;

动态顺序表:使用动态开辟的数组存储。

typedef int SLDataType;
typedef struct SeqList
{SLDataType* array; //指向动态开辟的数组size_t size;       //有效数据个数size_t capacity;   //空间容量
}SeqList;

2. 动态顺序表的接口实现 

1. 静态顺序表只适用于确定知道需要存多少数据的场景。

2. 静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。

3. 所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

2.1 顺序表初始化 

1. 将结构的每个成员进行初始化

void SeqListInit(SeqList* psl, size_t capacity)
{assert(psl);psl->array = (SLDataType*)malloc(sizeof(SeqList) * capacity);if (psl->array == NULL){perror("malloc");return;}psl->size = 0;psl->capacity = capacity;
}

2.2 判断是否需要扩容  

1. 判断有效个数是否和容量相等。

2. 使用realloc增容。

void CheckCapacity(SeqList* psl)
{assert(psl);if (psl->size == psl->capacity){SLDataType* tmp = (SLDataType*)realloc(psl->array, sizeof(SLDataType) * psl->capacity * 2);if (tmp == NULL){perror(realloc);return;}psl->array = tmp;psl->capacity *= 2;}
}

 2.3 顺序表指定位置插入

1. 对pos进行范围判断。

1. 判断是否需要扩容。

2. 将pos后面的元素往后挪一位。

3. pos位置插入值。

4. 有效个数加一。

void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos <= psl->size);CheckCapacity(psl);size_t cur = psl->size;while (cur != pos){psl->array[cur] = psl->array[cur - 1];cur--;}psl->array[pos] = x;psl->size++;
}

 2.4 顺序表头插

1. 判断是否需要扩容。

2. 将所有元素都往后移一位,留出第一个位置插入(如果头插之前没有元素,则直接插入即可)。

3. 有效个数加一。

void SeqListPushFront(SeqList* psl, SLDataType x)
{assert(psl);CheckCapacity(psl);int tmp = psl->size;while (tmp > 0) //当本身为空时,就不走这个循环{psl->array[tmp] = psl->array[tmp - 1];tmp--;}psl->array[0] = x;psl->size++;
}

方法2:复用SeqListInsert

void SeqListPushFront(SeqList* psl, SLDataType x)
{SeqListInsert(psl, 0, x);
}

2.5 顺序表尾插

1. 插入前判断是否需要增容。

2. size作为下标正好是最后一个元素的后一位。

void SeqListPushBack(SeqList* psl, SLDataType x)
{assert(psl);CheckCapacity(psl);psl->array[psl->size++] = x;
}

方法2:复用SeqListInsert

void SeqListPushBack(SeqList* psl, SLDataType x)
{assert(psl);SeqListInsert(psl, psl->size, x);
}

 2.6 顺序表指定位置删除

1. 判断pos是否合法。

2. 将pos后面的元素往前覆盖一位。

3. 有效个数减一。

void SeqListErase(SeqList* psl, size_t pos)
{assert(psl);assert(pos >= 0 && pos < psl->size);int cur = pos;while (cur < psl->size - 1){psl->array[cur] = psl->array[cur + 1];cur++;}psl->size--;
}

 2.7 顺序表头删

1. 判断有效个数是否为0,为0不用删。

2. 将后面的与元素往前覆盖一位。

3. 有效元素个数减一。

void SeqListPopFront(SeqList* psl)
{assert(psl);assert(psl->size);size_t cur = 0;while (cur < psl->size - 1){psl->array[cur] = psl->array[cur + 1];cur++;}psl->size--;
}

方法2:复用SeqListErase

void SeqListPopFront(SeqList* psl)
{assert(psl);SeqListErase(psl, 0);
}

 2.8 顺序表尾删

1. 判断size,size如果为0就不能删。

2. 删除尾部元素直接将size减减即可。

void SeqListPopBack(SeqList* psl)
{assert(psl);assert(psl->size);psl->size--;
}

方法2:复用SeqListErase

void SeqListPopBack(SeqList* psl)
{assert(psl);SeqListErase(psl, psl->size - 1);
}

2.9 顺序表查找

1. 遍历一遍进行比较。

2. 找到返回下标,否则返回-1。

int SeqListFind(SeqList* psl, SLDataType x)
{assert(psl);for (size_t i = 0; i < psl->size; i++){if (psl->array[i] == x) return i;}return -1;
}

2.10 顺序表修改 

1. 对pos进行范围判断。

2. 将pos作为下标进行修改。

void SeqListModify(SeqList* psl, size_t pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos < psl->size);psl->array[pos] = x;
}

2.11 顺序表销毁

1. 销毁时需要释放空间,指针置空。

2. 有效个数和容量置0。

void SeqListDestory(SeqList* psl)
{assert(psl);free(psl->array);psl->array = NULL;psl->capacity = 0;psl->size = 0;
}

2.12 顺序表打印

1. 遍历数组打印

void SeqListPrint(SeqList* psl)
{assert(psl);for (int i = 0; i < psl->size; i++) printf("%d ", psl->array[i]);printf("\n");
}

3. 顺序表的缺点

1. 中间/头部的插入删除,时间复杂度为O(N)。

2. 增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗。

3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

4. 顺序表编程练习题 

4.1 移除元素

链接:. - 力扣(LeetCode)

思路: 

1. src遍历判断,等于val就什么也不做,不等于val就把当前值给dst。

2. 等待src给我值,然后加加。

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

4.2 删除有序数组中的重复项

链接:. - 力扣(LeetCode)

思路:利用双指针进行比较。

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

4.3 合并两个有序数组

链接:. - 力扣(LeetCode)

思路:

1. 从后面开始比较,谁大谁放在后面。

2. 注意结束条件,这里以tail为标准。

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{int src1 = m-1;int src2 = n-1;int tail = nums1Size-1;while(tail>=0){if(src2<0) break;if(src1<0) nums1[tail] = nums2[src2--];else if(nums2[src2] >= nums1[src1]) nums1[tail] = nums2[src2--];else if(nums2[src2] < nums1[src1]) nums1[tail] = nums1[src1--];tail--;}
}

三. 链表

1. 链表的概念及结构

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

2. 单链表实现

2.1 单链表节点结构

1. 使用typedef重命名数据类型是为了方便类型的更改。

2. 结构包含存放的数据和指向下一个节点的地址。

typedef int SLDataType;
typedef struct SingleListNode
{SLDataType data;struct SingleListNode* next;
}SLNode;

2.2 动态申请一个节点

1. 使用malloc申请一块节点空间。

2. 将节点内容初始化。 

SLNode* BuySLNode(SLDataType x)
{SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));if (newnode == NULL){perror("malloc");return NULL;}newnode->data = x;newnode->next = NULL;return newnode;
}

2.3 单链表打印

1. 通过获取下一个节点地址进行遍历并打印数据。

2. 遇到空节点停下。

void SLPrint(SLNode* plist)
{SLNode* cur = plist;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}

2.4 单链表尾插

1. pplist不可能为空,所以加断言。

2. 无节点情况:直接将新节点地址给头指针。

3. 有节点情况:将最后一个节点连接新节点。

void SLPushBack(SLNode** pplist, SLDataType x)
{assert(pplist);SLNode* newnode = BuySLNode(x);if (*pplist == NULL) *pplist = newnode; //无节点else                                    //有节点{SLNode* cur = *pplist;while (cur->next != NULL) cur = cur->next;cur->next = newnode;}
}

2.5 单链表头插

1. 先将新节点连接第一个结点,再将头指针连接新节点。   

void SLPushFront(SLNode** pplist, SLDataType x)
{assert(pplist);SLNode* newnode = BuySLNode(x);newnode->next = *pplist;*pplist = newnode;
}

2.6 单链表尾删

1. 单节点情况:释放节点然后置空。

2. 多节点情况:利用倒数第二个节点,释放倒数第一个节点并置空。

void SLPopBack(SLNode** pplist)
{assert(pplist && *pplist);SLNode* cur = *pplist;if (cur->next == NULL) //单节点{free(cur);*pplist = NULL;}else                   //多节点{while (cur->next->next != NULL) cur = cur->next;free(cur->next);cur->next = NULL;}
}

2.7 单链表头删

1. *pplist不能为空,因为空节点不用删。

2. 将头指针指向第二个节点,释放第一个节点。

void SLPopFront(SLNode** pplist)
{assert(pplist && *pplist);SLNode* del = *pplist;*pplist = del->next;free(del);
}

2.8 单链表查找 

1. 遍历一遍,比较数据。

SLNode* SLFind(SLNode* plist, SLDataType x)
{SLNode* cur = plist;while (cur){if (cur->data == x) return cur;cur = cur->next;}return NULL;
}

 2.9 单链表在pos后一位插入x

1. 先将新节点连接pos的后一个节点,再将pos连接新节点。

void SLInsertAfter(SLNode* pos, SLDataType x)
{assert(pos);SLNode* newnode = BuySLNode(x);newnode->next = pos->next;pos->next = newnode;
}

2.10 单链表删除pos后一位的值

1. 空节点不用删。

2. 将pos和pos后面第二个节点连接,释放pos后面第一个节点。

void SLEraseAfter(SLNode* pos)
{assert(pos);SLNode* del = pos->next;pos->next = del->next;free(del);
}

3. 链表的分类 

4. 双向链表的实现

5. 链表编程练习题

5.1 移除链表元素

链接:. - 力扣(LeetCode)

思路:

1. 遍历链表,删除相同值得节点。

2. 使用前后指针,方便节点的释放。

3. 注意特殊情况,当第一个节点就需要删除的时候。

struct ListNode* removeElements(struct ListNode* head, int val) 
{struct ListNode* cur = head;struct ListNode* prev = NULL;while(cur){if(cur->val == val){   if(prev == NULL) //这里判断的是当前是不是第一个节点,{                   //注意,删除完第一个节点后,第二个节点会变成新的第一个节点。cur = cur->next;free(head);head = cur;}else{prev->next = cur->next;free(cur);cur = prev->next;}}else{prev = cur;cur = cur->next;}}return head;
}

5.2 链表的中间结点

链接:. - 力扣(LeetCode)

思路:

1. 快慢指针,slow一次走一步,fast一次走两步。

2. 有奇数节点,偶数节点两种情况,奇数节点时fast走到最后一个节点停下,偶数节点时fast走到空停下。

struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head;struct ListNode* fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;}return slow;
}

5.3 合并两个有序链表

链接:. - 力扣(LeetCode)

思路:

1. 将小于或等于的节点尾插到一个新的指针上,返回这个指针。

2. 注意第一个节点尾插需要特殊处理。

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{if(list1 == NULL) return list2;if(list2 == NULL) return list1;struct ListNode* list3 = NULL;struct ListNode* cur = NULL;while(list1 && list2){if(list1->val <= list2->val){if(list3 == NULL) list3 = cur = list1;else{cur->next = list1;cur = cur->next;}list1 = list1->next;}else{if(list3 == NULL) list3 = cur = list2;else{cur->next = list2;cur = cur->next;}list2 = list2->next;}}if(list1) cur->next = list1;if(list2) cur->next = list2;return list3;
}

5.4 反转链表 

链接:. - 力扣(LeetCode)

思路1:用三个指针来实现反转。

struct ListNode* reverseList(struct ListNode* head) 
{if(head == NULL) return NULL;struct ListNode* n1 = NULL;struct ListNode* n2 = head;struct ListNode* n3 = head->next;while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3) n3 = n3->next;}return n1;
}

思路2:头插法,每次cur节点对rhead进行头插。

struct ListNode* reverseList(struct ListNode* head) 
{struct ListNode* rhead = NULL;struct ListNode* cur = head;while(cur){struct ListNode* next = cur->next;cur->next = rhead;rhead = cur;cur = next;}return rhead;
}

5.5  链表分割

链接:链表分割_牛客题霸_牛客网

思路:

1. 分两个链表,将小于x的尾插一个链表,大于等于x的尾插另一个链表,最后连接起来。

2. 建议用带哨兵位的链表。

3. 连接起来后第二个链表最后记得指向NULL。

ListNode* partition(ListNode* pHead, int x) {ListNode* h1 = (ListNode*)malloc(sizeof(ListNode));ListNode* h2 = (ListNode*)malloc(sizeof(ListNode));ListNode* h1tail = h1;ListNode* h2tail = h2;ListNode* cur = pHead;while(cur){if(cur->val < x){h1tail->next = cur;h1tail = h1tail->next;}else { h2tail->next = cur;h2tail = h2tail->next;}cur = cur->next;}h1tail->next = h2->next;h2tail->next = NULL;pHead = h1->next;free(h1);free(h2);return pHead;}

5.6 相交链表

链接:. - 力扣(LeetCode)

思路:

1. 先求两个链表的长度。

2. 长的链表头指针先走,走到和短的链表一样长。

3. 两个指针一起走,直到遇到一样的节点。

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{int lenA = 0;int lenB = 0;struct ListNode* cur = headA;while(cur){lenA++;cur = cur->next;}cur = headB;while(cur){lenB++;cur = cur->next;}int gap = abs(lenA-lenB);struct ListNode* longlist = headA;struct ListNode* shortlist = headB;if(lenA < lenB){longlist = headB;        shortlist = headA;  }while(gap--) longlist = longlist->next;  while(longlist != shortlist){longlist = longlist->next;shortlist = shortlist->next;}return longlist;
}

5.7 环形链表 

链接:. - 力扣(LeetCode)

思路:

1. 利用快慢指针,如果有环那么会相遇,如果没环就走到链表结束。

bool hasCycle(struct ListNode *head) 
{struct ListNode *fast = head;struct ListNode *slow = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;if(slow == fast) return true;}    return false;
}

面试问题:

1. 快指针走两步,慢指针走一步,快指针和慢指针一定会相遇吗?

答:一定会,当他们进入环后,距离不断减1直到0。

快指针走n步,慢指针走一步,假设快指针追到慢指针的距离为N,那么N必须是n-1的倍数才有能追上。错过之后,N也会发生变化。

6. 顺序表和链表的区别 

相关文章:

【数据结构】线性表,顺序表

一. 线性表 1. 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 2. 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 3. 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线。但是在物理…...

Spring之最基础的创建与Bean的存储与获取(还有Maven加载jar包报错的解决方法)

目录 创建Spring项目 如何解决Maven加载jar包报错 存储Bean和取Bean 在Java中对象也称为Bean。所以后面我提到Bean&#xff0c;大家要知道我说的是什么。 创建Spring项目 我的idea是2022版本的&#xff0c;如果大家和我一样可以参考我的。 1.创建一个Maven项目。图片上忘了…...

RabbitMQ应用问题 - 消息顺序性保证、消息积压问题

文章目录 MQ 消息顺序性保证概述原因分析解决方案基于 spring-cloud-stream 实现分区消费 消息挤压问题概述原因分析解决方案 MQ 消息顺序性保证 概述 a&#xff09;消息顺序性&#xff1a;消费者消费的消息的顺序 和 生产者发送消息的顺序是一致的. 例如 生产者 发送消息顺序…...

linux tcp通讯demo

linux tcp通讯demo代码。通过用chatgpt生成的代码。做一个代码记录。 一、基本的通讯demo server.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h>…...

在 MongoDB 中,如何配置副本集以实现读写分离?

在 MongoDB 中&#xff0c;配置副本集以实现读写分离主要涉及以下几个步骤&#xff1a; 初始化副本集&#xff1a; 创建副本集时&#xff0c;需要在所有参与节点上运行 rs.initiate() 命令。这将初始化一个新的副本集。 添加成员到副本集&#xff1a; 使用 rs.add() 命令将所有…...

虚拟dom-Diff算法

虚拟dom-Diff算法 vue2 diff算法在vue2中就是patch&#xff0c;通过新旧虚拟dom对比&#xff0c;找到最小变化然后进行dom操作 在页面首次渲染的时候会调用一次patch并创建新的vnode&#xff0c;不会进行深层次的比较&#xff0c;然后再组件中数据发生变化的时候&#xff0c;…...

01创建型设计模式——单例模式

一、单例模式简介 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff08;GoF书中解释创建型设计模式&#xff1a;一种用来处理对象的创建过程的模式&#xff09;&#xff0c;单例模式是其中的一种&#xff0c;它确保一个类只有一个实例&#xff…...

图像分割(一)

一、概述 语义分割&#xff1a;是把每个像素都打上标签&#xff08;这个像素点是人、树、背景等&#xff09; 实例分割&#xff1a;不光要区别类别&#xff0c;还要区分类别中的每一个个体 损失函数&#xff1a;逐像素的交叉熵&#xff1b;样本均衡问题 MIOU指标&#xff1a…...

C++ 新经典:设计模式 目录(先留框架,慢慢来~)

C 新经典&#xff1a;设计模式 C 新经典&#xff1a;设计模式 C 新经典&#xff1a;设计模式第1章 设计模式与软件开发思想、编程环境介绍第2章 模板方法模式第3章 工厂模式、原型模式、建造者模式第4章 策略模式第5章 观察者模式第6章 装饰模式第7章 单件模式第8章 外观模式第…...

go之命令行工具urfave-cli

一、urfave/cli urfave/cli 是一个声明性的、简单、快速且有趣的包&#xff0c;用于用 Go 构建命令行工具。 二、快速使用 2.1 引入依赖 go get github.com/urfave/cli/v2 2.2 demo package mainimport ("fmt""log""os""github.com/ur…...

四种应用层协议——MQTT、CoAP、WebSockets和HTTP——在工业物联网监控系统中的性能比较

目录 摘要(Abstract) 实验设置 实验结果 节选自《A Comparative Analysis of Application Layer Protocols within an Industrial Internet of Things Monitoring System》&#xff0c;作者是 Jurgen Aquilina、Peter Albert Xuereb、Emmanuel Francalanza、Jasmine Mallia …...

MySQL的脏读、不可重复读、幻读与隔离级别

脏读/不可重复读/幻读 脏读 脏读(Dirty Read)发生在一个事务读取了另一个事务尚未提交的数据。如果第二个事务失败并回滚&#xff0c;第一个事务读到的数据就是错误的。这意味着数据从一开始就是不稳定或者“脏”的。 举例 事务A读取了某条记录的值为X。事务B修改该记录的值…...

程序员前端开发者的AI绘画副业之路:在裁员危机中寻找新机遇

正文&#xff1a; 在这个充满变数的时代&#xff0c;作为一名前端开发者&#xff0c;我经历了行业的起伏&#xff0c;见证了裁员危机和中年失业危机的残酷。在这样的背景下&#xff0c;我开始了利用AI绘画作为副业的探索&#xff0c;不仅为了寻求经济上的稳定&#xff0c;更是为…...

Burp Suite的使用和文件上传漏洞靶场试验

第一步&#xff1a;分析如何利用漏洞&#xff0c;通过对代码的查阅发现&#xff0c;代码的逻辑是先上传后删除&#xff0c;意味着&#xff0c;我可以利用webshell.php文件在上传到删除之间的间隙&#xff0c;执行webshell.php的代码&#xff0c;给上级目录创建一个shell.php木马…...

如何在Ubuntu中安装deepin wine版的企业微信

如何在Ubuntu中安装deepin wine版的企业微信 运行如下一条命令将移植仓库添加到系统中 wget -O- https://deepin-wine.i-m.dev/setup.sh | sh自此以后&#xff0c;你可以像对待普通的软件包一样&#xff0c;使用apt-get系列命令进行各种应用安装、更新和卸载清理了。 安装企业…...

案例:Nginx + Tomcat集群(负载均衡 动静分离)

目录 案例 案例环境 案例步骤 部署Tomcat服务器 部署Nginx服务器 实现负载均衡和读写分离 日志控制 案例 案例环境 操作系统 IP 地址 角色 CentOS 192.168.10.101 Nginx服务器&#xff08;调度器&#xff09; CentOS 192.168.10.102 Tomcat服务器① CentOS 1…...

【密码学】密码协议的分类:②认证协议

密码协议的分类有很多种方式&#xff0c;这里我采取的是基于协议实现的目的来分类。可以将密码协议分成三类&#xff1a;认证协议、密钥建立协议、认证密钥建立协议。 一、认证协议是什么&#xff1f; 认证协议都在认证些什么东西呢&#xff1f;认证一般要认证三个东西&#x…...

异步编程(Promise详解)

目录 异步编程 回调函数 回调地狱 Promise 基本概念 Promise的特点 1.Promise是一种构造函数 2.Promise接收函数创建实例 3.Promise对象有三种状态 4.Promise状态转变不可逆 5.Promise 实例创建即执行 6.Promise可注册处理函数 7.Promise支持链式调用 Promise的静…...

DjangoORM注入分享

DjangoORM注入 简介 ​ 这篇文章中&#xff0c;分享一些关于django orm相关的技术积累和如果orm注入相关的安全问题讨论。 ​ 攻击效果同数据库注入 从Django-Orm开始 开发角度 ​ Django ORM&#xff08;Object-Relational Mapping&#xff09;是Django框架中用于处理数…...

【HBZ分享】Redis各种类型的数据结构应用场景

String(字符串类型) 计数器&#xff1a; incr / decr, 比如商品库存&#xff0c;业务号的发号器业务数据key-value缓存&#xff0c; 缓存结果数据&#xff0c;提高网站性能&#xff0c;缓解DB压力分布式session会话&#xff0c; 集群环境下存储token鉴权信息分布式锁&#xff…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...