C++进阶——红黑树的实现
目录
1、红黑树的概念
1.1 红黑树的定义
1.2 红黑树的规则
1.3 为什么没有一条路径会比其他路径长出两倍
1.4 红黑树的性能
2、红黑树的实现
2.1 红黑树的结构
2.2 红黑树的插入
2.2.1 红黑树插入一个值的大概过程
2.2.2 情况1:变色
2.2.3 情况2:单旋+变色
2.2.4 情况3:双旋+变色
2.2.5 红黑树插入的代码实现
2.3 红黑树的查找
2.4 红黑树的验证
2.5 红黑树的删除
2.6 红黑树的代码实现
2.6.1 RBTree
2.6.2 Test.cpp
1、红黑树的概念
1.1 红黑树的定义
红黑树是一种自平衡的二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是红色或黑色。通过对从根节点到叶子节点的路径上的节点颜色进行约束,红黑树确保没有一条路径会比其他路径长出两倍,因此它是近似平衡的。
1.2 红黑树的规则
1. 每个节点不是红色就是黑色。
2. 根节点是黑色的。
3. 红色节点的子节点必须是黑色的,即任意一条路径不能有连续的红色结点。
4. 对于任意一个结点,从该结点到其所有NULL结点的简单路径上,均包含相同数量的黑色结点。
从根节点开始,有9条路径。
补充说明:在《算法导论》等书籍中,通常会补充一条规则,即每个叶子节点(NIL节点)都是黑色的。这里的叶子节点并不是传统意义上的叶子节点,而是指空节点(NIL节点),有时也称为外部节点。NIL节点的引入是为了方便准确地标识出所有路径。
1.3 为什么没有一条路径会比其他路径长出两倍
根据规则4,从根节点到任意NIL节点的路径上的黑色节点数量是相同的。假设最短路径上的黑色节点数量为bh(black height),那么最短路径的长度就是bh(即全黑的路径)。
根据规则2和规则3,根节点是黑色节点,路径中不能有连续的红色节点。因此,最长路径的节点颜色分布只能是“黑-红-黑-红...”交替出现。假设最短路径的长度为bh,那么最长路径的长度最多为2*bh(即一黑一红交替的路径)。
最短路径和最长路径是极端情况,可能一棵树中都没有。假设任意一条从根到NULL结点路径的长度为x,那么bh<=x<=2*bh。
1.4 红黑树的性能
1. 红黑树的高度近似为 logN。
2. 红黑树的查找、插入、删除等操作的时间复杂度均为 O(logN)。
3. 虽然它的平衡性不如AVL树严格,但在实际应用中,红黑树的旋转次数较少,性能表现良好。红黑树和AVL树的时间复杂度都是 O(logN),适用于需要高效查找、插入、删除操作的场景。
2、红黑树的实现
2.1 红黑树的结构
enum Color{RED,BLACK};template<class K,class V>struct RBTreeNode{pair<K,V> _kv;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;Color _col;RBTreeNode(const pair<K,V>& kv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr),_col(RED){ }};template<class K,class V>class RBTree{typedef RBTreeNode<K, V> Node;public://...private:Node* _root = nullptr;};
2.2 红黑树的插入
2.2.1 红黑树插入一个值的大概过程
1. 按二叉搜索树的规则插入一个值。
2. 如果是向空树中插入,新节点应为黑色节点(即根节点,规则2,根节点是黑色的)。
如果是向非空树中插入,新节点必须是红色节点,因为插入黑色新节点会破坏规则4,而规则4较难维护。
3. 在非空树中插入后,新节点必须是红色节点。如果其父节点是黑色的,则未违反任何规则,插入操作结束。
4. 在非空树中插入后,新节点必须是红色节点。如果其父节点是红色的,则违反了规则3。
若新节点cur为红色,其父节点parent也为红色,则祖父节点grandfather必为黑色,因为插入就是红黑树,不会出现连续的红节点。这三个节点的颜色已确定,关键在于考察叔叔节点uncle的情况。
说明:下图中假设我们把新增结点标识为c(cur),c的父亲标识为p(parent),p的父亲标识为 g(grandfather),p的兄弟标识为u(uncle)。
2.2.2 情况1:变色
叔叔存在且为红。
p和u变黑,g变红,
再c = g,c如果是根,c变黑,操作结束,如果是局部子树的根,继续向上判断。
如果p是g的右,操作相同。
注意:无所谓c是p的左或右,因为是c的p,g,u变色。
2.2.3 情况2:单旋+变色
叔叔存在且为黑,或叔叔不存在。bh(black height)为路径上黑色节点的数量。
对g进行右旋,将p(根)变黑,g变红。 对g进行左旋,其他操作相同。
旋转后,子树根节点是黑色,且满足规则3,4,操作结束。
2.2.4 情况3:双旋+变色
叔叔存在且为黑,或叔叔不存在。bh(black height)为路径上黑色节点的数量。
先对p进行左旋,再对g进行右旋,将c(根)变黑,g变红。 先对p进行右旋,再对g进行左旋,相同操作相同。
旋转后,子树根节点是黑色,且满足规则3,4,操作结束。
2.2.5 红黑树插入的代码实现
bool Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (kv.first > cur->_kv.first){parent = cur;cur = cur->_right;}else if (kv.first < cur->_kv.first){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(kv);if (kv.first > parent->_kv.first)parent->_right = cur;elseparent->_left = cur;cur->_parent = parent;while (parent&&parent->_col == RED){Node* grandfather = parent->_parent;Node* uncle;if (parent == grandfather->_left){// g// p uuncle = grandfather->_right;if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_left){RotateR(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{RotateL(parent);RotateR(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}else{// g// u puncle = grandfather->_left;if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{RotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}if (parent == nullptr)_root->_col = BLACK;return true;}
2.3 红黑树的查找
Node* Find(const K& key){Node* cur = _root;while (cur){if (key > cur->_kv.first)cur = cur->_right;else if (key < cur->_kv.first)cur = cur->_left;elsereturn cur;}return nullptr;}
2.4 红黑树的验证
1. 规则1通过枚举颜色类型来天然保证颜色要么是黑色要么是红色。
2. 规则2只需直接检查根节点即可满足条件。
3. 规则3采用前序遍历进行检查,当遇到红色节点时,检查其孩子节点不太方便,因为孩子节点有两个且不一定都存在。相反,遇到红色节点,检查父节点的颜色更方便。
4. 规则4使用前序遍历,在遍历过程中通过形参记录从根节点到当前节点的黑色节点数量(blackNum)。每遇到黑色节点,++blackNum。当遍历到空节点时,就计算出了一条路径上的黑色节点数量。然后,可以将任意一条路径的黑色节点数量作为参考值,依次进行比较即可。
bool IsBalance(){if (_root->_col != BLACK)return false;Node* cur = _root;int refNum = 0;while (cur){if (cur->_col == BLACK)++refNum;cur = cur->_left;}return _IsBalance(_root, 0, refNum);}bool _IsBalance(Node* root, int blackNum, const int refNum){if (root == nullptr){if (blackNum != refNum)return false;elsereturn true;}if (root->_col == RED && root->_parent->_col == RED)return false;if (root->_col == BLACK)++blackNum;return _IsBalance(root->_left, blackNum, refNum) && _IsBalance(root->_right, blackNum, refNum);}
2.5 红黑树的删除
红黑树的删除本章节不做讲解,有兴趣的同学可参考:《算法导论》或者《STL源码剖析》中讲解。
2.6 红黑树的代码实现
2.6.1 RBTree
#pragma once#include <iostream>
#include <assert.h>using namespace std;namespace Lzc
{enum Color{RED,BLACK};template<class K,class V>struct RBTreeNode{pair<K,V> _kv;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;Color _col;RBTreeNode(const pair<K,V>& kv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr),_col(RED){ }};template<class K,class V>class RBTree{typedef RBTreeNode<K, V> Node;public:bool Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (kv.first > cur->_kv.first){parent = cur;cur = cur->_right;}else if (kv.first < cur->_kv.first){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(kv);if (kv.first > parent->_kv.first)parent->_right = cur;elseparent->_left = cur;cur->_parent = parent;while (parent&&parent->_col == RED){Node* grandfather = parent->_parent;Node* uncle;if (parent == grandfather->_left){// g// p uuncle = grandfather->_right;if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_left){RotateR(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{RotateL(parent);RotateR(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}else{// g// u puncle = grandfather->_left;if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;cur = grandfather;parent = cur->_parent;}else{if (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{RotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}if (parent == nullptr)_root->_col = BLACK;return true;}void RotateR(Node* parent){Node* pParent = parent->_parent;Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;parent->_parent = subL;subL->_parent = pParent;if (pParent == nullptr) // 当pParent == nullptr时,_root == parent{_root = subL;}else{if (pParent->_left == parent)pParent->_left = subL;elsepParent->_right = subL;}}void RotateL(Node* parent){Node* pParent = parent->_parent;Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;parent->_parent = subR;subR->_parent = pParent;if (pParent == nullptr)_root = subR;else{if (pParent->_left == parent)pParent->_left = subR;elsepParent->_right = subR;}}Node* Find(const K& key){Node* cur = _root;while (cur){if (key > cur->_kv.first)cur = cur->_right;else if (key < cur->_kv.first)cur = cur->_left;elsereturn cur;}return nullptr;}void InOrder(){_InOrder(_root);}int Height(){return _Height(_root);}int Size(){return _Size(_root);}bool IsBalance(){if (_root->_col != BLACK)return false;Node* cur = _root;int refNum = 0;while (cur){if (cur->_col == BLACK)++refNum;cur = cur->_left;}return _IsBalance(_root, 0, refNum);}~RBTree(){Destroy(_root);_root = nullptr;}void Destroy(Node* root){if (root == nullptr)return;Destroy(root->_left);Destroy(root->_right);delete root;}private:void _InOrder(Node* root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_kv.first << ":" << root->_kv.second << endl;_InOrder(root->_right);}int _Height(Node* root){if (root == nullptr)return 0;int LeftHeight = _Height(root->_left);int RightHeight = _Height(root->_right);return LeftHeight > RightHeight ? LeftHeight + 1 : RightHeight + 1;}int _Size(Node* root){if (root == nullptr)return 0;return _Size(root->_left) + _Size(root->_right) + 1;}bool _IsBalance(Node* root, int blackNum, const int refNum){if (root == nullptr){if (blackNum != refNum)return false;elsereturn true;}if (root->_col == RED && root->_parent->_col == RED)return false;if (root->_col == BLACK)++blackNum;return _IsBalance(root->_left, blackNum, refNum) && _IsBalance(root->_right, blackNum, refNum);}Node* _root = nullptr;};
}
2.6.2 Test.cpp
#include"RBTree.h"
#include<vector>
#include<time.h>namespace Lzc
{void TestRBTree1() {RBTree<int, int> rbt;// 常规的测试用例int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };// 特殊的带有双旋场景的测试用例// int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };for (auto e : a) {rbt.Insert({ e, e });}rbt.InOrder();cout << rbt.IsBalance() << endl;}// 插入一堆随机值,测试平衡,顺便测试一下高度和性能等void TestRBTree2() {const int N = 100000;vector<int> v;v.reserve(N);srand(time(0));for (size_t i = 0; i < N; i++) {v.push_back(rand() + i);}// 测试插入性能size_t begin2 = clock();RBTree<int, int> rbt;for (auto e : v) {rbt.Insert(make_pair(e, e));}size_t end2 = clock();cout << "Insert:" << end2 - begin2 << endl;// 测试平衡性、高度和大小cout << "IsBalance:" << rbt.IsBalance() << endl;cout << "Height:" << rbt.Height() << endl;cout << "Size:" << rbt.Size() << endl;// 测试查找性能size_t begin1 = clock();// 查找已存在的值/*for (auto e : v) {rbt.Find(e);}*/// 查找随机值for (size_t i = 0; i < N; i++) {rbt.Find((rand() + i));}size_t end1 = clock();cout << "Find:" << end1 - begin1 << endl;}}int main()
{Lzc::TestRBTree1();//Lzc::TestRBTree2();return 0;
}
相关文章:
C++进阶——红黑树的实现
目录 1、红黑树的概念 1.1 红黑树的定义 1.2 红黑树的规则 1.3 为什么没有一条路径会比其他路径长出两倍 1.4 红黑树的性能 2、红黑树的实现 2.1 红黑树的结构 2.2 红黑树的插入 2.2.1 红黑树插入一个值的大概过程 2.2.2 情况1:变色 2.2.3 情况2ÿ…...
Linux 文件操作-标准IO函数1-文件指针、文件缓冲区(行缓冲、全缓冲、无缓冲)的验证
目录 1.文件指针 2.文件缓冲区 2.1 行缓冲 2.2. 全缓冲 2.3. 无缓冲 3. 程序验证: (1)main.c执行test1(),打印hello world,不加 \n 换行符 (2)刷新缓冲区方法1:使用\n (3&am…...
中国历史文化名城分布矢量数据
中国,这片古老而厚重的土地,承载着上下五千年的文明,从北国的冰天雪地到南疆的热带雨林,从东海之滨的波涛汹涌到西域大漠的风沙漫天,无数的历史文化名城如繁星般散布其间。 它们是岁月长河中沉淀下来的瑰宝࿰…...
蓝桥杯十天冲刺-day1(日期问题)
日期问题 基础循环遍历模板 对于蓝桥杯所有的日期问题遍历,都可以使用的上 for(year2000;year<2022;year) for(month1;month<12;month) for(day1;day<31;day) {if(month1||month3||month5||month7||month8||month10||month12);else if(month2){if((year…...
漏洞知识点《Tornado框架中RequestHandler的对象》
Tornado框架中RequestHandler的所有对象 [SUPPORTED_METHODS, _INVALID_HEADER_CHAR_RE, __class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __init_subclass__, __le__, __lt__, __module__,…...
动态规划(6.不同路径II)
题目链接:63. 不同路径 II - 力扣(LeetCode) 解法: 本题为不同路径的变型,只不过有些地方有「障碍物」,只要在「状态转移」上稍加修改就可解决。 状态表示: 对于这种Γ路径类」的问题…...
【算法学习】最小公倍数问题
前言: 求最小公倍数的两种算法: 求两个正整数的最小公倍数,比如3和5的最小公倍数是15,6和8的最小公倍数是24。 本片讨论如何求两个数的最小公倍数,第一种方法是通过最大公约数来求,第二种方法是累加法。 由…...
Spring Boot 整合 Apache Flink 教程
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 Spring Boot 整合 Apache Flink 教程 一、背景与目标 Apache Flink 是一个高性能的分布式流处理框架,而Spring Boot提供了快速构建企业级应用的…...
进制转换(R转十)(1290. 二进制转换十进制、1292. 十六进制转十进制、1291. 八进制转十进制、1405. 小丽找潜在的素数)
题单地址:题单中心-东方博宜OJ 这里以二进制转十进制为例(按位加权求和法) 1290. 二进制转换十进制 问题描述 请将一个 25 位以内的 2 进制正整数转换为 1010 进制! 输入 一个 25 位以内的二进制正整数。 输出 该数对应的…...
通过启用Ranger插件的Hive审计日志同步到Doris做分析
以下是基于Apache Doris的Ranger Hive审计日志同步方案详细步骤,结合审计日志插件与数据导入策略实现: 一、Doris环境准备 1. 创建审计日志库表 参考搜索结果的表结构设计,根据Ranger日志字段调整建表语句: CREATE DATABASE IF…...
Node.js框架Express、Koa、Koa2、Egg 和 NestJS 的对比分析
以下是 Express、Koa、Koa2、Egg 和 NestJS 的对比分析,从多个维度梳理它们的区别和适用场景: 1. 历史背景与定位 框架背景与定位ExpressNode.js 早期框架,灵活轻量,生态丰富,适合快速开发简单应用。KoaExpress 原班团…...
蓝桥杯--冲刺题单--随时更新
冲刺题单 感谢up主溶金落梧桐(uid:40733116),我是看了他的视频后总结的。 简单模拟(循环数组日期进制) 1.蓝桥19723–分布式队列 package datasimulation;import java.util.Scanner;public class Test3 {//计算数组…...
新一代电子数据取证专家 | 苏州龙信信息科技有限公司
本文关键词:电子取证、手机取证、计算机取证、云取证 关于我们About us 苏州龙信信息科技有限公司专注于电子数据取证、大数据、信息安全等领域,核心业务主要涵盖取证工具研发、大数据融合分析、案件技术支持、取证能力培训等,先后为执法部门…...
SSRF 攻击与防御:从原理到落地实践
1. 什么是 SSRF? SSRF(Server-Side Request Forgery) 是一种常见的Web安全漏洞。当服务器提供了某种对外请求的功能,如“URL 参数直接转发请求”,攻击者就可以通过精心构造的URL,让服务器“自己”去访问特…...
socks 协议介绍
SOCKS协议详解 一、基本定义与核心功能 SOCKS(Socket Secure)是一种网络传输协议,主要用于通过代理服务器转发客户端与目标服务器之间的通信请求。其核心功能包括隐藏用户真实IP地址、穿透防火墙限制以及支持多种网络协议(如TCP…...
不使用负压电源,ADC如何测量正负压?
电路图来自ZLinear的开源数据采集板卡DL8884_RFN,是一个比较常见的电压偏置采集法 对电路进行分析,所以说可以先看下采集卡的模拟输入部分的参数如下: 通道数量: 8通道单端输入/4通道差分输入 分辨率: 16位逐次逼近型(SAR) ADC 采样速率: 40…...
服务的拆分数据的迁移
参考: 数据迁移调研...
强推 Maven多镜像源快速切换工具,GUI操作超便捷
引言 在开发过程中,配置Maven的settings.xml文件以优化依赖下载速度是一个常见的需求。然而,手动编辑XML文件不仅繁琐,还容易出错。本文将介绍如何使用Python和Tkinter构建一个图形界面工具,帮助开发者快速、安全地切换Maven镜像…...
Qt6.8实现麦克风音频输入音频采集保存wav文件
一.本文目的 实现在Qt中接收麦克风数据并保存为WAV文件,使用QAudioInput来录音,并使用QFile来保存数据到WAV文件。 开发环境:QT6.8 本文用极简代码实现,核心代码只需不到100行。 二.代码实现...
自动驾驶AEB误触发率评估的必要测试里程估计
文章目录 一 问题背景与行业挑战二 数学建模框架2.1 基础假设2.2 贝叶斯推断流程先验分布选择: 使用 Γ \Gamma Γ分布作为 λ \lambda λ的共轭先验参数 α 0 \alpha_0 α0和 β 0 \beta_0 β0的工程物理意义可靠性判断条件 三 数值求解方法1. 无信息先验场景 ( α 0 1 ,…...
python3 -m http.sever 8080加载不了解决办法
解决方法很多,本文设置各种处理方法,逻辑上需要根据你的自身情况选择 我会告诉你遇到这种问题怎么做,根据具体症状处理 如需转载,标记出处 背景: 1。如图 2.。域名访问不了 http://www.meiduo.site:8080/register.html 上面的域名访问不了,下面的倒是正常 http://127…...
BYU-YOLO数据格式准备
BYU - Locating Bacterial Flagellar Motors 2025(在3D断层扫描图像中定位细菌鞭毛马达) 一、数据介绍 1.竞赛介绍 在本次竞赛中,您的任务是在3D断层扫描图像中找到鞭毛马达的中心位置。断层扫描图像是物体的三维体积表示。每个断层扫描图像作为一个独立的目录提供,其中…...
java NIO中的FileSystems工具类可以读取本地文件系统,ZIP/JAR等,无需解压处理,还可以复制文件
在Java NIO(java.nio.file包)中,FileSystems 是一个工具类,用于操作和管理文件系统。它提供了静态方法来获取或创建文件系统实例,并支持自定义文件系统实现。以下是其核心功能和用法: 1. 核心功能 (1) 获取…...
群体智能优化算法-模拟退火优化算法(Simulated Annealing, SA,含Matlab源代码)
摘要 模拟退火(SA)算法是一种基于物理退火过程的全局优化算法,其核心思想来源于热力学中的退火过程:将材料加热到高温后再缓慢冷却,使其分子结构趋于最低能量状态,从而获得稳定结构。SA 算法利用 Metropol…...
knowledge-微前端(多个前端应用聚合的一个应用架构体系,每个小的应用可独立运行,独立开发,独立部署上线)
1.前言 微前端,将一个大的前端应用拆分为多个小型的,独立开发的前端应用,每一个小型的应用都可以单独的开发,部署和运行。这种结构允许不同的团队使用不同的技术栈来开发应用的不同部分,提高开发的效率与灵活性。 2.实…...
目标检测中归一化的目的?
在目标检测任务中,归一化坐标和尺寸时需要除以图像的宽度和高度,主要有以下几个原因: 1. 统一尺度 不同图像可能具有不同的宽度和高度。通过将坐标和尺寸除以图像的宽度和高度,可以将所有图像的标注信息统一到相同的尺度范围([0, 1])。这使得模型在训练和推理时能够处理…...
HarmonyOs- UIAbility应用上下文
上下文为何物 上下文在计算机科学领域是一个广泛存在的概念。是现代操作系统核心抽象概念之一。其本质是环境信息的结构化封装。 有过开发经验的都知道,当我们在一个系统上进行开发的时候,无论是Android,HarmonyOs,Linux 等等&a…...
鸿蒙开发真机调试:无线调试和USB调试
前言 在鸿蒙开发的旅程中,真机调试堪称至关重要的环节,其意义不容小觑。虽说模拟器能够为我们提供初步的测试环境,方便我们在开发过程中快速预览应用的基本效果,但它与真机环境相比,仍存在诸多差异。就好比在模拟器中…...
【门店租金指定日期区间计算】
目录 一、背景(一)业务场景(二)相关数据支撑 二、计算方法统一封装(一)门店租金数据表格逻辑(二)业务逻辑详细解释(三)具体代码 一、背景 (一&am…...
Dify:开源大模型应用开发平台全解析
从部署到实践,打造你的AI工作流 一、项目简介 Dify 是一款面向开发者和企业的开源大语言模型(LLM)应用开发平台,旨在降低AI应用开发门槛,让用户通过可视化界面快速构建、管理和部署基于大模型的智能应用。其名称寓意“…...
使用DDR4控制器实现多通道数据读写(四)
在创建完DDR4的仿真模型后,我们为了实现异步时钟的读写,板卡中在PL端提供了一组差分时钟,可以用它通过vivado中的Clock Wizard IP核生成多个时钟,在这里生成两个输出时钟,分别作为用户的读写时钟,这样就可以…...
BFS--------N叉树的层序遍历
429. N 叉树的层序遍历 - 力扣(LeetCode) 1.题目解析 给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。 树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(…...
蓝桥杯备考----小贪心+分类讨论问题---Popsicle
这道题有点小贪心的意思,小老鼠每次都想阻碍小猫最多,老鼠每次阻碍猫的话,可能是把0变成9 也可能是把1变成9,再有可能把2变成9,把3变成9,小老鼠的贪心就是尽可能更多的阻碍小猫拿冰棍,所以小老…...
强大的AI网站推荐(第一集)—— Devv AI
网站:Devv AI 号称:最懂程序员的新一代 AI 搜索引擎 博主评价:我的大学所有的代码都是使用它,极大地提升了我的学习和开发效率。 推荐指数:🌟🌟🌟🌟🌟&#x…...
【问题解决】Postman 测试报错 406
现象 Tomcat 日志 org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved org.springframework.web.HttpMediaTypeNotAcceptableException: No acceptable representation HTTP状态 406 - 不可接收 的报错,核心原因 客…...
互联网it常用抓包工具说明
一、引言 在互联网 IT 领域,无论是网络故障排查、安全检测,还是开发调试,抓包工具都发挥着举足轻重的作用。 当网络出现故障,比如网页加载缓慢、应用无法连接服务器时,抓包工具可以帮助我们捕获网络数据包࿰…...
RS485总线加终端电阻可能存在的问题
目录 1、降低驱动信号幅值 2、增大通信线压降 3、增大收发器功耗 4、降低总线空闲时的差分电压 尽管终端电阻能有效减少信号反射、提高信号质量,但它也引入了一系列问题,需要在设计中谨慎考虑。以下是几个常见问题的详细分析: 1、降低驱…...
在 Linux 系统上部署 Deepseek AI 的全面指南
对于所有希望亲身体验 AI 魅力的玩家来说,本文将提供一个详尽的教程,指导你在 Linux 系统上部署 Deepseek AI。无论你是技术小白还是有一定基础的用户,都能轻松跟随本文完成部署。 一、关于 Ollama Ollama 是一款功能强大的开源应用&am…...
Docker下载,包含Win、Mac
介绍 Docker 是一种开源的容器化平台,通过操作系统级虚拟化技术实现应用的快速开发、部署和运行。以下从多个维度对 Docker 进行详细介绍: 一、Docker 的核心概念与功能 容器化技术 Docker 利用 Linux 内核的容器隔离技术(如 Cgroups 和 Nam…...
算法|2025最强优化算法
根据2025年的最新研究进展,以下是被广泛认可的几种“最强优化算法”,它们在理论创新、性能表现和应用范围上均有显著突破: 一、植物根茎生长优化算法(PRGO) 1 - 核心原理:灵感来源于植物根系结构…...
Prime: 1靶场渗透测试
Prime: 1 来自 <Prime: 1 ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.207 3,对靶机进行端口服务探测…...
html相关常用语法
html相关常用语法 HTML(HyperText Markup Language)即超文本标记语言,是用于创建网页的标准标记语言 HTML使用标记语言描述Web页面的结构 HTML元素是HTML页面的建构快 HTML元素通过标签tag来表示 HTML标签是“标题”、”段落“、”表格“等内…...
2025年R1 快开门式压力容器操作证考试题目及答案解析
R1 快开门式压力容器操作证考试题目及答案: 单选题 1、快开门式压力容器的快开门(盖)应设计安全联锁装置并应具有( )功能。 A. 当快开门达到预定关闭部位方能升压运行的安全联锁功能 B. 当压力容器的内部压力完全释…...
《傲慢与偏见》(Pride and Prejudice)简介
学习《傲慢与偏见》 本文缘于阅读床头灯3000词英文版《傲慢与偏见》。读完之后,想要了解的更深一点。 英语学习记录:床头灯3000词:《傲慢与偏见》(Pride and Prejudice)阅读记录 故事梗概 《傲慢与偏见》(…...
绿盟科技春招面试
《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇网安资料库https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…...
dpkg-architecture命令详解
dpkg-architecture 是 Debian 系系统中用于处理软件包架构相关操作的工具,尤其在软件包构建和交叉编译环境中至关重要。以下是其核心功能及用法的详细说明: 一、核心功能 架构查询与验证 显示或验证当前系统(DEB_HOST_ARCHÿ…...
阿里的MNN源码如何编译成so文件,供Android调用
在Ubtuntu下面的编译,先整理编译环境 1、安装环境依赖 # 安装必要工具 sudo apt update sudo apt install -y cmake ninja-build git wget # 安装Android NDK(建议使用r21版本或更高) wget https://dl.google.com/android/repository/a…...
【高项】信息系统项目管理师(九)项目资源管理【4分】
项目资源管理包括识别、获取和管理所需资源以成功完成项目的各个过程,这些过程有助于确保项目经理和项目团队在正确的时间和地点使用正确的资源。项目资源是指对于项目来说,一切具有使用价值,可为项目接受和利用,且属于项目发展过程所需的客观存在的资源,包括实物资源和团…...
hive 数据简介
Hive介绍 1)Hive简介 Hive是基于Hadoop的一个数据仓库工具,用于结构化数据的查询、分析和汇总。Hive提供类SQL查询功能,它将SQL转换为MapReduce程序。 Hive不支持OLTP,Hive无法提供实时查询。 2)Hive在大数据生态环境…...
SpringBoot的启动原理?
大家好,我是锋哥。今天分享关于【SpringBoot的启动原理?】面试题。希望对大家有帮助; SpringBoot的启动原理? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Boot的启动原理主要是通过 SpringApplication 类来…...