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

数据结构 树2

文章目录

前言

一,二叉搜索树的高度

 二,广度优先VS深度优先

三,广度优先的代码实现

四,深度优先代码实现

五,判断是否为二叉搜索树

六,删除一个节点

七,二叉收索树的中序后续节点

总结


前言

我们上一篇学习了树的基本知识和树的分类,二叉搜索树是作为我们学习的重点内容,所以我将继续深入学习二叉搜索树


一,二叉搜索树的高度

我们来复习一下树的高度和深度

树的高度节点到子叶节点的距离
树的深度节点到根节点的距离

接下来我们就要用代码来实现树的高度的计算

#include<iostream>using namespace std;struct BstNode {BstNode* left;int data;BstNode* right;
};BstNode* Insert(BstNode* root, int x);
BstNode* GetNode(int x);
int Hight(BstNode* rtoot);int main() {BstNode* root = NULL;root = Insert(root, 6);root = Insert(root, 9);root = Insert(root, 10);root = Insert(root, 8);root = Insert(root, 4);root = Insert(root, 5);root = Insert(root, 3);int hight = Hight(root);cout << hight << endl;
}/*6/     \4       9/   \   /   \3     5 8    10
*/BstNode* Insert(BstNode* root, int x) {if (root == NULL) {root = GetNode(x);return root;}else if (root->data >= x) {root->left = Insert(root->left, x);}else if (root->data < x) {root->right = Insert(root->right, x);}return root;
}BstNode* GetNode(int x) {BstNode* newNode = new BstNode();newNode->data = x;newNode->left = NULL;newNode->right = NULL;return newNode;
}int Hight(BstNode* root) {if (root == NULL) {return -1;}int lefthight = Hight(root->left);int righthight = Hight(root->right);return max(lefthight, righthight) + 1;
}

代码所表示的树的结构图 

       6/     \4       9/   \   /   \
3     5 8    10

代码里的计算高度

int Hight(BstNode* root) {if (root == NULL) {return -1;}int lefthight = Hight(root->left);int righthight = Hight(root->right);return max(lefthight, righthight) + 1;
}

分析

我们这里如果根节点是空,高度就是-1,这个是规定的
max函数

如果没有接触过C++的,这个max是系统自己给的函数,你也可以自己写,就是我们以往写两个数字比较出最大的数字是一样的
递归

我们这里用的是递归的方法进行了计算,这里就是不断地寻找NULL的节点,我们拿4的计算为例子

左子树:

  • 左子树的根是 3
  • 3 是叶子节点,它没有左子树和右子树,所以它的左右子树的高度都为 0
  • 那么,3 的高度是 max(0, 0) + 1 = 1

右子树:

  • 右子树的根是 5
  • 5 是叶子节点,它同样没有左右子树
  • 所以,5 的高度是 max(0, 0) + 1 = 1

我们不难想出,再寻找NULL的时候,这个是每一个子树的左右子树都是要进行比较的,这个就是递归nb的地方,然后计算完了4,又会跑到右子树进行计算,然后最后把左右两个子树进行比较,这个后面的+1是给子树赋值的

 二,广度优先VS深度优先

树不再像我们之前所学的链表,栈,队列这种顺序结构了,它是一个非线性结构,所以树是有属于自己的遍历方法的

在访问树的节点过程中,这个是有先后顺序的,按照某个顺序进行访问,且每个节点只可以访问一次,对于这个遍历,我们有两种方法:1,深度优先    2,广度优先    3,图搜索技术
这个图搜索技术,我们还没有学完图,所以我们值考虑前两个方法

1,广度优先思想

我们会逐层访问

1,我们访问第一层,记录9
2,我们访问第二层,记录7,15
3,我们访问第三层,记录4,6,12,16
4,我们访问第四层,记录3,5,14
5,我们访问第五层,记录10
总的次序:9,7,15,4,6,12,16,3,5,14,10

先访问同一层次的节点,当访问完这个层次的节点,再到下一深度的层次继续访问

2,深度优先思想

对于这个我们有三种情况

前序<root><left><right>
中序<left><root><right>
后序<left><right><root>

第一个为先访问根,再访问左子树,再访问右子树 
顺序:9,7,4,3,5,6,15,12,14,10,16
第二个为先访问左子树,再访问根,再访问右子树 
顺序:7,4,3,5,6,9,15,12,14,10,16
第三个为先访问右子树,再访问左子树,再访问根 
顺序:7,4,3,5,6,15,12,14,10,16,9

就是把子树访问顺序

三,广度优先的代码实现

我们这种逐层的访问不就是很像队列么,先把根放入队列,然后放入孩子,然后把根弹出,再放入孩子的孩子,再把孩子弹出……

接下来我们来实现这个代码 

实际我们运行代码,代码会帮我们优化为这样

         9/   \7     15/ \    /  \4   8  12   16/ \     / \3   5   10  14

代码实现

#include<iostream>
#include<queue>using namespace std;struct BstNode {BstNode* left;int data;BstNode* right;
};BstNode* Insert(BstNode* root, int x);
BstNode* GetNode(int x);
void leveread(BstNode* root);int main() {BstNode* root = NULL;root = Insert(root, 9);  // 根节点root = Insert(root, 7);  // 左子树root = Insert(root, 15); // 右子树root = Insert(root, 4);  // 7 的左子树root = Insert(root, 8);  // 7 的右子树root = Insert(root, 12); // 15 的左子树root = Insert(root, 16); // 15 的右子树root = Insert(root, 3);  // 4 的左子树root = Insert(root, 5);  // 4 的右子树root = Insert(root, 10); // 12 的左子树root = Insert(root, 14); // 12 的右子树leveread(root);
}BstNode* Insert(BstNode* root, int x) {if (root == NULL) {root = GetNode(x);return root;}else if (root->data > x) {root->left = Insert(root->left, x);}else if (root->data < x) {root->right = Insert(root->right, x);}return root;
}BstNode* GetNode(int x) {BstNode* newNode = new BstNode();newNode->data = x;newNode->left = NULL;newNode->right = NULL;return newNode;
}void leveread(BstNode* root) {if (root == NULL)return;queue<BstNode*>Q;Q.push(root);while (!Q.empty()){BstNode* current = Q.front();cout << current->data << " ";if (current->left!=NULL) {Q.push(current->left);}if (current -> right != NULL) {Q.push(current->right);}Q.pop();}
}

我们来看这个广度搜索的代码,最后面的函数就是把所有的元素放入到队列里面,然后再进行读取弹出,我们利用队列的顺序,一一的把这个孩子的孩子都放入到队列里面

时间为O(n)

四,深度优先代码实现

前序

         9/   \7     15/ \    /  \4   8  12   16/ \     / \3   5   10  14

代码实现

#include<iostream>
#include<queue>using namespace std;struct BstNode {BstNode* left;int data;BstNode* right;
};BstNode* Insert(BstNode* root, int x);
BstNode* GetNode(int x);
void preread(BstNode* root);int main() {BstNode* root = NULL;root = Insert(root, 9);  // 根节点root = Insert(root, 7);  // 左子树root = Insert(root, 15); // 右子树root = Insert(root, 4);  // 7 的左子树root = Insert(root, 8);  // 7 的右子树root = Insert(root, 12); // 15 的左子树root = Insert(root, 16); // 15 的右子树root = Insert(root, 3);  // 4 的左子树root = Insert(root, 5);  // 4 的右子树root = Insert(root, 10); // 12 的左子树root = Insert(root, 14); // 12 的右子树preread(root);
}BstNode* Insert(BstNode* root, int x) {if (root == NULL) {root = GetNode(x);return root;}else if (root->data > x) {root->left = Insert(root->left, x);}else if (root->data < x) {root->right = Insert(root->right, x);}return root;
}BstNode* GetNode(int x) {BstNode* newNode = new BstNode();newNode->data = x;newNode->left = NULL;newNode->right = NULL;return newNode;
}void preread(BstNode* root) {if (root == NULL) {return;}cout << root->data << " ";preread(root->left);preread(root->right);
}

分析

这个就是把这个cout放到递归上面,为什么呢?如果不知道证明你基础太差了,回炉重造吧,然后进入递归,我们会把左边的全部都找完,因为只要有left为NULL则会返回去找左子树的右子树的值,然后进入的根的左子树的时候,就会跳到根的右子树进行查找,先进去右子树的左子树,然后再进入到右子树的右子树

中序跟后序跟这个前序差不多,这里放了代码,读者可以自行思考

中序

void Inread(BstNode* root) {if (root == NULL) {return;}Inread(root->left);cout << root->data << " ";Inread(root->right);
}

后序

void proread(BstNode* root) {if (root == NULL) {return;}proread(root->left);proread(root->right);cout << root->data << " ";
}

时间为O(n) 

五,判断是否为二叉搜索树

 下面这个代码的时间复杂度为O(n)

​
bool Isreallytree(BstNode* root,int minvalue,int maxvalue) {if (root == NULL)return true;if (root->data > minvalue&& root->data < maxvalue&& Isreallytree(root->left, minvalue, root->data)&& Isreallytree(root->right, root->data, maxvalue))return true;elsereturn false;
}​

 分析
我们再if里面进行不断地判断

逻辑梳理

每次我进行递归地时候,先进行左子树的判断,然后对比这个左子树的最大值和最小值,这个最大值每次是需要不断地改进地,就是这个节点,然后当我们地左子树地左边全部判断完了之后,就会执行right语句,也就是去判断这个树地右边进行判断,然后再到根的右子树进行判断,最后决定是返回true还是false

六,删除一个节点

这个东西就比较复杂,因为我们删除之后还要恢复树的平衡

我们把删除的情况分为:1,删除子叶节点    2,删除有两个孩子的节点   3,删除有一个孩子的节点

1,删除子叶节点

我们可以看到,我们可以直接删除即可

直接删除

2,删除含有一个孩子的节点

 我们不难看出,当我们删除一个节点的时候,我们直接把这个节点删除,然后把这个节点跟上就好了,十分的简单,如果你怕有风险,可以试试3或者13,我们试一下,你会发现这都是没有问题的

先连接当前节点的下一个节点,然后再把这个节点删除

3,删除有两个孩子的节点

我们可以看到这个有两种方法

方法一:
就是把15这个节点删除,然后在左子树寻找最大值放到删除的节点
方法二:
就是把15这个节点删除,然后再右子树寻找最小值放到删除的节点

在左子树寻找最大值,在右子树寻找最大值

接下来我们就用代码来实现

BstNode* remove(BstNode* root, int data) {if (root == NULL) {return root;}else if (data < root->data) {root->left = remove(root->left, data);}else if (data < root->data) {root->right = remove(root->right, data);}else {//NO childrenif (root->left == NULL && root == NULL) {delete root;root = NULL;return root;}//One childrenelse if (root->left == NULL) {BstNode* temp = root;root = root->right;delete temp;return root;}else if (root->right == NULL) {BstNode* temp = root;root = root->left;delete temp;return root;}//two childrenelse {BstNode* temp = MAX(root->left);root->data = temp->data;root->left = remove(root->left, temp->data);}}
}BstNode* MAX(BstNode* root) {if (root == NULL) {cout << "未找到" << endl;return NULL;}BstNode* current = root;while (current -> right != NULL) {current = current->right;}return current;
}

 这个MAX就不用多说了,这个就是不断地到树的最右边进行查找,我们来看看这个删除的代码

第一部分

if (root == NULL) {return root;
}
else if (data < root->data) {root->left = remove(root->left, data);
}
else if (data < root->data) {root->right = remove(root->right, data);
}

这个是我们进行查找到这个值,直到我们找到那个值跳到else语句里面,这个为什么前面要有一个root->left/right进行接收呢?这个就是我们上一篇文章讨论的问题,我们需要不断地接受新的子树,不可以还是为原来地子树

第二部分

//NO children
if (root->left == NULL && root == NULL) {delete root;root = NULL;return root;
}

这个是我直接删除叶子节点

第三部分

//One children
else if (root->left == NULL) {BstNode* temp = root;root = root->right;delete temp;return root;
}
else if (root->right == NULL) {BstNode* temp = root;root = root->left;delete temp;return root;
}

 这个是我们需要进行左右子树的删除我们root节点,这个节点我们用一个指针指着,然后把这个root节点改掉,改成指向root->right,然后返回这个root删除temp,左右子树都是一样的

第四部分

//two children
else {BstNode* temp = MAX(root->left);root->data = temp->data;root->left = remove(root->left, temp->data);
}

这个就是我们把这个最大值找打,然后赋予给这个删除的地方,接下来我们就要找到这个节点并且删除,当我们找到之后,我们就又可以判断这个节点是哪一种,如果为两个孩子还要进行递归,如果为其他两种情况的话就是结束了

这个就是把两个孩子变成一个孩子或者没有孩子的情况 

七,二叉收索树的中序后续节点

这个就是让你去判断你要使用中序的方法读取的那个节点的后面那个节点是多少,这个读者可以自行思考,后续也会更新这个代码的实现方法,这个就是让你用中序方法,假设为7,让你判断7后面那个几点为多少


总结

1,二叉搜索树的高度的计算
就是利用递归找到树的最低端头,先进行左子树的进行判断,然后在进行右子树的判断

2,广度优先VS深度优先
这两个就是,广度优先就是利用队列的方法把对应的推入到队列里面,然后再进行cout,然后利用pop弹出

3,判断是否为二叉搜索树
这个就是利用二叉树的性质,找到最大值和最小值,然后进行判断,运用递归,注意判断每个子树的时候要修改最值

4,删除节点
这个就是有三个方法,无孩子,1个孩子,2个孩子,2个孩子就是寻找最值然后再降为1个孩子或者没有孩子的情况

相关文章:

数据结构 树2

文章目录 前言 一&#xff0c;二叉搜索树的高度 二&#xff0c;广度优先VS深度优先 三&#xff0c;广度优先的代码实现 四&#xff0c;深度优先代码实现 五&#xff0c;判断是否为二叉搜索树 六&#xff0c;删除一个节点 七&#xff0c;二叉收索树的中序后续节点 总结 …...

NeetCode刷题第19天(2025.1.31)

文章目录 099 Maximum Product Subarray 最大乘积子数组100 Word Break 断字101 Longest Increasing Subsequence 最长递增的子序列102 Maximum Product Subarray 最大乘积子数组103 Partition Equal Subset Sum 分区等于子集和104 Unique Paths 唯一路径105 Longest Common Su…...

Google Chrome-便携增强版[解压即用]

Google Chrome-便携增强版 链接&#xff1a;https://pan.xunlei.com/s/VOI0OyrhUx3biEbFgJyLl-Z8A1?pwdf5qa# a 特点描述 √ 无升级、便携式、绿色免安装&#xff0c;即可以覆盖更新又能解压使用&#xff01; √ 此增强版&#xff0c;支持右键解压使用 √ 加入Chrome增强…...

[EAI-027] RDT-1B,目前最大的用于机器人双臂操作的机器人基础模型

Paper Card 论文标题&#xff1a;RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation 论文作者&#xff1a;Songming Liu, Lingxuan Wu, Bangguo Li, Hengkai Tan, Huayu Chen, Zhengyi Wang, Ke Xu, Hang Su, Jun Zhu 论文链接&#xff1a;https://arxiv.org/ab…...

什么是Rust?它有什么特点?为什么要学习Rust?

什么是Rust&#xff1f;它有什么特点&#xff1f;为什么要学习Rust&#xff1f; 如果你是一名编程初学者&#xff0c;或者已经有一些编程经验但对Rust感兴趣&#xff0c;那么这篇文章就是为你准备的&#xff01;我们将用简单易懂的语言&#xff0c;带你了解Rust是什么、它有什…...

[EAI-028] Diffusion-VLA,能够进行多模态推理和机器人动作预测的VLA模型

Paper Card 论文标题&#xff1a;Diffusion-VLA: Scaling Robot Foundation Models via Unified Diffusion and Autoregression 论文作者&#xff1a;Junjie Wen, Minjie Zhu, Yichen Zhu, Zhibin Tang, Jinming Li, Zhongyi Zhou, Chengmeng Li, Xiaoyu Liu, Yaxin Peng, Chao…...

AIP-134 标准方法:Update

编号134原文链接AIP-134: Standard methods: Update状态批准创建日期2019-01-24更新日期2022-06-02 REST API通常向资源URI&#xff08;如 /v1/publishers/{publisher}/books/{book} &#xff09;发出 PATCH 或 PUT 请求&#xff0c;更新资源。 面向资源设计&#xff08;AIP-…...

计算机网络一点事(24)

TCP可靠传输&#xff0c;流量控制 可靠传输&#xff1a;每字节对应一个序号 累计确认&#xff1a;收到ack则正确接收 返回ack推迟确认&#xff08;不超过0.5s&#xff09; 两种ack&#xff1a;专门确认&#xff08;只有首部无数据&#xff09; 捎带确认&#xff08;带数据…...

DIFY源码解析

偶然发现Github上某位大佬开源的DIFY源码注释和解析&#xff0c;目前还处于陆续不断更新地更新过程中&#xff0c;为大佬的专业和开源贡献精神点赞。先收藏链接&#xff0c;后续慢慢学习。 相关链接如下&#xff1a; DIFY源码解析...

Kafka SSL(TLS)安全协议

文章目录 Kafka SSL&#xff08;TLS&#xff09;安全协议1. Kafka SSL 的作用1.1 数据加密1.2 身份认证1.3 数据完整性1.4 防止中间人攻击1.5 确保安全的分布式环境1.6 防止拒绝服务&#xff08;DoS&#xff09;攻击 2. Kafka SSL 配置步骤&#xff08;1&#xff09;创建 SSL 证…...

hexo部署到github page时,hexo d后page里面绑定的个人域名消失的问题

Hexo 部署博客到 GitHub page 后&#xff0c;可以在 setting 中的 page 中绑定自己的域名&#xff0c;但是我发现更新博客后绑定的域名消失&#xff0c;恢复原始的 githubio 的域名。 后面搜索发现需要在 repo 里面添加 CNAME 文件&#xff0c;内容为 page 里面绑定的域名&…...

【Block总结】MAB,多尺度注意力块|即插即用

文章目录 一、论文信息二、创新点三、方法MAB模块解读1、MAB模块概述2、MAB模块组成3、MAB模块的优势 四、效果五、实验结果六、总结代码 一、论文信息 标题: Multi-scale Attention Network for Single Image Super-Resolution作者: Yan Wang, Yusen Li, Gang Wang, Xiaoguan…...

移动互联网用户行为习惯哪些变化,对小程序的发展有哪些积极影响

一、碎片化时间利用增加 随着生活节奏的加快&#xff0c;移动互联网用户的碎片化时间越来越多。在等公交、排队、乘坐地铁等间隙&#xff0c;用户更倾向于使用便捷、快速启动的应用来满足即时需求。小程序正好满足了这一需求&#xff0c;无需下载安装&#xff0c;随时可用&…...

使用UpdateCursor删除行

UpdateCursor除了可以编辑表或要素类的行外,还可以删除行.但要记住,在编辑会话外删除行时,更改是永久性的. 操作方法: 1.打开IDLE,新建一个脚本 2.导入arcpy和os模块 import arcpy import os 3.设置工作空间 arcpy.env.workspace "<>" 4.在with语句中新…...

使用 Tauri 2 + Next.js 开发跨平台桌面应用实践:Singbox GUI 实践

Singbox GUI 实践 最近用 Tauri Next.js 做了个项目 - Singbox GUI&#xff0c;是个给 sing-box 用的图形界面工具。支持 Windows、Linux 和 macOS。作为第一次接触这两个框架的新手&#xff0c;感觉收获还蛮多的&#xff0c;今天来分享下开发过程中的一些经验~ 为啥要做这个…...

1.4 Go 数组

一、数组 1、简介 数组是切片的基础 数组是一个固定长度、由相同类型元素组成的集合。在 Go 语言中&#xff0c;数组的长度是类型的一部分&#xff0c;因此 [5]int 和 [10]int 是两种不同的类型。数组的大小在声明时确定&#xff0c;且不可更改。 简单来说&#xff0c;数组…...

攻防世界_simple_php

同类型题&#xff08;更难版->&#xff09;攻防世界_Web(easyphp)&#xff08;php代码审计/json格式/php弱类型匹配&#xff09; php代码审计 show_source(__FILE__)&#xff1a;show_source() 函数用于显示指定文件的源代码&#xff0c;并进行语法高亮显示。__FILE__ 是魔…...

如何使用C#的using语句释放资源?什么是IDisposable接口?与垃圾回收有什么关系?

在 C# 中,using语句用于自动释放实现了IDisposable接口的对象所占用的非托管资源,如文件句柄、数据库连接、图形句柄等。其使用方式如下: 基础用法 声明并初始化资源对象:在using关键字后的括号内声明并初始化一个实现了IDisposable接口的对象。使用资源:在using语句块内…...

C++哈希(链地址法)(二)详解

文章目录 1.开放地址法1.1key不能取模的问题1.1.1将字符串转为整型1.1.2将日期类转为整型 2.哈希函数2.1乘法散列法&#xff08;了解&#xff09;2.2全域散列法&#xff08;了解&#xff09; 3.处理哈希冲突3.1线性探测&#xff08;挨着找&#xff09;3.2二次探测&#xff08;跳…...

Solon Cloud Gateway 开发:导引

Solon Cloud Gateway 是 Solon Cloud 体系提供的分布式网关实现&#xff08;轻量级实现&#xff09;。 分布式网关的特点&#xff08;相对于本地网关&#xff09;&#xff1a; 提供服务路由能力提供各种拦截支持 1、分布式网关推荐 建议使用专业的分布式网关产品&#xff0…...

科技快讯 | OpenAI首次向免费用户开放推理模型;特朗普与黄仁勋会面;雷军回应“10后小学生深情表白小米SU7”

不用开口&#xff1a;谷歌 AI 帮你致电商家&#xff0c;价格、预约一键搞定 谷歌在1月30日推出Search Labs中的“Ask for Me”实验性功能&#xff0c;用户可利用AI代替自己致电商家咨询价格和服务。该功能已与美汽车修理厂和美甲沙龙店合作&#xff0c;用户需加入Search Labs并…...

dmfldr实战

dmfldr实战 本文使用达梦的快速装载工具&#xff0c;对测试表进行数据导入导出。 新建测试表 create table “BENCHMARK”.“TEST_FLDR” ( “uid” INTEGER identity(1, 1) not null , “name” VARCHAR(24), “begin_date” TIMESTAMP(0), “amount” DECIMAL(6, 2), prim…...

谷歌收购HTC Vive部分软件团队:为VR/AR生态注入新活力

虚拟现实(VR)和增强现实(AR)技术的快速发展,正在重新定义我们与数字世界互动的方式。然而,尽管这些技术具有巨大的潜力,初创公司进入平台层面的竞争却异常艰难。Meta凭借其既有实力和先发优势占据了市场的主导地位,而苹果则似乎更倾向于专注于AR领域的发展。在这种背景…...

Spring AOP 入门教程:基础概念与实现

目录 第一章&#xff1a;AOP概念的引入 第二章&#xff1a;AOP相关的概念 1. AOP概述 2. AOP的优势 3. AOP的底层原理 第三章&#xff1a;Spring的AOP技术 - 配置文件方式 1. AOP相关的术语 2. AOP配置文件方式入门 3. 切入点的表达式 4. AOP的通知类型 第四章&#x…...

ElasticSearch view

基础知识类 elasticsearch和数据库之间区别&#xff1f; elasticsearch&#xff1a;面向文档&#xff0c;数据以文档的形式存储&#xff0c;即JSON格式的对象。更强调数据的搜索、索引和分析。 数据库&#xff1a;更侧重于事务处理、数据的严格结构化和完整性&#xff0c;适用于…...

一文读懂Python之random模块(31)

random模块是Python的内置标准库&#xff0c;用于生成各类随机数&#xff0c;可以用作生成网站初始登录密码和随机验证码。 一、random模块简介 random模块可以生成随机数&#xff0c;包括随机整数、浮点数、随机元素等。 二、random模块相关概念 随机数&#xff1a; 是指在…...

12.udp

12.udp **1. UDP特性****2. UDP编程框架&#xff08;C/S模式&#xff09;****3. UDP发送接收函数****4. UDP编程练习** 1. UDP特性 连接特性&#xff1a;无链接&#xff0c;通信前无需像TCP那样建立连接。可靠性&#xff1a;不可靠&#xff0c;不保证数据按序到达、不保证数据…...

Upscayl-官方开源免费图像AI增强软件

upscayl 链接&#xff1a;https://pan.xunlei.com/s/VOI0Szqe0fCwSSUSS8zRqKf7A1?pwdhefi#...

【Super Tilemap Editor使用详解】(十七):常见问题解答(FAQ)

1.问题:我更新了 Unity 版本后,资源无法正常工作或代码出现错误。 解答:当你使用不同版本的 Unity 打开项目时,应该删除项目根目录下的 Library 文件夹。此外,如果遇到窗口问题,可以将窗口布局重置为默认布局。 2.问题:我在 SceneView 中看不到工具栏,也无法在图块地图…...

SpringBoot Web开发(SpringMVC)

SpringBoot Web开发&#xff08;SpringMVC) MVC 核心组件和调用流程 Spring MVC与许多其他Web框架一样&#xff0c;是围绕前端控制器模式设计的&#xff0c;其中中央 Servlet DispatcherServlet 做整体请求处理调度&#xff01; . 除了DispatcherServletSpringMVC还会提供其他…...