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

【数据结构】二叉搜索树——二叉搜索树的概念和介绍、二叉搜索树的简单实现、二叉搜索树的增删查改

文章目录

  • 二叉搜索树
    • 1. 二叉搜索树的概念和介绍
    • 2. 二叉搜索树的简单实现
      • 2.1二叉搜索树的插入
      • 2.2二叉搜索树的查找
      • 2.3二叉搜索树的遍历
      • 2.4二叉搜索树的删除
      • 2.5完整代码和测试

二叉搜索树

1. 二叉搜索树的概念和介绍

  二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

  (1)若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

  (2)若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

  (3)它的左右子树也分别为二叉搜索树

在这里插入图片描述

  二叉搜索树(Binary Search Tree)的每个节点包含三个属性:键(key)、左孩子(lchild)和右孩子(rchild)。 键用于存储节点的值,左孩子和右孩子分别指向左子树和右子树的根节点。

  二叉搜索树的结构类似于一个倒置的树,最底层的节点位于树的顶部,每个节点都有一个键值,并且每个节点的左子树上的所有节点的键值都小于该节点的键值,而右子树上的所有节点的键值都大于该节点的键值。这种结构使得二叉搜索树在处理有序数据时非常高效。

  基于以上性质,二叉搜索树在查找、插入和删除操作上具有较好的效率,时间复杂度为O(logn)。

  基于二叉搜索树的特殊结构,二叉搜索树的中序遍历(Inorder Traversal)按照左子树、根节点、右子树的顺序遍历二叉树,它会按照从大到小的顺序输出二叉树中的所有元素。

  以下这颗二叉搜索树的中序遍历结果:1 3 4 6 7 8 10 13 14
在这里插入图片描述
             

2. 二叉搜索树的简单实现

  和之前的二叉树实现类似,二叉搜索树的实现只需要在二叉树的实现基础上,将左右元素根据和根节点的大小,重新考虑排列顺序即可。

  定义二叉搜索树的节点:

//搜索二叉树创建节点
template<class K>
struct BSTreeNode
{//左右节点和节点值keyBSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;//二叉树节点构造函数BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}
};

  定义二叉搜索树类:

//创建二叉搜索树
template<class K>
class BSTree
{//便于书写BNode节点typedef BSTreeNode<K> BNode;public://二叉搜索树构造函数BSTree():_root(nullptr){}private:BNode* _root;
};

             

2.1二叉搜索树的插入

  二叉搜索树的插入过程可以分为以下步骤:

  (1)如果二叉搜索树为空,创建一个新的节点,并将待插入关键字放入新节点的数据域。将新节点作为根节点,左右子树均为空。

  (2)如果二叉搜索树非空,将待查找关键字与根节点关键字进行比较。如果小于根节点关键字,则将待查找关键字插入左子树中;如果大于根节点关键字,则将待查找关键字插入右子树中。

  重复上述步骤,直到找到合适的位置插入待插入的关键字。

  在插入过程中,需要保持二叉搜索树的性质:任意节点的左子树的所有节点的值都小于该节点的值,右子树的所有节点的值都大于该节点的值。如果插入后破坏了这种性质,需要进行调整。

在这里插入图片描述

  非递归的实现:

//二叉树插入节点
bool BSInsert(const K& key)
{//如果该树为空树,直接创建节点if (_root == nullptr){_root = new BNode(key);return true;}//找到二叉树所在的节点BNode* parent = nullptr;BNode* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}//插入节点cur = new BNode(key);if (parent->_key > key){parent->_left = cur;}else {parent->_right = cur;}return true;
}


  递归的实现:

bool _BSInsertR(BNode*& root, const K& key)//这里传&,直接可以得到地址
{if (root == nullptr){root = new BNode(key);return true;}if (root->_key < key){_BSInsertR(root->_right, key);}else if (root->_key > key){_BSInsertR(root->_left, key);}else{return false;}
}

             

2.2二叉搜索树的查找

  二叉搜索树的查找实现过程可以分为以下步骤:

  (1)将待查找关键字与根节点关键字进行比较。如果相等,则找到了目标关键字,查找结束。

  (2)如果待查找关键字小于根节点关键字,则将待查找关键字放入左子树中继续查找。

  (3)如果待查找关键字大于根节点关键字,则将待查找关键字放入右子树中继续查找。

  重复上述步骤,直到找到目标关键字,或者搜索到了空节点(表示未找到目标关键字)。

  在查找过程中,由于二叉搜索树是基于二分的思想,所以每次比较都可以排除一半的搜索空间,因此时间复杂度为O(logn)。

在这里插入图片描述

  非递归实现:

//查找二叉树的节点
bool BSFind(const K& key)
{BNode* cur = _root;while (cur){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else{return true;}}return false;
}

  递归实现:

bool _BSFindR(BNode* root, const K& key)
{if (root == nullptr){return false;}if (root->_key < key){return _BSFindR(root->_right, key);}else if (root->_key > key){return _BSFindR(root->_left, key);}else{return true;}
}

             

2.3二叉搜索树的遍历

  二叉搜索树常使用中序遍历,而不是前序遍历和后序遍历。

  因为中序遍历的特点是先访问左子树,然后访问根节点,最后访问右子树。 在访问左子树时,先访问左子树的左子树,再访问左子树的右子树;在访问右子树时,先访问右子树的左子树,再访问右子树的右子树。

  二叉搜索树中序遍历的结果是按照从小到大的顺序输出二叉搜索树中的所有元素。

  二叉搜索树的中序遍历过程可以分为以下步骤:

  (1)首先遍历左子树,访问左子树中的所有节点,并按照中序遍历的顺序递归地访问它们的右子树。

  (2)然后访问根节点。

  (3)最后遍历右子树,访问右子树中的所有节点,并按照中序遍历的顺序递归地访问它们的左子树。

  递归实现:

void _BSInOrder(BNode* root)
{if (root == nullptr){return;}_BSInOrder(root->_left);printf("%d ", root->_key);_BSInOrder(root->_right);
}

             

2.4二叉搜索树的删除

  二叉搜索树的删除操作可以按照以下步骤实现:

  (1)首先,找到要删除的节点。可以通过中序遍历或者二分查找等方式找到要删除的节点。

  (2)如果要删除的节点是叶子节点(没有子节点),直接将该节点从二叉搜索树中删除即可。

  (3)如果要删除的节点只有一个子节点,将该节点的子节点与其父节点相连,删除该节点即可。

  (4)如果要删除的节点有两个子节点,需要找到该节点的左子树中的最大节点(或者右子树中的最小节点),用该节点代替要删除的节点的位置,然后删除该最小(或最大)节点。

  在实现删除操作时,需要注意保持二叉搜索树的性质,即任意节点的左子树的所有节点的值都小于该节点的值,右子树的所有节点的值都大于该节点的值。同时,删除操作可能会导致二叉搜索树的平衡被破坏,需要进行相应的调整操作。

  (1)当没有叶子结点,或者只有一个子节点的情况:
在这里插入图片描述

  (2)当左右都有子节点的情况:
在这里插入图片描述

  非递归实现:

//删除二叉树中的节点
bool BSErase(const K& key)
{BNode* cur = _root;BNode* parent = nullptr;//先要找到所删除的节点while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else//找到了所要删除的节点{if (cur->_left == nullptr)//当左节点为空节点{if (cur == _root)//cur为根节点{_root = cur->_right;}else//cur不为空节点{if (parent->_right == cur){parent->_right = cur->_right;}else{parent->_left = cur->_right;}}}else if(cur->_right==nullptr)//当右节点为空节点{if (cur == _root)//cur为空节点{_root = cur->_left;}else//cur不为空节点{if (parent->_right == cur){parent->_right = cur->_left;}else{parent->_left = cur->_left;}}}else//当左右节点都不为空节点{//找代替节点BNode* parent = cur;BNode* leftMax = cur->_left;while (leftMax->_right){parent = leftMax;leftMax = leftMax->_right;}swap(cur->_key, leftMax->_key);if (parent->_left == leftMax){parent->_left = leftMax->_left;}else{parent->_right = leftMax->_left;}cur=leftMax;}delete cur;return true;}}return false;
}

  递归实现:

bool _BSEraseR(BNode* &root, const K& key)
{if (root == nullptr){return false;}if (root->_key < key){_BSEraseR(root->_right, key);}else if (root->_key > key){_BSEraseR(root->_left, key);}else{BNode* del = root;//1.左为空//2.右为空//3.左右都不为空if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{BNode* leftMax = root->_left;while (leftMax->_right){leftMax = leftMax->_right;}swap(root->_key, leftMax->_key);return _BSEraseR(root->_left, key);}delete del;return true;}
}

             

2.5完整代码和测试

  完整代码:

#pragma once//搜索二叉树创建节点
template<class K>
struct BSTreeNode
{//左右节点和节点值keyBSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;//二叉树节点构造函数BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}
};//创建搜索二叉树
template<class K>
class BSTree
{//便于书写BNode节点typedef BSTreeNode<K> BNode;public://搜索二叉树构造函数BSTree():_root(nullptr){}//二叉树插入节点bool BSInsert(const K& key){//如果该树为空树,直接创建节点if (_root == nullptr){_root = new BNode(key);return true;}//找到二叉树所在的节点BNode* parent = nullptr;BNode* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}//插入节点cur = new BNode(key);if (parent->_key > key){parent->_left = cur;}else {parent->_right = cur;}return true;}//查找二叉树的节点bool BSFind(const K& key){BNode* cur = _root;while (cur){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else{return true;}}return false;}//删除二叉树中的节点bool BSErase(const K& key){BNode* cur = _root;BNode* parent = nullptr;//先要找到所删除的节点while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else//找到了所要删除的节点{if (cur->_left == nullptr)//当左节点为空节点{if (cur == _root)//cur为根节点{_root = cur->_right;}else//cur不为空节点{if (parent->_right == cur){parent->_right = cur->_right;}else{parent->_left = cur->_right;}}}else if(cur->_right==nullptr)//当右节点为空节点{if (cur == _root)//cur为空节点{_root = cur->_left;}else//cur不为空节点{if (parent->_right == cur){parent->_right = cur->_left;}else{parent->_left = cur->_left;}}}else//当左右节点都不为空节点{//找代替节点BNode* parent = cur;BNode* leftMax = cur->_left;while (leftMax->_right){parent = leftMax;leftMax = leftMax->_right;}swap(cur->_key, leftMax->_key);if (parent->_left == leftMax){parent->_left = leftMax->_left;}else{parent->_right = leftMax->_left;}cur=leftMax;}delete cur;return true;}}return false;}//二叉树的中序遍历void BSInOrder(){_BSInOrder(_root);cout << endl;}//递归实现二叉树的查找bool BSFindR(const K& key){return _BSFindR(_root, key);}//递归实现二叉树的插入节点bool BSInsertR(const K& key){return _BSInsertR(_root, key);}//递归实现二叉树的删除节点bool BSEraseR(const K& key){return _BSEraseR(_root, key);}private://递归二叉树删除的封装实现bool _BSEraseR(BNode* &root, const K& key){if (root == nullptr){return false;}if (root->_key < key){_BSEraseR(root->_right, key);}else if (root->_key > key){_BSEraseR(root->_left, key);}else{BNode* del = root;//1.左为空//2.右为空//3.左右都不为空if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{BNode* leftMax = root->_left;while (leftMax->_right){leftMax = leftMax->_right;}swap(root->_key, leftMax->_key);return _BSEraseR(root->_left, key);}delete del;return true;}}//递归二叉树插入的封装实现bool _BSInsertR(BNode*& root, const K& key)//这里传&,直接可以得到地址{if (root == nullptr){root = new BNode(key);return true;}if (root->_key < key){_BSInsertR(root->_right, key);}else if (root->_key > key){_BSInsertR(root->_left, key);}else{return false;}}//递归二叉树查找的封装实现bool _BSFindR(BNode* root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _BSFindR(root->_right, key);}else if (root->_key > key){return _BSFindR(root->_left, key);}else{return true;}}//为了递归实现,进行一层封装void _BSInOrder(BNode* root){if (root == nullptr){return;}_BSInOrder(root->_left);printf("%d ", root->_key);_BSInOrder(root->_right);}private:BNode* _root;
};


  简单测试:

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;#include"BinarySearchTree.h"void BSTree_test1()
{BSTree<int> t;t.BSInsert(5);t.BSInsert(8);t.BSInsert(6);t.BSInsert(1);t.BSInsert(3);t.BSInsert(2);t.BSInsert(4);t.BSInOrder();cout << "是否存在二叉树的值为1:";if (t.BSFind(1))cout << "存在";else cout << "不存在";cout << endl;int arr[] = { 5,3,1,2,4,9,8,6,7,10 };BSTree<int> t1;for (auto e : arr){t1.BSInsert(e);}t1.BSInOrder();t1.BSErase(3);t1.BSInOrder();cout << "是否存在二叉树的值为1:";if (t1.BSFindR(1))cout << "存在";else cout << "不存在";cout << endl;t1.BSInsertR(11);t1.BSInOrder();t1.BSEraseR(11);t1.BSInOrder();}int main()
{BSTree_test1();return 0;
}

这里就是数据结构中二叉搜索树的基本介绍了😉
如有错误❌望指正,最后祝大家学习进步✊天天开心✨🎉

             

相关文章:

【数据结构】二叉搜索树——二叉搜索树的概念和介绍、二叉搜索树的简单实现、二叉搜索树的增删查改

文章目录 二叉搜索树1. 二叉搜索树的概念和介绍2. 二叉搜索树的简单实现2.1二叉搜索树的插入2.2二叉搜索树的查找2.3二叉搜索树的遍历2.4二叉搜索树的删除2.5完整代码和测试 二叉搜索树 1. 二叉搜索树的概念和介绍 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&…...

通过linux定时任务删除es日志索引

能过linux定时任务删除es日志索引 项目用上了elk&#xff0c;产生的日志索引要定时&#xff0c;其一个方法&#xff0c;通过linux定时任务&#xff0c;调用es接口删除索引。 #!/bin/bash #删除ELK30天前的日志 #计算索引名称包含的日期&#xff0c;比如这里是 %Y.%m.%d (2023…...

【跟小嘉学 Rust 编程】二十二、常用 API

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...

【ES6】Class中this指向

先上代码&#xff1a; 正常运行的代码&#xff1a; class Logger{printName(name kexuexiong){this.print(hello ${name});}print(text){console.log(text);} }const logger new Logger(); logger.printName("kexueixong xiong");输出&#xff1a; 单独调用函数p…...

Python 编程竟然如此幽默!揭秘程序员们的搞笑日常,快来看看吧!

食用原文效果更佳&#xff0c;原文链接 Python 编程竟然如此幽默&#xff01;揭秘程序员们的搞笑日常&#xff0c;快来看看吧&#xff01; 在 Python 编程的世界里&#xff0c;充满了智慧与创造力。 当然&#xff0c;也少不了轻松幽默的段子&#xff0c;这些段子让程序员们在…...

Linux c++开发-03-使用CMake组织工程

一、简单文件的编译 有如下的目录结构&#xff1a; 其中 helloworld.cpp如下&#xff1a; #include <iostream> using namespace std; int main() {printf("hello world my name is Ty!");return 0; }CMakeLists.txt如下&#xff1a; cmake_minimum_requir…...

【C++】函数重载 ④ ( 函数指针定义的三种方式 | 直接定义函数指针 | 通过 函数类型 定义 函数指针 | 通过 函数指针类型 定义 函数指针 )

文章目录 一、函数指针定义方法1、直接定义函数指针2、通过 函数类型 定义 函数指针3、通过 函数指针类型 定义 函数指针4、代码示例 - 不同方式定义函数指针 博客总结 : 重载函数 : 使用 相同 的 函数名 , 定义 不同 的 函数参数列表 ;判定标准 : 只有 函数参数 的 个数 / 类…...

异常-java

目录 一、异常的概念和体系结构 1.1 异常的概念 1.2 异常的体系结构 1.3 异常的分类 二、异常的处理 2.1 防御式编程 2.2 异常抛出 2.3 异常捕获 2.4 异常处理流程 三、自定义异常类 一、异常的概念和体系结构 1.1 异常的概念 程序员在开发过程中&#xff0c;想要将代码写得…...

软件测试/测试开发丨Selenium Web自动化测试 高级控件交互方法

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27045 一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件&am…...

深入Go语言:进阶指南

深入Go语言&#xff1a;进阶指南 欢迎来到深入Go语言的进阶指南。如果你已经熟悉Go语言的基础知识&#xff0c;想要更深入地探索这门语言的高级特性和技巧&#xff0c;那么本篇博客将为你提供有关Go语言的更多深入内容。 Go语言的并发编程 Go语言以其强大的并发支持而闻名。…...

FOXBORO FBM232 P0926GW 自动化控制模块

Foxboro FBM232 P0926GW 是 Foxboro&#xff08;福克斯博罗&#xff09;自动化控制系统的一部分&#xff0c;通常用于监测和控制工业过程。以下是关于这种类型的自动化控制模块可能具有的一些常见功能&#xff1a; 数字输入通道&#xff1a; FBM232 P0926GW 控制模块通常具有多…...

【C# Programming】编程入门:方法和参数

一、方法 1、方法的定义 由一系列以执行特定的操作或计算结果语句组成。方法总是和类关联&#xff0c;类型将相关的方法分为一组。 方法名称 形参和实参(parameter & argument)返回值 2、命名空间 一种分类机制&#xff0c;用于组合功能相关的所有类型。命名空间是分级…...

【报错】 Cannot create property ‘showColumn‘ on number ‘-1‘

1、报错原因&#xff1a; 代码如下&#xff1a; 报错是因为&#xff1a;this.findObject(this.option.column, "thirdId")是一个number &#xff0c;没有.showColumn属性 2、修改代码 将其变成object属性就行了...

C++容器string的运用和注意

介绍 首先&#xff0c;先说明&#xff0c;string在C的string头文件中定义&#xff0c;而在C语言中的字符串就是字符数组&#xff0c;在C中&#xff0c;string容器相当于C语言中的字符数组&#xff0c;string比C语言中的字符数组更为好用&#xff0c;如&#xff1a;C中cin/cout可…...

用对工具,你的全渠道电子商务业务就成功了一半

希望将全渠道电子商务纳入您的业务战略&#xff0c;但不确定从哪里开始&#xff1f;我们为您提供保障。这篇文章将指导您了解全渠道商务的基础知识&#xff0c;以及它与多渠道方法的区别&#xff0c;还将探讨利用全渠道方法的众多好处&#xff0c;并讨论企业如何通过全渠道客户…...

TDengine学习(1):采集量(Metric),标签(label),数据采集点,表,超级表,子表、库

因为TDengine是面向物联网诞生的一种数据库&#xff0c;所以在一些概念的命名上有一点相应的特色。 一、数据采集点 比如需要对一辆高铁上的各种信息进行采集&#xff0c;采集信息存入数据库中。我们可以对高铁车厢内的一些数据进行采集&#xff0c;比如&#xff1a;车厢内温…...

【洛谷 P1029】[NOIP2001 普及组] 最大公约数和最小公倍数问题 题解(辗转相除法)

[NOIP2001 普及组] 最大公约数和最小公倍数问题 题目描述 输入两个正整数 x 0 , y 0 x_0, y_0 x0​,y0​&#xff0c;求出满足下列条件的 P , Q P, Q P,Q 的个数&#xff1a; P , Q P,Q P,Q 是正整数。 要求 P , Q P, Q P,Q 以 x 0 x_0 x0​ 为最大公约数&#xff0c;以…...

Golang 中的 errors 包详解:返回自定义 error 类型

之前的文章《Golang 中的 errors 包详解》详细讲解了 errors 包的主要类型和函数&#xff0c;以及它们的使用方法。本文结合之前讲解的知识&#xff0c;来讲解一下根据自己或团队的项目要求如何返回自定义的 error 类型。 为什么需要自定义 error 类型&#xff1f; 在日常开发…...

C#开发的OpenRA游戏之信标按钮

前面已经分析了两个按钮:变卖和维修,接着下来就是分析信标按钮,这个按钮使用是比较少,但是对于多人游戏时,使用这个信号就很方便同盟军过来查看和帮助了,相当于一个朋友之间共同查看的地址。当你经过同盟标记的标志时,就会听到beacon detected,检测到信标,这就是你的盟…...

16字节协议的串口通信

1.协议要求 协议为帧传输&#xff0c;一共16字节。主要是2字节的固定帧头 EB 90&#xff0c;2字节的帧计数(用来计数发出的帧),10字节的数据和2字节的校验位 帧头&#xff1a;2字节&#xff0c;固定值 8’HEB、8’H90 帧计数&#xff1a;2字节&#xff0c;用来说明发出去帧是…...

Node.js调用Llama.cpp:本地部署大语言模型的完整指南

1. 项目概述&#xff1a;当Llama遇见Node.js如果你最近在折腾大语言模型&#xff08;LLM&#xff09;的本地部署&#xff0c;特别是对Meta的Llama系列模型情有独钟&#xff0c;同时又是一名Node.js开发者&#xff0c;那么你很可能已经听说过或者正在寻找一个像withcatai/node-l…...

AI智能体与Stable Diffusion融合:打造对话式文生图应用实战

1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目&#xff0c;叫agent-chat-selfie。光看名字&#xff0c;你可能会觉得这又是一个聊天机器人或者AI对话项目&#xff0c;但它的核心其实在于“Selfie”——自拍。这个项目巧妙地结合了当下流行的AI智能体&#xff08;…...

抠图怎么抠出来?2026年最好用的免费AI抠图工具测评指南

你是否经常为了一张证件照、商品图或者头像而烦恼&#xff1f;想要快速去掉背景但又不想学复杂的PS操作&#xff1f;我今天要分享的&#xff0c;就是如何用现代AI抠图工具轻松搞定这一切。为什么抠图这么难&#xff1f;抠图之所以成为很多人的"老大难"&#xff0c;主…...

B站视频下载终极指南:5步轻松掌握BilibiliDown完整教程

B站视频下载终极指南&#xff1a;5步轻松掌握BilibiliDown完整教程 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirrors/…...

AI工作流编排框架aiflows:构建模块化、可维护的多智能体系统

1. 项目概述&#xff1a;当AI工作流成为团队协作的“操作系统”如果你和我一样&#xff0c;在过去几年里尝试过将多个大语言模型&#xff08;LLM&#xff09;串联起来&#xff0c;构建一个能处理复杂任务的智能体&#xff08;Agent&#xff09;或工作流&#xff0c;那你一定经历…...

如何在Windows平台上快速构建专业级词法语法分析器:WinFlexBison终极指南

如何在Windows平台上快速构建专业级词法语法分析器&#xff1a;WinFlexBison终极指南 【免费下载链接】winflexbison Main winflexbision repository 项目地址: https://gitcode.com/gh_mirrors/wi/winflexbison WinFlexBison是Windows平台上最专业的词法分析和语法解析…...

Mastercard开源AI代理工具包:用智能代理重塑支付集成开发体验

1. 项目概述&#xff1a;当开发者遇上Mastercard&#xff0c;一个工具包如何重塑支付集成体验如果你是一名开发者&#xff0c;正在为你的电商平台、SaaS服务或者任何需要处理在线支付的应用程序集成支付功能&#xff0c;那么你大概率绕不开与Mastercard这类全球支付网络的交互。…...

基于GitHub Actions的跨平台应用自动化发布流水线实战指南

1. 项目概述&#xff1a;一个开源应用发布管道的诞生在软件开发的日常里&#xff0c;发布环节常常是那个“说起来简单&#xff0c;做起来一团糟”的部分。尤其是在团队协作中&#xff0c;从代码提交到最终用户能下载到安装包&#xff0c;中间要经历构建、测试、签名、打包、上传…...

现在不掌握NotebookLM航天科研工作流,你将错过下一轮国家重大专项申报窗口期——3大航天高校已启用的AI原生课题孵化模板首次解密

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;NotebookLM航天科学研究 NotebookLM 是 Google 推出的基于 AI 的研究协作者工具&#xff0c;专为处理长文档、技术报告与多源文献而设计。在航天科学研究中&#xff0c;其语义理解能力与引用溯源机制可…...

listmonk CI/CD安全扫描集成:在部署前发现漏洞

listmonk CI/CD安全扫描集成&#xff1a;在部署前发现漏洞 邮件营销系统作为企业与用户沟通的重要渠道&#xff0c;其安全性直接关系到用户数据保护和品牌声誉。根据行业统计&#xff0c;超过68%的邮件系统漏洞是在生产环境中被发现的&#xff0c;而此时修复成本已增加10倍以上…...