【C++】10道经典面试题带你玩转二叉树

🦄个人主页:修修修也

🎏所属专栏:C++

⚙️操作环境:Leetcode/牛客网


目录

一.根据二叉树创建字符串

二.二叉树的层序遍历

三.二叉树的层序遍历 II

四.二叉树的最近公共祖先

五.二叉搜索树与双向链表

六.从前序与中序遍历序列构造二叉树

七.从中序与后序遍历序列构造二叉树

八.二叉树的前序遍历(迭代算法)

九.二叉树的中序遍历(迭代算法)

十.二叉树的后序遍历(迭代算法)

结语


一.根据二叉树创建字符串

题目链接:

606. 根据二叉树创建字符串icon-default.png?t=O83Ahttps://leetcode.cn/problems/construct-string-from-binary-tree/


题目描述:

        给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

        空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。


题目详情:


解题思路:

        使用前序遍历遍历整颗树即可,但是要注意遍历根节点时不需要加括号,如果有子树,无论左子树有没有都要加括号,右子树有才加,没有就不加。具体细节见解题代码注释。

解题代码:

class Solution 
{
public:
    string tree2str(TreeNode* root) 
    {
        if(root)
        {
            //先遍历根节点
            string ret = to_string(root->val);//不用to_string用+48会遇到负数

            //只要左或右不为空,就进去执行,否则是叶子,直接返回
            if(root->left || root->right)
            {
                //再遍历左子树
                //因为左树为空也必须有"()",所以我们不用判断直接执行
                ret += ( '(' + tree2str(root->left) + ')' );

                //最后遍历右子树
                //因为右树为空没有"()",所以我们需要判断一下
                if(root->right)
                {
                    ret += ( '(' + tree2str(root->right) + ')' );
                }
            }
            return ret;
        }
        else
        {
            return "";
        }
    }
};

提交运行:


二.二叉树的层序遍历

题目链接:

102. 二叉树的层序遍历icon-default.png?t=O83Ahttps://leetcode.cn/problems/binary-tree-level-order-traversal/


题目描述:

        给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。


题目详情:


解题思路:

        思路就是因为我们要返回的是二维数组,所以必须要记录下结点是哪一层的.有两种方法可以使用:

  1. 一种是用两个队列,第一个队列先入第一层的结点,然后出第一个队列结点时将下一层结点存入第二个队列中,出第二个队列时再把下一层结点存入第一个队列中,边出边将数据存入相应层的vector里,直到两个队列中的结点出完代表二叉树层序遍历结束.
  2. 另一种是使用一个队列,然后使用一个levelSize变量来记录下上一层结点出的时候入了多少个,下一层就循环多少次将数据放入vector里,直到队列出空,代表二叉树遍历结束.

解题代码:

class Solution 
{
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        //因为要返回的是二维数组,所以必须双队列或者用一个变量控制levelSize
        //我们就是一层一层入,一层一层出,一层入完统计有多少个,出下层就出多少个
        queue<TreeNode*> q;
        vector<vector<int>> vv;
        int levelSize=0;

        if(root)
        {
            q.push(root);
            levelSize=1;
        }
        while(!q.empty())//while循环一次就是一层
        {
            vector<int> v;
            for(int i=0;i<levelSize;i++)
            {
                TreeNode*front=q.front();
                q.pop();
                v.push_back(front->val);
                if(front->left!=nullptr)
                {
                    q.push(front->left);
                }
                if(front->right!=nullptr)
                {
                    q.push(front->right);
                }
            }
            vv.push_back(v);
            levelSize=q.size();
        }
        return vv;
    }
};

提交运行:


三.二叉树的层序遍历 II

题目链接:

107. 二叉树的层序遍历 IIicon-default.png?t=O83Ahttps://leetcode.cn/problems/binary-tree-level-order-traversal-ii/


题目描述:

        给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)


题目详情:


解题思路:

        需要倒着层序遍历二叉树,我们可以先正着遍历,然后再把存放数据的二维数组逐层逆置一下就可以了,正着层序遍历的思路和代码和上题一模一样这里就不赘述了.

解题代码:

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) 
    {
        //先正着层序遍历,后面再逆置一下就行
        //因为要返回的是二维数组,所以必须双队列或者用一个变量控制levelSize
        //我们就是一层一层入,一层一层出,一层入完统计有多少个,出下层就出多少个
        queue<TreeNode*> q;
        vector<vector<int>> vv;
        int levelSize=0;

        if(root)
        {
            q.push(root);
            levelSize=1;
        }
        while(!q.empty())//while循环一次就是一层
        {
            vector<int> v;
            for(int i=0;i<levelSize;i++)
            {
                TreeNode*front=q.front();
                q.pop();
                v.push_back(front->val);
                if(front->left!=nullptr)
                {
                    q.push(front->left);
                }
                if(front->right!=nullptr)
                {
                    q.push(front->right);
                }
            }
            vv.push_back(v);
            levelSize=q.size();
        }

        //要倒着的层序遍历,那我们先正着存,再逆置一下数组就行
        vv.
        vector<vector<int>> vvr;
        for(int i=vv.size()-1;i>=0;i--)
        {
            vvr.push_back(vv[i]);
        }
        return vvr;
    }
};

提交运行:


四.二叉树的最近公共祖先

题目链接:

236. 二叉树的最近公共祖先icon-default.png?t=O83Ahttps://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/


题目描述:

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

        百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”


题目详情:


解题思路:

方法一:暴力查找

        借用搜索二叉树的查找思路,重点是向下查找时,找到它们最开始"分叉"的那个结点,就是最近祖先结点,图示如下:           因此我们只需要递归找到从这个结点开始两个结点一个位于它左子树一个位于它右子树的那个结点,就是最近共同祖先,这种思路简单,但是时间复杂度较高,在O(nlogn)~O(n^2)之间.

方法二:栈存路径

        方法二的思路是我在查找p,q结点的时候顺带用两个栈把它们的路径存下来,然后找到栈的最顶上的相等结点即可,该思路时间复杂度较低,为O(n),思路图示如下:


解题代码:

方法一:

class Solution 
{
public:
    bool Find(TreeNode* root, TreeNode* x)
    {
        if(root==nullptr)
        {
            return false;
        }
        return root==x || Find(root->left,x)||Find(root->right,x);
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root == nullptr)   //这种是找不到的情况,可以不写,因为题干说两个结点一定存在
        {
            return nullptr;
        }
        if(root == p || root == q)  //如果p/q就是root了,那其公共祖先一定是它本身
        {
            return root;
        }

        //开始确定p,q对于root的位置
        bool pInLeft,pInRight,qInLeft,qInRight;
        pInLeft=Find(root->left,p);   //pInLeft记录p在root的左子树存在情况
        pInRight=!pInLeft;    //pInright记录p在root的右子树存在情况

        qInLeft=Find(root->left,q);    //qInLeft记录q在root的左子树存在情况
        qInRight=!qInLeft;      //qInright记录q在root的右子树存在情况

        if(pInLeft && qInLeft)  //如果p,q都在root的左子树,那向左继续找
        {
            return lowestCommonAncestor(root->left,p,q);
        }
        else if(pInRight && qInRight)  //如果p,q都在root的右子树,那向右继续找
        {
            return lowestCommonAncestor(root->right,p,q);
        }
        else        //如果p,q一个在root的左子树,一个在root的右子树,那root就是分叉点,就是最近共同祖先
        {
            return root;
        }
    }
};

提交运行:

方法二:

class Solution 
{
public:
    bool FindPath(TreeNode* root,TreeNode* x, stack<TreeNode*>& path)
    {
        if(root == nullptr)
        {
            return false;
        }
        path.push(root);

        if(root==x)
            return true;
        if(FindPath(root->left,x,path))
            return true;
        if(FindPath(root->right,x,path))
            return true;
            
        path.pop();
        return false;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        stack<TreeNode*> pPath,qPath;
        FindPath(root,p,pPath);
        FindPath(root,q,qPath);

        while(pPath.size()>qPath.size())
        {
            pPath.pop();
        }
        while(pPath.size()<qPath.size())
        {
            qPath.pop();
        }
        while(pPath.top()!=qPath.top())
        {
            pPath.pop();
            qPath.pop();
        }
        return pPath.top();
    }
};

提交运行:


五.二叉搜索树与双向链表

题目链接:

JZ36 二叉搜索树与双向链表icon-default.png?t=O83Ahttps://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking


题目描述:

        输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示

        数据范围:输入二叉树的节点数 0≤n≤10000≤n≤1000,二叉树中每个节点的值                         0≤val≤10000≤val≤1000
        要求:空间复杂度O(1)O(1)(即在原树上操作),时间复杂度 O(n)O(n)

注意:

  1. 要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
  2. 返回链表中的第一个节点的指针
  3. 函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
  4. 你不用输出双向链表,程序会根据你的返回值自动打印输出

题目详情:


解题思路:

        使用中序递归遍历的逻辑函数,函数包含两个参数,一个表示当前结点,一个表示上一层递归的结点prev。因为搜索二叉树中序遍历的结点顺序就是有序的,因此只要在遍历时顺便将这些结点前后链接起来即可.具体链接时,因为我们传给函数的参数是当前结点和上一结点,所以我们链接时,就将当前结点的左指针连接上上一结点,然后将上一结点的右指针连接上当前结点即可,更多细节见解题代码注释.

解题代码:

class Solution 
{
public:
	//中序遍历
	void InOrder(TreeNode* cur,TreeNode*& prev)//传引用就不怕改形参不影响实参了
	{
		if (cur == nullptr)
			return;

		//中序:左
		InOrder(cur->left,prev);

		//链接左指针使其连接到上一个递归的结点
		cur->left=prev;
		//链接前一个的右指针使其指向我自己
		if(prev)
			prev->right=cur;
		prev=cur;

		//中序:右
		InOrder(cur->right,prev);
	}
    TreeNode* Convert(TreeNode* pRootOfTree) 
	{
		TreeNode* prev = nullptr;
        InOrder(pRootOfTree,prev);

		//找最左结点,一直往左走就行,但小心一开始就为空的情况
		TreeNode* cur=pRootOfTree;
		while(cur && cur->left)
		{
			cur=cur->left;
		}
		return cur;
    }
};

提交运行:


六.从前序与中序遍历序列构造二叉树

题目链接:

105. 从前序与中序遍历序列构造二叉树icon-default.png?t=O83Ahttps://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/


题目描述:

        给定两个整数数组 preorderinorder ,其中 preorder 是二叉树的先序遍历inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。


题目详情:


解题思路:

        将前序结点数组按照从前向后的顺序遍历, 将每一个结点都看作根,然后去中序根据这个根来划分左右子树。中序数组中,左子树一定在根的左边,右子树一定在根的右边, 到下一个结点时,就更新下一个结点的子树范围。

        如果这个范围不存在,那表明这个树没有子树,直接链接nullptr即可。

        图示如下:


解题代码:

class Solution 
{
public:
    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& prei, int inbegin, int inend) 
    {
        if(inbegin > inend)
            return nullptr;

        TreeNode* root = new TreeNode(preorder[prei]);
        int rooti = inbegin;
        while(rooti <= inend)
        {
            if(preorder[prei] == inorder[rooti])
                break;
            ++rooti;
        }
        //根据中序将数组分为三段
        //      左子树          根          右子树
        //[inbegin,rooti-1]  [rooti]  [rooti+1,inend]

        ++prei;
        root->left=_buildTree(preorder,inorder,prei,inbegin,rooti-1);
        root->right=_buildTree(preorder,inorder,prei,rooti+1,inend);

        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        int prei=0;
        return _buildTree(preorder,inorder,prei,0,inorder.size()-1);
    }
};

提交运行:


七.从中序与后序遍历序列构造二叉树

题目链接:

106. 从中序与后序遍历序列构造二叉树


题目描述:

        给定两个整数数组 inorderpostorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。


题目详情:


解题思路:

        本题与上一题思路相似,只是后序数组要从后向前遍历构造二叉树,则后序数组向前访问到的结点的顺序是先根再右再左,只有这一点需要特别注意,其余和上一题没有什么区别.图示如下:

解题代码:

class Solution 
{
public:
    TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder, int& prei, int inbegin, int inend) 
    {
        if(inbegin > inend)
            return nullptr;

        TreeNode* root = new TreeNode(postorder[prei]);
        int rooti = inbegin;
        while(rooti <= inend)
        {
            if(postorder[prei] == inorder[rooti])
                break;
            ++rooti;
        }
        //根据中序将数组分为三段
        //      左子树          根          右子树
        //[inbegin,rooti-1]  [rooti]  [rooti+1,inend]

        --prei;

        //后序从后向前遍历时是先根再右再左!
        root->right=_buildTree(inorder,postorder,prei,rooti+1,inend);
        root->left=_buildTree(inorder,postorder,prei,inbegin,rooti-1);
        
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) 
    {
        int prei=inorder.size()-1;
        return _buildTree(inorder,postorder,prei,0,inorder.size()-1);
    }
};

提交运行:


八.二叉树的前序遍历(迭代算法)

题目链接:

144. 二叉树的前序遍历icon-default.png?t=O83Ahttps://leetcode.cn/problems/binary-tree-preorder-traversal/


题目描述:

        给你二叉树的根节点 root ,返回它节点值的 前序 遍历。


题目详情:


解题思路:

        本题的迭代算法即不使用递归来完成树的前序遍历,我们还是借助栈来完成,具体思路是,先访问左路结点,并将其存入vector,入栈,当左路走到底时,我们先将该根节点pop出栈, 再访问栈顶结点的右路。

        当我们来到右路时,把右路再当成一个新的根节点,同样先访问左路,并将其存入vector,入栈,当左路走到底时,我们先将该根节点pop出栈, 再访问栈顶结点的右路,就这样不断循环, 直到栈中所有元素pop完,代表这颗树已经全部按照先序存入vector中了。

        思路图示如下:


解题代码:

class Solution 
{
public:
    vector<int> preorderTraversal(TreeNode* root)
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        
        while(cur || !st.empty())
        {

            //访问左路结点,左路结点入栈,后续依次访问左路节点的右子树
            while(cur)
            {
                v.push_back(cur->val);
                st.push(cur);
                cur=cur->left;
            }

            //依次访问左路节点的右子树
            TreeNode* top = st.top();
            st.pop();
            
            cur = top->right;
        }
        return v;
    }
};

提交运行:


九.二叉树的中序遍历(迭代算法)

题目链接:

94. 二叉树的中序遍历icon-default.png?t=O83Ahttps://leetcode.cn/problems/binary-tree-inorder-traversal/


题目描述:

        给定一个二叉树的根节点 root ,返回 它的 中序 遍历


题目详情:


解题思路:

        中序和先序的区别就是,先序是访问左子树前就将数据push进vector了,而中序遍历时我们是先将左子树访问完,再开始入vector.同样是借助栈来完成,区别仅在于向vector里push的时机.

解题代码:

class Solution 
{
public:
    vector<int> inorderTraversal(TreeNode* root) 
    {
       stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        
        while(cur || !st.empty())
        {

            //访问左路结点,左路结点入栈,后续依次访问左路节点的右子树
            while(cur)
            {
                st.push(cur);
                cur=cur->left;
            }

            //依次访问左路节点和其右子树
            TreeNode* top = st.top();
            st.pop();

            v.push_back(top->val);
            
            cur = top->right;
        }
        return v;
    }
};

提交运行:


十.二叉树的后序遍历(迭代算法)

题目链接:

145. 二叉树的后序遍历icon-default.png?t=O83Ahttps://leetcode.cn/problems/binary-tree-postorder-traversal/


题目描述:

        给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历


题目详情:


解题思路:

        对于后序遍历而言,我们要先了解一个概念:

        因此我们后序遍历时插入vector的时机就是在上一次访问到是它的右节点时表示是最后一次访问了的时候,才将其Push进vector中,这样得到的vector就是按照后序遍历的结果了。


解题代码:

class Solution 
{
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        TreeNode* prev =nullptr;
        TreeNode* cur = root;

        vector<int> v;
       
        while(cur || !st.empty())
        {
            while(cur)
            {
                st.push(cur);
                cur=cur->left;
            }

            TreeNode* top = st.top();

            //一个结点右子树为空,或者上一个访问的结点是右子树,那么说明是最后一次经过了
            //就可以访问了
            if(top->right == nullptr || top->right == prev)
            {
                prev = top;
                v.push_back(top->val);
                st.pop();
            }
            else
            {
                cur = top->right;
            }
        }
        return v;

    }
};

提交运行:


结语

        希望通过上面的题目能使大家对二叉树的理解以及运用能够更上一层楼,欢迎大佬们留言或私信与我交流.学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!

相关文章推荐

【数据结构】什么是二叉搜索(排序)树?

【数据结构】C语言实现链式二叉树(附完整运行代码)

【C++】模拟实现priority_queue(优先级队列)

【C++】模拟实现queue

【C++】模拟实现stack

【C++】模拟实现list

【C++】模拟实现vector

【C++】模拟实现string类

【C++】构建第一个C++类:Date类

【C++】类的六大默认成员函数及其特性(万字详解)

【C++】什么是类与对象?


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/882308.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于yolov8的无人机检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的无人机检测系统是一项前沿技术&#xff0c;结合了YOLOv8深度学习模型的强大目标检测能力与无人机的灵活性。YOLOv8作为YOLO系列的最新版本&#xff0c;在检测精度和速度上均有显著提升&#xff0c;特别适用于复杂和高动态的场景。 该系统通过捕获实…

【QML 基础】QML ——描述性脚本语言,用于用户界面的编写

文章目录 1. QML 定义2. QML 1. QML 定义 &#x1f427; QML全称为Qt Meta-Object Language&#xff0c;QML是一种描述性的脚本语言&#xff0c;文件格式以.qml结尾。支持javascript形式的编程控制。QML是Qt推出的Qt Quick技术当中的一部分&#xff0c;Qt Quick是 Qt5中用户界…

C++笔记---set和map

1. 序列式容器与关联式容器 前面我们已经接触过STL中的部分容器如&#xff1a;string、vector、list、deque、array、forward_list等&#xff0c;这些容器统称为序列式容器&#xff0c;因为逻辑结构为线性序列的数据结构&#xff0c;两个位置存储的值之间一般没有紧密的关联关…

U盘格式化了怎么办?这4个工具能帮你恢复数据。

如果你思维U盘被格式化了&#xff0c;也不用太过担心&#xff0c;其实里面的数据并没有被删除&#xff0c;只是被标记为了可覆盖的状态。只要我们及时采取正确的数据恢复措施&#xff0c;就有很大的机会可以将数据找回。比如使用专业得的数据恢复软件&#xff0c;我也可以跟大家…

缓存的思考与总结

缓存的思考与总结 什么是缓存缓存命中率数据一致性旁路模式 Cache aside双写模式直写模式 write through异步写 Write Behind 旁路和双写 案例 新技术或中间的引入&#xff0c;一定是解决了亟待解决的问题或是显著提升了系统性能&#xff0c;并且这种改变所带来的增幅&#xff…

python新手的五个练习题

代码 # 1. 定义一个变量my_Number,将其设置为你的学号&#xff0c;然后输出到终端。 my_Number "20240001" # 假设你的学号是20240001 print("学号:", my_Number) # 2. 计算并输出到终端:两个数(例如3和5)的和、差、乘积和商。 num1 3 num2 5 print(&…

nodejs基于vue电子产品商城销售网站的设计与实现 _bugfu

目录 技术栈具体实现截图系统设计思路技术可行性nodejs类核心代码部分展示可行性论证研究方法解决的思路Express框架介绍源码获取/联系我 技术栈 该系统将采用B/S结构模式&#xff0c;开发软件有很多种可以用&#xff0c;本次开发用到的软件是vscode&#xff0c;用到的数据库是…

论文集搜索网站-dblp 详细使用方法

分享在dblp论文集中的两种论文搜索方式&#xff1a;关键字搜索&#xff0c;指定会议/期刊搜索。 关键字搜索 进入dblp官方网址dblp: computer science bibliography&#xff0c;直接在上方搜索栏&#xff0c;搜索关键字&#xff0c;底下会列出相关论文。 指定会议/期刊搜索 …

三菱FX5U PLC故障处理(各种出错的内容、原因及处理方法进行说明。)

对使用系统时发生的各种出错的内容、原因及处理方法进行说明。 故障排除的步骤 发生故障时&#xff0c;按以下顺序实施故障排除。 1.确认各模块是否正确安装或正确配线。 2、确认CPU模块的LED。 3.确认各智能功能模块的LED。(各模块的用户手册) 4、连接工程工具&#xff0c;启…

从数据仓库到数据中台再到数据飞轮:我了解的数据技术进化史

这里写目录标题 前言数据仓库&#xff1a;数据整合的起点数据中台&#xff1a;数据共享的桥梁数据飞轮&#xff1a;业务与数据的双向驱动结语 前言 在当今这个数据驱动的时代&#xff0c;企业发展离不开对数据的深度挖掘和高效利用。从最初的数据仓库&#xff0c;到后来的数据…

828华为云征文|华为Flexus云服务器搭建Cloudreve私人网盘

一、华为云 Flexus X 实例&#xff1a;开启高效云服务新篇&#x1f31f; 在云计算的广阔领域中&#xff0c;资源的灵活配置与卓越性能犹如璀璨星辰般闪耀。华为云 Flexus X 实例恰似一颗最为耀眼的新星&#xff0c;将云服务器技术推向了崭新的高度。 华为云 Flexus X 实例基于…

使用SpringCloud构建可伸缩的微服务架构

Spring Cloud是一个用于构建分布式系统的开源框架。它基于Spring Boot构建&#xff0c;并提供了一系列的工具和组件&#xff0c;用于简化开发分布式系统的难度。Spring Cloud可以帮助开发人员快速构建可伸缩的微服务架构。 要使用Spring Cloud构建可伸缩的微服务架构&#xff0…

对接阿里asr和Azure asr

1&#xff1a;对接阿里asr 1.1&#xff1a;pom <dependency><groupId>com.alibaba.nls</groupId><artifactId>nls-sdk-recognizer</artifactId><version>2.2.1</version> </dependency>1.2&#xff1a;生成token package c…

C++之STL—vector容器基础篇

头文件 #include <vector> //vector容器 #include <algorithm> //算法 基本用法&&概念 vector<int> v; v.push_back(10); vector<int >::iterator v.begin(); v.end(); 三种遍历方式 #include <vector> #include <algorithm>…

基于区块链的相亲交易系统源码解析

随着区块链技术的成熟与发展&#xff0c;其去中心化、不可篡改的特性逐渐被应用于各行各业。特别是在婚恋市场中&#xff0c;区块链技术的应用为相亲平台带来了新的可能性 。本文将探讨如何利用区块链技术构建一个透明、高效的相亲交易系统&#xff0c;并提供部分源码示例。 区…

大模型的实践应用30-大模型训练和推理中分布式核心技术的应用

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用30-大模型训练和推理中分布式核心技术的应用。本文深入探讨了大模型训练和推理中分布式核心技术的应用。首先介绍了项目背景,阐述了大模型发展对高效技术的需求。接着详细讲解了分布式技术的原理,包括数据并行、模型并…

数据转换器——佛朗哥Chater2

【注:本文基于《数据转换器》一书进行学习、总结编撰,适合新手小白进行学习】 目录 2.1 数据转换器类别 2.2 工作条件 2.3 转换器性能参数 2.3.1 基本特性参数 2.4 静态性能参数 2.5 动态性能参数 2.6 数字和开关性能参数 2.1 数据转换器类别 转换器类型可以被分为两…

英飞凌TC3xx -- Bootstrap Loader分析

目录 1.Bootstrap Loaders作用 2.CAN BSL详解 2.1 CAN BSL的时钟系统 2.2 CAN BSL流程 3.小结 英飞凌TC3xx的Platform Firmware章节里&#xff0c;提供了多种启动模式&#xff1a; Internal start from Flash&#xff1a;b111Alternate Boot Mode&#xff1a;b110Generic …

杀软对抗 ---> Perfect Syscall??

好久没更了&#xff0c;今天想起来更新了&#x1f60b;&#x1f60b;&#x1f60b;&#x1f60b; 目录 1.AV && EDR 2.Perfect Syscall&#xff1f;&#xff1f; 3.Truly Perfect ??? 在开始之前先来展示一下这次的免杀效果 1.AV && EDR 360 天擎EDR …

[c++进阶(九)] STL之deque深度剖析

1.前言 本章重点 本章将会着重的介绍deque底层到底是如何实现它能够双向进出的&#xff0c;并且双向进出的消耗率还特别低&#xff0c;并且讲解deque的优缺点。 2.deque的使用 如果没有看我前面两篇文章的&#xff0c;请先看前面两篇文章再来看这篇文章&#xff0c;可以有助于…