【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
目录😋
任务描述
相关知识
1. 二叉树的基本概念与结构定义
2. 建立二叉树
3. 先序遍历
4. 中序遍历
5. 后序遍历
6. 层次遍历
测试说明
通关代码
测试结果
任务描述
本关任务:实现二叉树的遍历
相关知识
为了完成本关任务,你需要掌握:
- 二叉树的基本概念与结构定义
- 建立二叉树
- 先序遍历
- 中序遍历
- 后序遍历
- 层次遍历
1. 二叉树的基本概念与结构定义
二叉树是树形结构的一种特殊形式,它的每个节点最多有两个子节点,分别称为左子节点和右子节点,对应的子树就是左子树和右子树。二叉树可以为空(即没有节点),也可以由根节点、左子树和右子树组成复杂的树形结构,这种结构在很多数据处理场景中有着重要应用,例如表达式解析、文件系统目录结构模拟、搜索算法实现等。
在 C++ 中,我们通常使用结构体(
struct
)或者类(class
)来定义二叉树的节点结构,下面以结构体为例:#include <iostream> using namespace std;// 定义二叉树节点结构体 struct TreeNode {int val; // 节点存储的值,可以根据实际需求修改类型,比如存储字符、结构体等其他复杂类型TreeNode* left; // 指向左子树的指针TreeNode* right; // 指向右子树的指针TreeNode(int x) : val(x), left(NULL), right(NULL) {} // 构造函数,用于方便地初始化节点 };
在上述代码中:
val
成员变量用于存储节点所包含的数据,比如数字、字符等,这里定义为int
类型只是一个示例,实际应用中可按需调整。left
和right
是指针类型,分别用于指向该节点的左子树和右子树的根节点,如果相应子树不存在,则指针为NULL
。- 自定义的构造函数
TreeNode(int x)
接受一个参数,用于初始化节点的值,并将左、右子树指针初始化为NULL
,这样在创建节点时能更方便地进行初始化操作。
2. 建立二叉树
(1) 手动输入构建二叉树示例
下面是一种简单的通过手动输入节点值来构建二叉树的方式,采用递归的思想:#include <iostream> using namespace std;// 定义二叉树节点结构体 struct TreeNode {int val; // 节点存储的值,可以根据实际需求修改类型TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(NULL), right(NULL) {} };// 构建二叉树的函数(简单示例,这里采用手动输入的方式构建,实际可按具体需求从文件等读取数据构建) TreeNode* buildTree() {int data;cin >> data;if (data == -1) { // 用 -1 表示空节点return NULL;}TreeNode* root = new TreeNode(data);root->left = buildTree();root->right = buildTree();return root; }
代码的详细解释如下:
- 首先,程序从标准输入读取一个整数值到变量
data
中,这个值将作为当前节点要存储的值。- 接着,通过判断
data
的值来确定是否创建节点。如果data
的值为-1
,按照我们的约定,这表示当前节点为空,直接返回NULL
,意味着这个位置在二叉树中不存在实际节点。- 若
data
不为-1
,则创建一个新的TreeNode
类型的节点,使用刚才读取到的值通过构造函数进行初始化,也就是root = new TreeNode(data)
这一步,此时新节点的left
和right
指针初始化为NULL
。- 然后,递归地调用
buildTree
函数来构建当前节点的左子树,将返回的左子树的根节点指针赋值给root->left
;同样地,再次递归调用buildTree
函数来构建右子树,并将右子树的根节点指针赋值给root->right
。- 最后,返回构建好的以
root
为根节点的二叉树的根节点指针,这样就完成了整个二叉树的构建过程。例如,按照以下输入顺序(假设输入顺序是先根节点,再左子树节点,然后右子树节点,空节点用
-1
表示)来构建一棵二叉树:它将构建出这样一棵简单的二叉树:1 2 -1 -1 3 -1 -1
1/ \2 3
(2) 从数组构建二叉树示例
除了手动输入的方式,还可以从给定的数组来构建二叉树,以下是一个示例代码,假设数组按照完全二叉树的层次遍历顺序存储节点值(空节点用特定值表示,这里同样用-1
):TreeNode* buildTreeFromArray(int arr[], int index, int n) {if (index >= n || arr[index] == -1) {return NULL;}TreeNode* root = new TreeNode(arr[index]);root->left = buildTreeFromArray(arr, 2 * index + 1, n);root->left = buildTreeFromArray(arr, 2 * index + 2, n);return root; }
3. 先序遍历
先序遍历的顺序是根节点 -> 左子树 -> 右子树。可以通过递归方式很方便地实现。
递归实现先序遍历的代码如下:
// 先序遍历二叉树 void preorderTraversal(TreeNode* root) {if (root == NULL) {return;}cout << root->val << " "; // 访问根节点preorderTraversal(root->left); // 遍历左子树preorderTraversal(root->right); // 遍历右子树 }
代码逻辑详细解释如下:
- 首先进行边界判断,当传入的根节点指针
root
为NULL
时,说明已经遍历到了空子树或者二叉树本身为空,此时直接返回,不需要进行后续操作。- 如果根节点不为
NULL
,那么按照先序遍历的顺序,首先要访问根节点。这里通过cout << root->val << " ";
语句将根节点的值输出显示,这只是一种简单的访问方式示例,在实际应用中,比如要将遍历结果存储起来用于后续处理,可以把节点值存储到一个数组或者其他合适的数据结构中。- 接着,递归调用
preorderTraversal
函数去遍历左子树,这一步会以同样的逻辑去访问左子树的根节点、左子树的左子树、左子树的右子树等,直到左子树遍历完,也就是遇到叶子节点(其左子树和右子树都为NULL
)。- 最后,再递归调用
preorderTraversal
函数去遍历右子树,同样会按照先序遍历的规则去访问右子树中的各个节点,直至整个二叉树的所有节点都被访问完。例如,对于前面构建的二叉树:
1/ \2 3
先序遍历的输出结果将是:
1 2 3
。
4. 中序遍历
中序遍历的顺序是左子树 -> 根节点 -> 右子树。
其递归实现代码如下:
// 中序遍历二叉树 void inorderTraversal(TreeNode* root) {if (root == NULL) {return;}inorderTraversal(root->left); // 遍历左子树cout << root->val << " "; // 访问根节点inorderTraversal(root->right); // 遍历右子树 }
具体的代码逻辑解释如下:
- 同样先进行边界判断,若根节点指针
root
为NULL
,说明已经遍历完或者二叉树本身为空,直接返回,避免后续无效操作。- 当根节点不为
NULL
时,按照中序遍历的规则,首先要递归地遍历左子树,也就是从最底层的左子树节点开始访问,一直向上到根节点的左子节点,这个过程中会依次访问左子树中的各个节点,直到左子树遍历完毕。- 然后,访问当前的根节点,通过
cout << root->val << " ";
输出根节点的值(同样这只是简单访问示例,可按需改变操作)。- 最后,递归遍历右子树,以同样的中序遍历规则去访问右子树中的各个节点,直到整个二叉树的所有节点都被访问到。
对于上述示例二叉树:
1/ \2 3
中序遍历的输出结果是:
2 1 3
。
5. 后序遍历
后序遍历的顺序是左子树 -> 右子树 -> 根节点。
其递归实现如下:
// 后序遍历二叉树 void postorderTraversal(TreeNode* root) {if (root == NULL) {return;}postorderTraversal(root->left); // 遍历左子树postorderTraversal(root->right); // 遍历右子树cout << root->val << " "; // 访问根节点 }
详细的代码逻辑说明如下:
- 开始先判断根节点是否为
NULL
,若是则直接返回,因为已经遍历完或者二叉树为空。- 若根节点不为
NULL
,首先递归地遍历左子树,按照后序遍历的要求,从左子树的最底层叶子节点开始,依次访问左子树中的各个节点,直到左子树全部遍历完成。- 接着,递归遍历右子树,同样以左子树的遍历方式,从右子树的底层开始,逐步向上访问右子树的各个节点,直至右子树遍历完毕。
- 最后,访问当前的根节点,输出根节点的值(示例中是简单打印,实际可根据具体需求进行其他处理),这样就按照后序遍历的顺序访问了整个二叉树的所有节点。
对于前面给出的示例二叉树:
1/ \2 3
后序遍历的输出结果是:
2 3 1
。
6. 层次遍历
层次遍历是按照二叉树的层次,从根节点开始,逐层向下访问各个节点,通常借助队列(
queue
)数据结构来实现。以下是使用 C++ 标准库中的
queue
实现层次遍历的详细示例代码:#include <iostream> #include <queue> using namespace std;// 层次遍历二叉树 void levelOrderTraversal(TreeNode* root) {if (root == NULL) {return;}queue<TreeNode*> q; // 创建一个存储 TreeNode* 类型的队列,用于存放节点指针q.push(root); // 首先将根节点入队while (!q.empty()) { // 只要队列不为空,就继续循环进行遍历操作TreeNode* node = q.front(); // 获取队列头部的节点q.pop(); // 将队列头部的节点出队cout << node->val << " "; // 访问当前节点,这里同样是简单输出节点值,可按需改变操作if (node->left!= NULL) { // 判断当前节点的左子树是否存在q.push(node->left); // 如果存在,将左子树节点入队}if (node->right!= NULL) { // 判断当前节点的右子树是否存在q.push(node->right); // 如果存在,将右子树节点入队}} }
代码的详细逻辑解释如下:
- 首先进行根节点是否为空的判断,若为空则直接返回,因为空二叉树不需要进行遍历操作。
- 创建一个
queue<TreeNode*>
类型的队列,用于存储二叉树的节点指针,然后将根节点指针root
通过q.push(root)
操作入队,这是层次遍历的起始点。- 进入
while
循环,只要队列不为空,就表示还有节点需要遍历。在循环中:
- 首先通过
q.front()
获取队列头部的节点指针,并将其赋值给node
,然后通过q.pop()
将队列头部的节点出队,这一步是按照先进先出的原则处理队列中的节点。- 接着访问当前节点,示例中通过
cout << node->val << " ";
输出节点的值,实际应用中可以根据需求进行更复杂的操作,比如将节点值存储到二维数组中,按照层次结构来存储,便于后续的处理和展示等。- 之后,判断当前节点的左子树是否存在,如果左子树节点指针不为
NULL
,则通过q.push(node->left)
将左子树节点入队,以便后续按照层次顺序访问它。- 同样地,判断当前节点的右子树是否存在,若右子树节点指针不为
NULL
,则通过q.push(node->right)
将右子树节点入队。- 通过不断地循环上述操作,队列会依次存储和取出每一层的节点,从而实现按照层次顺序遍历整个二叉树的所有节点。
例如,对于以下稍微复杂一点的二叉树:
1/ \2 3/ \ / \4 5 6 7
层次遍历的输出结果将是:
1 2 3 4 5 6 7
。
测试说明
平台会对你编写的代码进行测试:
测试输入:
A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))
预期输出:
二叉树b:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))) 层次遍历序列:A B C D E F G H I J K L M N 先序遍历序列:A B D E H J K L M N C F G I 中序遍历序列:D B J H L K M N E A F C G I 后序遍历序列:D J L N M K H E B F I G C A
开始你的任务吧,祝你成功!
通关代码
// 请在Begin-End之间添加你的代码,
//实现二叉树遍历的基本运算//
//对括号表示串的二叉树进行遍历,由用户输入括号表示串//
//实现二叉树的先序遍历、中序遍历、后序遍历、层次遍历//
/********** Begin *********/
#include <bits/stdc++.h>
using namespace std;
#define MaxSize 100
typedef char ElemType;
typedef struct node {ElemType data;struct node *lchild;struct node *rchild;
} BTNode;
typedef struct {BTNode *data[MaxSize];int front, rear;
} SqQueue;
void CreateBTree(BTNode *&b, char *str) {BTNode *St[MaxSize], *p;int top = -1, k, j = 0;char ch;b = nullptr;ch = str[j];while (ch != '\0') {switch (ch) {case '(':top++;St[top] = p;k = 1;break;case ')':top--;break;case ',':k = 2;break;default:p = (BTNode *)malloc(sizeof(BTNode));p->data = ch;p->lchild = p->rchild = nullptr;if (b == nullptr)b = p;else {switch (k) {case 1:St[top]->lchild = p;break;case 2:St[top]->rchild = p;break;}}}j++;ch = str[j];}
}
void DispBTree(BTNode *b) {if (b != nullptr) {printf("%c", b->data);if (b->lchild != nullptr || b->rchild != nullptr) {printf("(");DispBTree(b->lchild);if (b->rchild != nullptr)printf(",");DispBTree(b->rchild);printf(")");}}
}
void InitQueue(SqQueue *&q) {q = (SqQueue *)malloc(sizeof(SqQueue));q->front = q->rear = 0;
}
void DestroyQueue(SqQueue *&q) { free(q); }
bool QueueEmpty(SqQueue *q) { return (q->front == q->rear); }
bool enQueue(SqQueue *&q, BTNode *e) {if ((q->rear + 1) % MaxSize == q->front) {return false;}q->rear = (q->rear + 1) % MaxSize;q->data[q->rear] = e;return true;
}
bool deQueue(SqQueue *&q, BTNode *&e) {if (q->front == q->rear)return false;q->front = (q->front + 1) % MaxSize;e = q->data[q->front];return true;
}
void LevelOrder(BTNode *b) {BTNode *p;SqQueue *qu;InitQueue(qu);enQueue(qu, b);while (!QueueEmpty(qu)) {deQueue(qu, p);printf("%c ", p->data);if (p->lchild != nullptr)enQueue(qu, p->lchild);if (p->rchild != nullptr)enQueue(qu, p->rchild);}DestroyQueue(qu);
}
void PreOrder(BTNode *b) {if (b != nullptr) {printf("%c ", b->data);PreOrder(b->lchild);PreOrder(b->rchild);}
}
void InOrder(BTNode *b) {if (b != nullptr) {InOrder(b->lchild);printf("%c ", b->data);InOrder(b->rchild);}
}
void PostOrder(BTNode *b) {if (b != nullptr) {PostOrder(b->lchild);PostOrder(b->rchild);printf("%c ", b->data);}
}
int main() {char str[100];cin >> str;BTNode *b;CreateBTree(b, str);cout << "二叉树b:";DispBTree(b);cout << endl;cout << "层次遍历序列:";LevelOrder(b);cout << endl;cout << "先序遍历序列:";PreOrder(b);cout << endl;cout << "中序遍历序列:";InOrder(b);cout << endl;cout << "后序遍历序列:";PostOrder(b);return 0;
}/********** End **********/
测试结果
相关文章:

【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
目录😋 任务描述 相关知识 1. 二叉树的基本概念与结构定义 2. 建立二叉树 3. 先序遍历 4. 中序遍历 5. 后序遍历 6. 层次遍历 测试说明 通关代码 测试结果 任务描述 本关任务:实现二叉树的遍历 相关知识 为了完成本关任务,你需要掌…...
Android Telephony | 协议测试针对 test SIM attach network 的问题解决(3GPP TS 36523-1-i60)
背景 除了运营商实网卡之外,在各种lab的协议测试中需要 follow 3GPP 协议定义(可以查询3gpp.org website 获取),那么 feature 需要支持覆盖的卡就不止运营商本身了。 本文介绍 IA APN流程,重点关注在协议/lab测试中,针对测试卡、非实网卡的的设置项,记录遇到的问题分…...

jenkins入门3 --执行一个小demo
1、新建视图 视图可以理解为是item的集合,这样可以将item分类。新建视频可以选择加入已有的item 2、新建item 1)输入任务名称、选择一个类型,常用的是第一个freestyle project 2)进行item相关配置,general 设置项目名字,描述,参数…...

STM32传感器系列:GPS定位模块
简介 我们在做一些项目的时候,可能需要使用到GPS模块,我们可以通过这个模块获得当前的位置以及时间,我这里就教大家如何去使用GPS定位模块,并且把示例代码开源到评论区下面,有需要自取即可,我我这里用到的…...

技术成长战略是什么?
文章目录 技术成长战略是什么?1. 前言2. 跟技术大牛学成长战略2.1 系统性能专家案例2.2 从开源到企业案例2.3 技术媒体大V案例2.4 案例小结 3. 学习金字塔和刻意训练4. 战略思维的诞生5. 建议 技术成长战略是什么? 1. 前言 在波波的微信技术交流群里头…...

【前端】Vue3与Element Plus结合使用的超详细教程:从入门到精通
文章目录 Moss前沿AI一、教程概述1.1 目标读者1.2 学习目标 二、为什么选择Vue3与Element Plus2.1 Vue3的优势2.2 Element Plus的优势2.3 二者结合的优势 三、环境搭建3.1 创建Vue3项目3.2 安装Element Plus3.3 引入Element Plus 四、Element Plus常用组件使用详解4.1 按钮&…...

Linux 35.6 + JetPack v5.1.4之 pytorch升级
Linux 35.6 JetPack v5.1.4之 pytorch升级 1. 源由2. 升级步骤1:获取二进制版本步骤2:安装二进制版本步骤3:获取torchvision步骤4:安装torchvision步骤5:检查安装版本 3. 使用4. 补充4.1 torchvision版本问题4.2 支持…...
旷视科技C++面试题及参考答案
在 Linux 系统下常用的命令有哪些? 在 Linux 系统中有许多常用命令。首先是文件和目录操作相关的命令。“ls” 命令用于列出目录的内容,它有很多选项,比如 “ls -l” 可以以长格式显示文件和目录的详细信息,包括文件权限、所有者、大小、修改时间等;“ls -a” 则会显示所有…...
C 语言函数指针 (Pointers to Functions, Function Pointers)
C 语言函数指针 {Pointers to Functions, Function Pointers} 1. Pointers to Functions (函数指针)2. Function Pointers (函数指针)2.1. Declaring Function Pointers2.2. Assigning Function Pointers2.3. Calling Function Pointers 3. Jump Tables (转移表)References 1. …...

66.基于SpringBoot + Vue实现的前后端分离-律师事务所案件管理系统(项目 + 论文)
项目介绍 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装律师事务所案件管理系统软件来发挥其高效地信息处理的作用…...
Docker容器中Elasticsearch内存不足问题排查与解决方案
在使用Docker运行Elasticsearch(ES)时,可能会遇到内存不足的问题,导致ES无法启动。以下是一次完整的排查和解决过程。 问题描述 在启动ES时,日志提示如下错误: # Native memory allocation (mmap) failed…...

Ubuntu 下测试 NVME SSD 的读写速度
在 Ubuntu 系统下,测试 NVME SSD 的读写速度,有好多种方法,常用的有如下几种: 1. Gnome-disks Gnome-disks(也称为“Disks”)是 GNOME 桌面环境中的磁盘管理工具,有图形界面,是测试…...
Neo4j的部署和操作
注:本博文展示部署哥操作步骤和命令,具体报告及运行截图可通过上方免费资源绑定下载 一.数据库的部署与配置 在单个节点上对进行数据库的单机部署 (1)上传neo4j-community-3.5.30-unix.tar.gz到hadoop1的/export/so…...
react axios 优化示例
使用 axios 是 React 项目中非常常见的 HTTP 请求库。为了提升 axios 在 React 中的性能、可维护性和用户体验,我们可以从 代码组织、请求优化 和 用户体验优化 多个角度进行详细的优化。 一、安装与基础配置 安装 axios npm install axios创建 Axios 实例 为了更好地管理…...

探索数字化展馆:开启科技与文化的奇幻之旅
在科技飞速发展的当下,数字展馆作为一种新兴的展示形式,正逐渐走进大众的视野。数字展馆不仅仅是传统展馆的简单“数字化升级”,更是融合了多媒体、数字化技术以及人机交互等前沿科技的创新产物。 数字展馆借助VR、AR、全息投影等高科技手段&…...

基于深度学习的视觉检测小项目(七) 开始组态界面
开始设计和组态画面。 • 关于背景和配色 在组态画面之前,先要确定好画面的风格和色系。如果有前端经验和美术功底,可以建立自己的配色体系。像我这种工科男,就只能从网络上下载一些别人做好的优秀界面,然后在photo shop中抠取色…...

AI赋能跨境电商:魔珐科技3D数字人破解出海痛点
跨境出海进入狂飙时代,AI应用正在深度渗透并重塑着跨境电商产业链的每一个环节,迎来了发展的高光时刻。生成式AI时代的大幕拉开,AI工具快速迭代,为跨境电商行业的突破与飞跃带来了无限可能性。 由于跨境电商业务自身特性鲜明&…...
【C/C++】nlohmann::json从文件读取json,并进行解析打印,实例DEMO
使用 json::parse 函数将JSON格式的字符串解析为 nlohmann::json 对象。这个函数支持多种输入源,包括字符串、文件流等。 #include <iostream> #include <nlohmann/json.hpp> #include <fstream>using json nlohmann::json;int main() {// 解析…...

安装Anaconda搭建Python环境,并使用VSCode作为IDE运行Python脚本
下面详细说明如何安装Anaconda搭建Python环境,并使用VSCode作为编辑器运行Python脚本的过程: 1. 下载Anaconda 访问Anaconda的官方网站:https://www.anaconda.com/products/distribution 3. 根据您的操作系统选择适合的版本下载。Anaconda支…...
我用AI学Android Jetpack Compose之入门篇(1)
这篇我们先来跑通第一个Android Jetpack Compose工程,现在新版本的Android Studio,新建工程选择Empty Activity默认就会开启Jetpack Compose的支持,再次声明,答案来自 通义千问Ai 文章目录 1.用Android Jetpack Compose需要安装什…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...