二叉树的最大深度
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明:叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],相关标签:树 深度优先搜索 广度优先搜索 二叉树
3
/ \
9 20
/ \
15 7
返回它的最大深度3
#pragma once
#include<algorithm>
#include<queue>
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
class Solution {
public:
int maxDepth(TreeNode* root) {
/*by myself(深度优先,递归实现)
if (root == nullptr) { //遍历到空结点返回
return 0;
}
return std::max(maxDepth(root->left), maxDepth(root->right)) + 1; //比较每个递归层root的左子树和右子数深度,返回值为 其中的最大深度再加1(因为root本身也是一层,当前递归层最大深度即 max(maxDepth(root->left), maxDepth(root->right)) + 1)
*/
//(广度优先,使用了队列)
if (root == nullptr) { //如果为空树返回0,否则在if (t->left != nullptr)判断时会非法引用
return 0;
}
std::queue<TreeNode*>que; //队列的作用是存放当前层所有的结点
int level = 0; //记录二叉树最大深度(层数)
que.push(root); //首先将第一层的root节点入队
while (!que.empty()) { //如果队列为空,表示遍历到最深一层,由于最深一层都没有子结点,所以当进入下一层查找时最深一层作为父结点会被出队
int father_nodes = que.size(); //father_nodes表示这一层结点的个数(也是下一层的父节点的个数)
while (father_nodes) { //遍历这一层父结点,查找是否存在子节点,存在就入队,每个父结点查找完毕后将其出队,因此队列里都是下一层的子结点(每次遍历队列中的上层父节点,入队其子结点后删除父结点,队列中的这层子结点将作为下一层的父结点继续遍历查找。直到遍历到最深一层,最深一层的结点没有子结点,所以遍历后没有可入队的子结点,并且删除队列里的这层父结点,因此队列最后为空)
TreeNode* t = que.front();
if (t->left != nullptr) {
que.push(t->left);
}
if (t->right != nullptr) {
que.push(t->right);
}
que.pop();
father_nodes--; //遍历查找后删除一个父结点,father_nodes--
}
level++; //内层while循环结束,表示一层遍历完毕,因此level++
}
return level; //返回最后得到的level,即最大深度
}
};
验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
输入:2/ \1 3输出: true
输入:5/ \1 4/ \3 6输出: false解释: 输入为: [5,1,4,null,null,3,6]。根节点的值为 5 ,但是其右子节点值为 4 。
相关标签:树 深度优先搜索 二叉搜索树 二叉树
例如:
#pragma
#include<iostream>
#include<stack>
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
class Solution {
public:
bool helper(TreeNode* root, long long min, long long max);
bool isValidBST(TreeNode* root) {
/* (错误理解) 只考虑到子结点和上一层父结点直间的大小关系,而没有考虑到全部(例如,不仅右子结点应大于其父节点的值,而是整个右子树的所有结点(包括其左子结点)都应该大于其父结点的值)
* if (root->left != nullptr && root->right != nullptr) {
* if (root->val <= root->left->val || root->val >= root->right->val) {
* return false;
* }
*
* if (!isValidBST(root->left)) {
* return false;
* }
* if (!isValidBST(root->right)) {
* return false;
* }
* }
* return true;
*/
/*(递归)
return helper(root, LONG_MIN, LONG_MAX);
*/
//(中序遍历,迭代,利用栈)
std::stack<TreeNode*>stk; //使用栈来模拟中序遍历的过程
long long min = LONG_MIN; //定义一个最小值(如果满足二叉搜索树再结合中序遍历特点,可知中序遍历后的所以结点是从小到大排列的。所以只要按照中序遍历对所有结点进行比较,如果满足从小到大的次序则是二叉搜索树)
while (!stk.empty() || root != nullptr) { //初始时,栈是空的,root!=nullptr(非空树);中序遍历过程中,栈不是空的,root==nullptr或者root!=nullptr(即右结点可能是空也可能不是);遍历结束时,栈是空的,root==nullptr(所有应该为||而不是&&,否则进入不了循环,中间遍历过程也可能突然退出)
while (root != nullptr) { //只要left存在就一直找left,直到nullptr
stk.push(root); //左要保留在栈中
root = root->left;
}
root = stk.top(); //当root==nullptr(即left_r->left==nulltr),弹出left_r,root=left_r
stk.pop();
if (root->val <= min) { //此时的root(left_r)即 中,将 中 与min比较,如果 中>=min,则说明不是二叉搜索树(不管前序、中序、后序遍历,所有结点都会有作为 中,比如前序遍历第一次遍历到该结点就是 中,中序遍历第二次遍历到该结点就是 中,后续遍历第三次遍历到该结点就是 中。所有所有结点都会成为中别遍历到,三种遍历只是说最终所有结点作为 中 被遍历到的顺序不同而已)
return false;
}
min = root->val; //min被设置为被遍历到的结点值,接着与下一个 中 比较
root = root->right; //找完了左,中,找右(以右作为新的子树root,继续不断找左)
}
return true; //如果完整中序遍历完,说明该树就是二叉搜索树
}
};
bool Solution::helper(TreeNode* root, long long min, long long max) { //自己设计一个递归函数,增加每个结点值范围的参数(min,max)
if (root == nullptr) { //遍历到空结点,返回true
return true;
}
if (root->val <= min || root->val >= max) { //该结点不在范围内,即不满足二叉搜索树,返回false
return false;
}
return helper(root->left, min, root->val) && helper(root->right, root->val, max); //对左右子树进行递归,只有在都返回true时才满足二叉搜索树的条件(这里对左子树root的范围为(min, root->val),对左子树root的范围为(root->val, max)。min和max在动态变化,即被覆盖,最终的目的就是要满足,对于左子树而言:左子树上的所有结点都应该小于这个左子树root,虽然存在树里面的子树,不管是外层树还是内层子树,只要该结点在其树上,既要小于外层树root,也要小于内存子树的root)
} 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。例如:
二叉树 [1,2,2,3,4,4,3] 是对称的1/ \2 2/ \ / \3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的1/ \2 2\ \3 3
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
相关标签:树 深度优先搜索 广度优先搜索 二叉树
示例:
你可以运用递归和迭代两种方法解决这个问题吗?
相关标签:树 深度优先搜索 广度优先搜索 二叉树
#pragma once
#include<deque>
#include<queue>
#include<stack>
#include<vector>
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
class Solution {
public:
bool is_hui_wen(std::deque<TreeNode*> DQ_t); //验证双端队列DQ_t中存储的结点是否构成回文(DQ_t中存储二叉树当前层的结点)
bool is_hui_wen(std::vector<TreeNode*> vec); //验证双端队列DQ_t中存储的结点是否构成回文(vec中存储二叉树当前层的结点的值)
bool compare(TreeNode* t1, TreeNode* t2); //比较对称位置t1,t2结点是否都存在,如果存在是否值相同
bool check(TreeNode* t1, TreeNode* t2); //官方代码简化版
bool isSymmetric(TreeNode* root) {
/*by myself(层序遍历,回文判断,有点暴力味)
std::deque<TreeNode*>DQ;
std::deque<TreeNode*>DQ_t;
TreeNode* t = new TreeNode(-1); //假设所有结点值都>0,在这里t代指一个空结点,起到占位作用(埋了个内存泄露的伏笔)
DQ.push_back(root);
DQ_t.push_back(root);
while (!DQ.empty()) { //中序遍历
if (!is_hui_wen(DQ_t)) { //如果当前层的结点按从左到右顺序不构成回文,则直接返回false
return false;
}
DQ_t.clear(); //清空双端队列DQ_t,即清空上一层结点,准备存入当前层结点
int level_nodes = DQ.size(); //双端队列DQ_t中存储着上一层结点,寻找当前层结点是根据上一层结点进行
while (level_nodes) { //根据上一层记录的结点,寻找下一层结点
root = DQ.front();
if (root->left != nullptr) { //以上一层结点为root,如果存在左右结点,则插入到DQ和DQ_t中(每查找完DQ中存储的当前root结点,如果存在其左右则插入,插入完删除该root,继续查找DQ中下一个root)
DQ.push_back(root->left);
DQ_t.push_back(root->left);
}
else {
DQ_t.push_back(t); //如果root不存在left或者right,对于DQ是不插入的,但是对于DQ_t需要插入一个t
}
if (root->right != nullptr) {
DQ.push_back(root->right);
DQ_t.push_back(root->right);
}
else {
DQ_t.push_back(t);
}
DQ.pop_front();
level_nodes--; //每查找完上一层一个结点,level_nodes--,当level_nodes==0,表示上一层结点查找遍历完毕
}
}
return true;
*/
/*by myself(层序遍历,回文判断,简单优化:用queue和vector代替deque)
std::queue<TreeNode*>Q;
std::vector<TreeNode*>vec;
Q.push(root);
vec.push_back(root);
while (!Q.empty()) { //中序遍历
if (!is_hui_wen(vec)) { //如果当前层的结点按从左到右顺序不构成回文,则直接返回false
return false;
}
vec.clear(); //清空vec,即清空上一层结点,准备存入当前层结点
int level_nodes = Q.size(); //队列Q中存储着上一层结点,寻找当前层结点是根据上一层结点进行
while (level_nodes) { //根据上一层记录的结点,寻找下一层结点
root = Q.front();
if (root->left != nullptr) { //以上一层结点为root,如果存在左右结点,则插入到Q和vec中(每查找完DQ中存储的当前root结点,如果存在其左右则插入,插入完删除该root,继续查找Q中下一个root)
Q.push(root->left);
vec.push_back(root->left);
}
else {
vec.push_back(nullptr); //如果root不存在left或者right,对于Q是不插入的,但是对于vec需要插入一个nullptr(nullptr起到占位作用)
}
if (root->right != nullptr) {
Q.push(root->right);
vec.push_back(root->right);
}
else {
vec.push_back(nullptr);
}
Q.pop();
level_nodes--; //每查找完上一层一个结点,level_nodes--,当level_nodes==0,表示上一层结点查找遍历完毕
}
}
return true;
*/
/*by myself(递归)
return compare(root->left, root->right);
*/
/*(递归,代码排放简明,逻辑性更强)
return check(root->left, root->right);
*/
/*by myself(迭代,栈实现)
std::stack<TreeNode*>stk;
stk.push(root);
stk.push(root);
TreeNode* t1 =root->left;
TreeNode* t2 = root->right;
while (!stk.empty()) {
if (t1 == nullptr && t2 != nullptr || t1 != nullptr && t2 == nullptr) { //1.在新的一轮开始时要判断 "t1父结点的right,t2父结点的left"作为新的root的两个结点(新一轮初始时判断)
return false;
}
while (t1 != nullptr && t2 != nullptr) { //从当前树,不断向下查找比较left和right结点,无非三种情况:(1)t1,t2都为nullptr,返回flase; (2)t1,t2只有一个为nullptr,返回false; (3)t1,t2都不为nullptr,值相对返回true,否则返回false;
if (t1->val != t2->val) { //能正常从循环中出来,说明t1==nullptr,t2==nullptr,否则都会返回false。
return false;
}
stk.push(t1);
stk.push(t2);
t1 = t1->left; //不断查找判断 左和右 结点
t2 = t2->right;
if (t1 == nullptr && t2 != nullptr || t1 != nullptr && t2 == nullptr) { //2.在向下查找比较 左和右结点 时要判断(过程中判断)
return false;
}
}
t2 = stk.top()->left; //当t1==nullptr,t2==nullptr,此应该继续查找 "t1父结点的right,t2父结点的left ",并且t1,t2各自的父结点作为root的俩颗子树,继续查找比较 左和右 结点
stk.pop(); //注:由于是栈的缘故,开始是t1、t2入栈,此时应该以t2、t1顺序接收出栈值(stk.top()即他们的父结点)
t1 = stk.top()->right;
stk.pop();
}
return true;
*/
//(迭代,队列实现)
std::queue<TreeNode*>Q;
Q.push(root->left);
Q.push(root->right);
while (!Q.empty()) { //结合广度优先遍历理解,只不过这里是同时处理俩组(左右,右左),但也是一层一层处理
TreeNode* t1 = Q.front(); //和广度优先遍历类似,当t1,t2作为父结点的时候应移除队列,并且在此时进行比较
Q.pop();
TreeNode* t2 = Q.front();
Q.pop();
if (t1 == nullptr && t2 == nullptr) {
continue;
}
if (t1 == nullptr || t2 == nullptr || t1->val != t2->val) {
return false;
}
Q.push(t1->left); //对于两个位置对称的父结点t1,t2来说:t1->left和t2->right;t1->right和t2->left是两组位置对称的子结点,将他们加入队列
Q.push(t2->right);
Q.push(t1->right);
Q.push(t2->left);
}
return true;
}
};
bool Solution::is_hui_wen(std::deque<TreeNode*> DQ_t) { //判断是否为构成回文
while (!DQ_t.empty()) {
TreeNode* first = DQ_t.front();
TreeNode* last = DQ_t.back();
if (first->val != last->val) {
return false;
}
if (DQ_t.size()>1) {
DQ_t.pop_front();
DQ_t.pop_back();
}
else {
DQ_t.pop_front();
}
}
return true;
}
bool Solution::is_hui_wen(std::vector<TreeNode*>vec) { //判断是否为构成回文
auto first = vec.begin();
auto last = vec.end()-1;
while (first < last) {
if ((*first != nullptr && *last != nullptr) && (*first)->val != (*last)->val) { //first、last是有效的结点则比较值,不等则不构成回文,返回false
return false;
}
if ((*first == nullptr && *last != nullptr) || (*first != nullptr && *last == nullptr)) { //first、last其中一个为有效结点,一个为无效结点,则肯定不构成回文,返回false
return false; //满足条件情况:first、last都为无效结点 或者 都为有效结点且值相等
}
first++;
last--;
}
return true;
}
bool Solution::compare(TreeNode* t1, TreeNode* t2) { //t1,t2两个结点是对称结点(位置对称)
if (t1 != nullptr && t2 != nullptr) { //如果是对称二叉树,最起码每个结点都有一个与之位置对称的结点
if (t1->val == t2->val) { //每个结点不仅要有位置上对称的结点,而且结点值要相等。在满足这样的条件下才有必要继续递归比较下去
if (!compare(t1->left, t2->right)) { //可知t1和t2是两个位置对称结点(从root开始推就可知,t1处于root的左,t2处于root的右),所以接下来要比较t1,t2这俩个结点的子结点也必须对称,所以t1->left对应的是t2->right,t1->right对应的是t2->left。(一个左一个右才呈对称位置)
return false; //如果compare函数返回false则直接向上一层返回false
}
if (!compare(t1->right, t2->left)) {
return false;
}
}
else { //如果对称位置上两个结点值不等,返回false
return false;
}
}
if ((t1 == nullptr && t2 != nullptr) || (t1 != nullptr && t2 == nullptr)) { //如果一个结点连对称位置上都不存在相应对称结点,肯定不满足对称二叉树,直接返回false
return false;
}
return true; //上面俩个if如果都不满足,说明t1,t2都为nullptr,说明这一递归层的对应位置都是空结点,直接返回上一层,所以返回true
}
bool Solution::check(TreeNode* t1, TreeNode* t2) { //官方代码简化版,无非三种情况: (1)t1,t2都为nullptr,返回flase; (2)t1,t2只有一个为nullptr,返回false; (3)t1,t2都不为nullptr,值相对返回true,否则返回false;
//我是按(3)(2)(1)顺序写,(3)(2)为俩个if,剩下自然是(1),放在return。官方an(1)(2)(3),先写明(1)(2)俩代码量最少的,剩下情况自然就是(3),(3)代码量最多,放在return,省去了冗余的判断,因为(1)(2)判断完,剩下肯定是(3)这种情况不用再次判断
if (t1 == nullptr && t2 == nullptr) {
return true;
}
if (t1 == nullptr || t2 == nullptr) { //根据上面判断知道,到这里说明t1,t2不可能都为nullptr,所以判断t1,t2是否只有一个为nullptr时,只需要判断t1==nullptr或t2==nullptr就行,满足就返回flase
return false;
}
return (t1->val == t2->val) && check(t1->left, t2->right) && check(t1->right, t2->left); //因为经过了(1)(2)判断这里默认就是(3)成立,即t1,t2都不为空。利用了&&的特点,先把(t1->val == t2->val)放前面,满足才会判断后来俩个函数,即继续递归,否则直接跳过后面俩个函数返回flase,正好和(3)对上。
}
二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。示例:
二叉树:[3,9,20,null,null,15,7],3/ \9 20/ \15 7返回其层序遍历结果:[[3],[9,20],[15,7]]
相关标签:树 广度优先搜索 二叉树
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:

#pragma once
#include<vector>
#include<queue>
using std::vector;
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
class Solution {
public:
vector<vector<int>>& helper(TreeNode* root, int level, vector<vector<int>>& vec);
vector<vector<int>> levelOrder(TreeNode* root) {
/*by myself(队列实现)
std::queue<TreeNode*>Q;
vector<vector<int>>vec;
int level = 0;
if (root == nullptr) { //root为空要返回,否则下面语句 if(t->left != nullptr) 非法引用
return vec;
}
Q.push(root);
while (!Q.empty()) {
int nodes_level = Q.size();
vec.resize(level + 1); //vector<vector<int>>vec;这样定义的vec没有分配空间,不能够直接vec[1]!!!。两种方法:(1)vec.resize(level + 1) (2)vec.push_back(vector <int> ())。emmm,后面这种更加C++
while (nodes_level) {
TreeNode* t = Q.front();
vec[level].push_back(t->val); //每一层对应二维数组vec的每一个元素(即一维数组),这里遍历每一层结点时,只需要将其插入其所在层对应的一维数组中
Q.pop();
if (t->left != nullptr) {
Q.push(t->left);
}
if (t->right != nullptr) {
Q.push(t->right);
}
nodes_level--;
}
level++;
}
return vec;
*/
//by myself(递归)
vector<vector<int>>vec;
return helper(root, 0, vec);
}
};
vector<vector<int>>& Solution::helper(TreeNode* root, int level, vector<vector<int>>& vec) { //因为要层序遍历,所有这把结点所在层数level作为参数传递,传递vec参数目的为了传引用,以免因递归调用而导致多次构造数组带来的浪费
if (root == nullptr) {
return vec;
}
if (level + 1 > vec.size()) { //要判断在该递归层level时,vec.size()如果小于level+1,则说明该层对应的一维数组空间还不存在,所以要对vec进行扩容
vec.resize(level + 1);
}
vec[level].push_back(root->val); //采用先序遍历,将结点插入其所在层对应的一维数组中(直接插入后面就行,不管是先序、中序、后续遍历,其本质都是从左往右遍历)
helper(root->left, level + 1, vec);
helper(root->right, level + 1, vec);
return vec;
}
将有序数组转换为二叉搜索树
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
输入:nums = [-10,-3,0,5,9]输出:[0,-3,9,-10,null,5]解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
示例 2:

输入:nums = [1,3]输出:[3,1]解释:[1,3] 和 [3,1] 都是高度平衡二叉搜索树。
提示:
1 <= nums.length <= 104-104 <= nums[i] <= 104nums 按 严格递增 顺序排列
相关标签:树 二叉搜索树 数组 分治 二叉树
#pragma once
#include<vector>
using std::vector;
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
class Solution {
public:
TreeNode* helper(const std::vector<int>& vec, int left, int right);
TreeNode* sortedArrayToBST(vector<int>& nums) {
/*(错误实例)
//泪目,想用贪心,贪错了。。 (原本思路:首先确顶root(在这里是3,即数组中间元素),如果vec.size()>3,那么再确定root->left,root->right(在这里分别为2、5,left即数组中间元素的前一个,right为数组最后一个),root->left之前的全部接在root->left结点左边,root到root->right之前的结点,全部接在root->right左边。
//这样构造出的树虽然满足搜索树,但是"不是完全的平衡二叉树(AVL)",AVL对所有节点作为root的子树时也都必须满足AVL!!!(即每个节点的左右两个子树的高度差的绝对值不超过 1)
// 输出结果 预期结果 数组vec={0,1,2,3,4,5}
int root_index = nums.size() / 2; // 3 3
TreeNode* root = new TreeNode(nums[root_index]); // / \ / \
// 2 5 1 5
TreeNode* t = root; // / / / \ /
for (int i = root_index - 1; i >= 0; i--) { // 1 4 0 2 4
TreeNode* p = new TreeNode(nums[i]); // /
t->left = p; // 0
t = p;
}
if (root_index != nums.size() - 1) {
TreeNode* p = new TreeNode(nums[nums.size() - 1]);
root->right = p;
t = p;
for (int i = nums.size() - 2; i > root_index; i--) {
TreeNode* p = new TreeNode(nums[i]);
t->left = p;
t = p;
}
}
return root;
*/
//(中序遍历,递归)
return helper(nums, 0, nums.size() - 1); //二叉搜索树的中序遍历是升序序列,题目给定的数组是按照升序排序的有序数组,因此可以确保数组是二叉搜索树的中序遍历序列。
//注:就算给定二叉搜索树的中序遍历,也不可以唯一地确定二叉搜索树,这里再子树结点为偶数数时,总是选择中间位置左边作为root,中间位置右边也可以,如果这两种可能再在每一个递归层(也就是当前层子树)交错选择,会导致多种不同结果。
}
};
TreeNode* Solution::helper(const std::vector<int>& vec, int left, int right) {
if (left > right) {
return nullptr;
}
int mid = (right + left) / 2;
TreeNode* root = new TreeNode(vec[mid]); //总选择中间位置(奇个)或者左边(偶个)作为该所在层子树的root。确定平衡二叉搜索树的根节点之后,其余的数字分别位于平衡二叉搜索树的左子树和右子树中,左子树和右子树分别也是平衡二叉搜索树,因此可以通过递归的方式创建平衡二叉搜索树。
//为什么这么建树一定能保证是「平衡」的呢? 简单脑部理解就是:这样递归也是一直二分下去,分一半结点给左边以left为根结点建立左子树,分一半给右边以right为根结点建立右子树。按递归走只是先建立左再建立右,但是每一层的左右子树在每一层都早已经二分好了,最后得到的树是平衡二叉树
root->left = helper(vec, left, mid - 1);
root->right = helper(vec, mid + 1, right);
return root;
}

京公网安备 11010502036488号