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

c++之二叉树【进阶版】

前言

        在c语言阶段的数据结构系列中已经学习过二叉树,但是这篇文章是二叉树的进阶版,因为首先就会讲到一种树形结构“二叉搜索树”,学习二叉搜索树的目标是为了更好的理解map和set的特性。二叉搜索树的特性就是左子树键值小于根,右子树键值大于根,所以二叉搜索树就天然的具有查找功能,有时二叉搜索树又叫二叉排序树或者二叉查找树。

目录

前言

Ⅰ、二叉搜索树概念

Ⅱ、二叉搜索树操作

Ⅲ、二叉搜索树的实现

Ⅳ、 二叉搜索树的应用

Ⅴ、二叉搜索树的性能分析

Ⅵ、二叉树进阶面试题


Ⅰ、二叉搜索树概念

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

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

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

        ●它的左右子树也分别为二叉搜索树

        ●它没有重复的键值

Ⅱ、二叉搜索树操作

 int   a[ ] = {8,         3,         1,         10,         6,         4,         7,         14,         13};

1. 二叉搜索树的查找

        a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。

        b、最多查找高度次,走到到空,还没找到,这个值不存在。

2. 二叉搜索树的插入

插入的具体过程如下:

        a. 树为空,则直接新增节点,赋值给root指针

        b. 树不空,按二叉搜索树性质查找插入位置,插入新节点

 

1. 二叉搜索树的删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情 况:

        a. 要删除的结点无孩子结点

        b. 要删除的结点只有左孩子结点

        c. 要删除的结点只有右孩子结点

        d. 要删除的结点有左、右孩子结点

看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程 如下:

        ●情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除

        ●情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除

        ●情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点 中,再来处理该结点的删除问题--替换法删除

如图理解,情况a实质就是删除1,4,7,13可以直接删除。

关于情况b,情况c,就需要详细探讨

对于情况d是最难以理解的,这种情况就好比删除3和8,他们是需要替换法删除的场景,这种情况就需要找子树右边的最小值(minright),找到之后minright的key值与cur的key交换(赋值)后再判断后进行链接。

但是通下面代码我们发现,这段代码删除8时就会发现root为nullptr,这样就出现错误了,还有一个问题就是minright可以是parent左右子树,所以关于删除的时候还需要判断是否parent的左右子树

Ⅲ、二叉搜索树的实现

二叉搜索树代码的实现,查找,插入是比较容易理解的,对于删除考虑的情况比较多。主要分三种情况,1.直接删除,2.左右子树为nullptr,交换删除,3.左右子树都不为nullptr,需要找minright替换key值后链接。

对于整个结构与我之前学习的二叉树基本一样,只是用到了c++,封装了节点(该节点中有左右节点和key值),通过模板实现不同参数的调用。

非递递归代码实现如下

#pragma once
#include <iostream>
#include <string>
using namespace std;namespace K
{template<class K>struct BSTreeNode{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_key(key), _left(nullptr), _right(nullptr){}};template<class K>class BSTree{typedef BSTreeNode<K> Node;public:BSTree():_root(nullptr){}BSTree(const BSTree<K> &t){_root = Copy(t._root);}BSTree<K>& operator=(BSTree<K> t){swap(_root, t._root);return *this;}~BSTree(){Destroy(_root);_root=nullptr;}bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}Node* parent = nullptr;Node* 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 Node(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}bool Erase(const K& key){Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{// 1、左为空// 2、右为空// 3、左右都不为空,替换删除if (cur->_left == nullptr){//if (parent == nullptr)if (cur == _root){_root = cur->_right;}else{if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete cur;}else if (cur->_right == nullptr){//if (parent == nullptr)if (cur == _root){_root = cur->_left;}else{if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete cur;}else{// 右子树的最小节点Node* parent = cur;Node* minRight = cur->_right;while (minRight->_left){parent = minRight;minRight = minRight->_left;}cur->_key = minRight->_key;if (minRight == parent->_left){parent->_left = minRight->_right;}else{parent->_right = minRight->_right;}delete minRight;}return true;}}return false;}void InOrder(){_InOrder(_root);cout << endl;}private:void Destroy(Node* root){if (root == nullptr)return;Destroy(root->_left);Destroy(root->_right);delete root;}Node*  Copy(Node *root){if (root == nullptr)return nullptr;Node* newRoot = new Node(root->_key);newRoot->_left = Copy(root->_left);newRoot->_right = Copy(root->_right);return newRoot;}bool Find(const K& key){Node* cur = _root;while (cur){if (cur->_key < key)cur = cur->_right;else if (cur->_key > key)cur = cur->_left;elsereturn true;}return false;}void _InOrder(Node* root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}private:Node* _root = nullptr;};
}

递归

这里递归主要讲解删除(Erase),相信大家之前对递归也是有所涉猎的。对于Erase的实现,开始也是通过递归查找key节点,还需要循环找到minright,然后通过(swap)交换key值和minright值,之后再通过递归(cur的子树)删除。下面我们就来深入分析递归删除,列如删除如图3。

        ●1.先通过递归查找到删除节点

         ●2.如果是左右子树为nullptr,直接链接到根(root)

         ●3.这里如果删除的是3,就是通过上面步骤找到3为cur,然后判断出cur的左右子树都不为nullptr,这时就需要寻找minright,找到minright之后,swap交换(3,4),然后递归删除4节点的右子树的3。

最后需要注意的一点是,递归就会调用_root,所以我们可以在类中先封装再调用。

非递归代码实现如下 

namespace K
{template<class K>struct BSTreeNode{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_key(key), _left(nullptr), _right(nullptr){}};template<class K>class BSTree{typedef BSTreeNode<K> Node;public:BSTree():_root(nullptr){}BSTree(const BSTree<K> &t){_root = Copy(t._root);}BSTree<K>& operator=(BSTree<K> t){swap(_root, t._root);return *this;}~BSTree(){Destroy(_root);_root=nullptr;}void InOrder(){_InOrder(_root);cout << endl;}bool InsertR(const K& key){return _InsertR(_root,key);}bool FindR(const K& key){return _FindR(_root, key);}bool EraseR(const K& key){return _EraseR(_root, key);}private:void Destroy(Node* root){if (root == nullptr)return;Destroy(root->_left);Destroy(root->_right);delete root;}Node*  Copy(Node *root){if (root == nullptr)return nullptr;Node* newRoot = new Node(root->_key);newRoot->_left = Copy(root->_left);newRoot->_right = Copy(root->_right);return newRoot;}bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;if (root->_right == nullptr){root = root->_left;}else if (root->_left == nullptr){root = root->_right;}else{Node* minRight = root->_right;while (minRight->_left){minRight = minRight->_left;}swap(root->_key, minRight->_key);// 转换后在子树中去删除节点return _EraseR(root->_right, key);}delete del;return true;}}bool _InsertR(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (root->_key < key)return  _InsertR(root->_right, key);else if (root->_key > key)return  _InsertR(root->_left, key);elsereturn false;}bool _FindR(Node* root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return  _FindR(root->_right);}else if (root->_key> key){return _FindR(root->_left);}else{return true;}}
private:Node* _root = nullptr;};
}

Ⅳ、 二叉搜索树的应用

1. K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。 比如:给一个单词word,判断该单词是否拼写正确,具体方式如下:

        ○以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树

        ○在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。

2. KV模型:每一个关键码key,都有与之对应的值Value,即的键值对。该种方式在现实生活中非常常见:

        ○比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文就构成一种键值对;

        ○再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是就构成一种键值对。

改造二叉搜索树为KV结构如下

namespace KV
{template<class K, class V>struct BSTreeNode{BSTreeNode<K, V>* _left;BSTreeNode<K, V>* _right;K _key;V _value;BSTreeNode(const K& key, const V& value):_key(key), _value(value), _left(nullptr), _right(nullptr){}};template<class K, class V>class BSTree{typedef BSTreeNode<K, V> Node;public:bool Insert(const K& key, const V& value){if (_root == nullptr){_root = new Node(key, value);return true;}Node* parent = nullptr;Node* 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 Node(key, value);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}Node* Find(const K& key){Node* cur = _root;while (cur){if (cur->_key < key){cur = cur->_right;}else if (cur->_key > key){cur = cur->_left;}else{return cur;}}return nullptr;}void Inorder(){_Inorder(_root);}void _Inorder(Node* root){if (root == nullptr)return;_Inorder(root->_left);cout << root->_key << ":" << root->_value << endl;_Inorder(root->_right);}private:Node* _root = nullptr;};
}

测试1:通过英文查找中文,这个时候就用到KV搜索树,我们可以给树的key和value定义都为string类型,然后将信息插入到KV搜索树。最后通过查找key值,如果有就打印value即可。

void TestBSTree2()
{//词库中单词都放进这个搜索树中//key的搜索模型,判断在不在?//场景:检查单词拼写是否正确/车库出入系统/...//K::BSTree<string> dict;//Key/Value的搜索模型,通过Key查或者修改ValueKV::BSTree<string, string> dict;dict.Insert("sort", "排序");dict.Insert("string", "字符串");dict.Insert("left", "左边");dict.Insert("right", "右边");string str;while(cin >> str){KV::BSTreeNode<string, string>* ret = dict.Find(str); if (ret){cout << ret->_value << endl;}else{cout << "没有这个单词" << endl;}}}
编译结果:sort 排序        left 左边        right 右边        hello 没有这个单词

测试2:统计水果出现的次数

void TestBSTree3()
{string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉" };KV::BSTree<string, int> countTree;for (auto e : arr){auto* ret = countTree.Find(e);if (ret == nullptr){countTree.Insert(e, 1);}else{ret->_value++;}}countTree.Inorder();
}

Ⅴ、二叉搜索树的性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。 对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二 叉搜索树的深度的函数,即结点越深,则比较次数越多。

但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:

 

 

最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其平均比较次数为:$log_2 N$

最差情况下,二叉搜索树退化为单支树(或者类似单支),其平均比较次数为:$\frac{N}{2}$

问题:如果退化成单支树,二叉搜索树的性能就失去了。那能否进行改进,不论按照什么次序插 入关键码,二叉搜索树的性能都能达到最优?那么我们后续章节学习的AVL树和红黑树就可以上场了。

Ⅵ、二叉树进阶面试题

这些题目更适合使用C++完成,难度也更大一些

        1. 二叉树创建字符串。OJ链接

        2. 二叉树的分层遍历1。OJ链接

        3. 二叉树的分层遍历2。OJ链接

        4. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 。OJ链接

        5. 二叉树搜索树转换成排序双向链表。OJ链接

        6. 根据一棵树的前序遍历与中序遍历构造二叉树。 OJ链接

        7. 根据一棵树的中序遍历与后序遍历构造二叉树。OJ链接

        8. 二叉树的前序遍历,非递归迭代实现 。OJ链接

        9. 二叉树中序遍历 ,非递归迭代实现。OJ链接

        10. 二叉树的后序遍历 ,非递归迭代实现。OJ链接

相关文章:

c++之二叉树【进阶版】

前言 在c语言阶段的数据结构系列中已经学习过二叉树&#xff0c;但是这篇文章是二叉树的进阶版&#xff0c;因为首先就会讲到一种树形结构“二叉搜索树”&#xff0c;学习二叉搜索树的目标是为了更好的理解map和set的特性。二叉搜索树的特性就是左子树键值小于根&#xff0c;右…...

【数据库】 SQLServer

SQL Server 安装 配置 修改SQL Server默认的数据库文件保存路径_ 认识 master &#xff1a;是SQL Server中最重要的系统数据 库&#xff0c;存储SQL Server中的元数据。 Model&#xff1a;模板数据库&#xff0c;在创建新的数据库时&#xff0c;SQL Server 将会复制此数据…...

Linux 4.19 内核中 spinlock 概览

Linux内核中 spinlock相关数据结构和代码实现涉及的文件还是挺多的&#xff0c;这篇博客尝试从文件的角度来梳理一下 spinlock的相关数据结构和代码实现&#xff0c;适合想大概了解 Linux内核中 spinlock从上层 API到底层实现间的调用路径和传参变化&#xff0c;尤其适合了解 s…...

TensorFlow 1.x学习(系列二 :1):基本概念TensorFlow的基本介绍,图,会话,会话中的run(),placeholder(),常见的报错

目录1.基本介绍2.图的结构3.会话&#xff0c;会话的run方法4.placeholder5.返回值异常写在前边的话&#xff1a;之前发布过一个关于TensorFlow1.x的转载系列&#xff0c;自己将基本的TensorFlow操作敲了一遍&#xff0c;但是仍然有很多地方理解的不够深入。所以重开一个系列&am…...

javaEE 初阶 — 关于 IPv4、IPv6 协议、NAT(网络地址转换)、动态分配 IP 地址 的介绍

文章目录1. IPv42. IPv63. NAT4. 动态分配 IP 地址1. IPv4 在互联网的世界中只有 0 和1 &#xff0c;所以每个人都有一个由 0 和 1 组成的地址来让别人找到你。 这段由 0 和 1 组成的地址叫 IP 地址&#xff0c;这是互联网的基础资源&#xff0c;可以简单的理解为互联网的土地。…...

《Qt 6 C++开发指南》简介

我们编写的新书《Qt 6 C开发指南》在2月份终于正式发行销售了&#xff0c;这本书是对2018年5月出版的《Qt 5.9 C开发指南》的重磅升级。以下是本书前言的部分内容&#xff0c;算是对《Qt 6 C开发指南》的一个简介。1&#xff0e;编写本书的目的《Qt 5.9C开发指南》是我写的第一…...

CleanMyMac是什么清理软件?及使用教程

你知道CleanMyMac是什么吗&#xff1f;它的字面意思为“清理我的Mac”&#xff0c;作为软件&#xff0c;那就是一款Mac清理工具&#xff0c;Mac OS X 系统下知名系统清理软件&#xff0c;是数以万计的Mac用户的选择。它可以流畅地与系统性能相结合&#xff0c;只需简单的步骤就…...

Linux小黑板(9):共享内存

"My poor lost soul"上章花了不少的篇幅讲了讲基于管道((匿名、命名))技术实现的进程间通信。进程为什么需要通信&#xff1f;目的是为了完成进程间的"协同",提高处理数据的能力、优化业务逻辑的实现等等&#xff0c;在linux中我们已经谈过了一个通信的大类…...

Detr源码解读(mmdetection)

Detr源码解读(mmdetection) 1、原理简要介绍 整体流程&#xff1a; 在给定一张输入图像后&#xff0c;1&#xff09;特征向量提取&#xff1a; 首先经过ResNet提取图像的最后一层特征图F。注意此处仅仅用了一层特征图&#xff0c;是因为后续计算复杂度原因&#xff0c;另外&am…...

一个.Net Core开发的,撑起月6亿PV开源监控解决方案

更多开源项目请查看&#xff1a;一个专注推荐.Net开源项目的榜单 项目发布后&#xff0c;对于我们程序员来说&#xff0c;项目还不是真正的结束&#xff0c;保证项目的稳定运行也是非常重要的&#xff0c;而对于服务器的监控&#xff0c;就是保证稳定运行的手段之一。对数据库、…...

C语言数据结构初阶(2)----顺序表

目录 1. 顺序表的概念及结构 2. 动态顺序表的接口实现 2.1 SLInit(SL* ps) 的实现 2.2 SLDestory(SL* ps) 的实现 2.3 SLPrint(SL* ps) 的实现 2.4 SLCheckCapacity(SL* ps) 的实现 2.5 SLPushBack(SL* ps, SLDataType x) 的实现 2.6 SLPopBack(SL* ps) 的实现 2.7 SLP…...

K8S常用命令速查手册

K8S常用命令速查手册一. K8S日常维护常用命令1.1 查看kubectl版本1.2 启动kubelet1.3 master节点执行查看所有的work-node节点列表1.4 查看所有的pod1.5 检查kubelet运行状态排查问题1.6 诊断某pod故障1.7 诊断kubelet故障方式一1.8 诊断kubelet故障方式二二. 端口策略相关2.1 …...

Linux系统下命令行安装MySQL5.6+详细步骤

1、因为想在腾讯云的服务器上创建自己的数据库&#xff0c;所以我在这里是通过使用Xshell 7来连接腾讯云的远程服务器&#xff1b; 2、Xshell 7与服务器连接好之后&#xff0c;就可以开始进行数据库的安装了&#xff08;如果服务器曾经安装过数据库&#xff0c;得将之前安装的…...

13.STM32超声波模块讲解与实战

目录 1.超声波模块讲解 2.超声波时序图 3.超声波测距步骤 4.项目实战 1.超声波模块讲解 超声波传感器模块上面通常有两个超声波元器件&#xff0c;一个用于发射&#xff0c;一个用于接收。电路板上有4个引脚&#xff1a;VCC GND Trig&#xff08;触发&#xff09;&#xff…...

逆向之Windows PE结构

写在前面 对于Windows PE文件结构&#xff0c;个人认为还是非常有必要掌握和了解的&#xff0c;不管是在做逆向分析、免杀、病毒分析&#xff0c;脱壳加壳都是有着非常重要的技能。但是PE文件的学习又是一个非常枯燥过程&#xff0c;希望本文可以帮你有一个了解。 PE文件结构…...

ACL是什么

目录 一、ACL是什么 二、ACL的使用&#xff1a;setacl与getacl 1&#xff09;针对特定使用者的方式&#xff1a; 1. 创建acl_test1后设置其权限 2. 读取acl_test1的权限 2&#xff09;针对特定群组的方式&#xff1a; 3&#xff09;针对有效权限 mask 的设置方式&#xf…...

操作系统核心知识点整理--内存篇

操作系统核心知识点整理--内存篇按段对内存进行管理内存分区内存分页为什么需要多级页表TLB解决了多级页表什么样的缺陷?TLB缓存命中率高的原理是什么?段页结合: 为什么需要虚拟内存&#xff1f;虚拟地址到物理地址的转换过程段页式管理下程序如何载入内存&#xff1f;页面置…...

从零开始学习iftop流量监控(找出服务器耗费流量最多的ip和端口)

一、iftop是什么iftop是类似于top的实时流量监控工具。作用&#xff1a;监控网卡的实时流量&#xff08;可以指定网段&#xff09;、反向解析IP、显示端口信息等官网&#xff1a;http://www.ex-parrot.com/~pdw/iftop/二、界面说明>代表发送数据&#xff0c;< 代表接收数…...

第一篇博客------自我介绍篇

目录&#x1f506;自我介绍&#x1f506;学习目标&#x1f506;如何学习单片机Part 1 基础理论知识学习Part 2 单片机实践Part 3 单片机硬件设计&#x1f506;希望进入的公司&#x1f506;结束语&#x1f506;自我介绍 Hello!!!我是一名即已经步入大二的计算机小白。 --------…...

No suitable device found for this connection (device lo not available(网络突然出问题)

当执行 ifup ens33 出现错误&#xff1a;[rootlocalhost ~]# ifup ens33Error: Connection activation failed: No suitable device found for this connection (device lo not available because device is strictly unmanaged).1解决办法&#xff1a;[rootlocalhost ~]# chkc…...

Phi-4-mini-reasoning部署教程:容器化打包(Dockerfile)+ NVIDIA Container Toolkit

Phi-4-mini-reasoning部署教程&#xff1a;容器化打包&#xff08;Dockerfile&#xff09; NVIDIA Container Toolkit 1. 项目概述 Phi-4-mini-reasoning是微软推出的3.8B参数轻量级开源模型&#xff0c;专为数学推理、逻辑推导、多步解题等强逻辑任务设计。这款模型主打&quo…...

基于计算机视觉的AI头像质量评估系统

基于计算机视觉的AI头像质量评估系统 1. 引言 在数字社交时代&#xff0c;头像已经成为个人形象的重要代表。无论是社交平台、专业网站还是在线会议&#xff0c;一个高质量的头像都能显著提升个人形象和可信度。然而&#xff0c;如何快速评估头像的质量一直是个难题——什么样…...

Pixel Dream Workshop 企业级部署架构:基于 Docker 的高可用方案

Pixel Dream Workshop 企业级部署架构&#xff1a;基于 Docker 的高可用方案 1. 为什么企业需要高可用部署方案 当Pixel Dream Workshop从开发测试环境走向生产环境时&#xff0c;稳定性、扩展性和可维护性就成为了关键考量。想象一下&#xff0c;当营销团队急需批量生成节日…...

Qwen2.5-14B-Instruct在AI编剧赛道的突破:像素剧本圣殿Glitch标题交互体验分享

Qwen2.5-14B-Instruct在AI编剧赛道的突破&#xff1a;像素剧本圣殿Glitch标题交互体验分享 1. 像素剧本圣殿&#xff1a;AI编剧的新范式 在数字内容创作领域&#xff0c;剧本创作一直是最具挑战性的任务之一。传统编剧需要花费大量时间构思情节、塑造角色、打磨对白&#xff…...

HUNYUAN-MT惊艳翻译效果:专业领域长文档翻译案例集

HUNYUAN-MT惊艳翻译效果&#xff1a;专业领域长文档翻译案例集 最近在尝试各种翻译工具时&#xff0c;我偶然间用到了HUNYUAN-MT 7B模型来处理一些工作上的专业文档。说实话&#xff0c;一开始没抱太大期望&#xff0c;毕竟专业翻译的门槛不低&#xff0c;尤其是那些充满术语和…...

从零搭建到百万QPS:Python MCP服务器模板实战对比(含Docker镜像体积、CI/CD兼容性、调试友好度全维度打分)

第一章&#xff1a;从零搭建到百万QPS&#xff1a;Python MCP服务器模板实战对比总览在构建高并发、低延迟的MCP&#xff08;Model Control Protocol&#xff09;服务时&#xff0c;Python凭借其生态丰富性与开发效率成为主流选型之一&#xff0c;但原生GIL限制与异步模型差异常…...

错位排序算法

首先&#xff0c;让我们理解什么是错位排列&#xff1a;错位排列是指在排列中&#xff0c;任何一个元素都不在自己原来的位置上。比如&#xff0c;对于序列 {1,2,3}{1,2,3}&#xff0c;一个错位排列可能是 {3,1,2}{3,1,2}&#xff0c;因为 11 不在位置 11 上&#xff0c;22 不在…...

ZGC停顿时间为何突然飙升?3个被90%团队忽略的配置雷区曝光

第一章&#xff1a;ZGC停顿时间为何突然飙升&#xff1f;3个被90%团队忽略的配置雷区曝光 ZGC&#xff08;Z Garbage Collector&#xff09;以亚毫秒级停顿著称&#xff0c;但生产环境中频繁出现 10–50ms 甚至更高停顿&#xff0c;往往并非内存压力所致&#xff0c;而是源于几…...

数谷智能和爱莫科技,非标准数据 AI 定制处理谁更强?

在数字化转型步入“深水区”的今天&#xff0c;企业面临的最大挑战不再是标准化的数据库信息&#xff0c;而是占据企业数据总量 80% 以上的“非标准数据”。这些数据散落在手写单据、非结构化合同、复杂的网页信息、甚至是不规则的工业图像中。如何高效、精准地处理这些非标数据…...

万象视界灵坛惊艳效果展示:同一张宠物图在‘金毛犬’‘幼犬’‘户外玩耍’‘毛发蓬松’多维排序

万象视界灵坛惊艳效果展示&#xff1a;同一张宠物图在"金毛犬""幼犬""户外玩耍""毛发蓬松"多维排序 1. 效果展示开场 今天我要向大家展示万象视界灵坛这个神奇工具的实际效果。它就像一个视觉魔法师&#xff0c;能够深入理解图片中的…...