思路分析:
题目要求从上而下并且为从左到右依次打印出每层的值~,这也称为二叉树的广度优先搜索(BFS),BFS通常借助队列来实现"~而且这里是需要使用二维数组返回的~
处理流程:
如果根为空那么就会直接返回了~
不为空就先把根入队的, 计数器size++;为这一层节点的个数~然后将这一层pop掉的同时将这个节点的左右入队~这里需要一个临时的节点变量来记录这个节点的数据~然后将队列头节点pop掉~头节点pop掉左右孩子继续入队~在pop的同时将数据放入数组中存起来~
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
/* 根据函数返回值定义存储结果的变量 */
vector<vector<int>> result;
/* 定义一个队列用于存储节点的数据 */
queue<TreeNode*> que;
/* 判空 */
if(root != NULL) que.push(root);
/* 开始层序遍历 */
while(!que.empty()) {
/* 计算队列的大小也即有多少个孩子 */
int size = que.size();
/* 定义一个临时vector 存储每一层 */
vector<int> vec;
/* 层序遍历 */
for(int i = 0; i < size; i++) {
/* 获取第一个节点数据 */
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
/* 将一层的数据保存 */
result.push_back(vec);
}
return result;
}
2.最近公共祖先
思路分析:
这个题是要我们找给定两个节点的最近公共祖先~直接画图分析
第一种情况为要找的两个节点分别在根节点的左边和右边~如果是这样那么这个根节点就为他们的最近公共祖先~
第二种情况就是要找的两个节点都在左边或者右边,这种情况就需要再到左树或者右树查找~
第三中情况就是最近公共节点为自己本身,这个可以在开始就判断一下~
class Solution {
public:
//查询p这个节点是否在左子树,或者右子树~
bool find(TreeNode* root, TreeNode* p)
{
if(root==nullptr)
{
return false;
}
if(root==p)
{
return true;
}
return find(root->left,p)||find(root->right,p);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root)
{
return nullptr;
}
if(root==p||root==q)
{
return root;
}
bool pInleft,pInright,qInleft,qInright;
//观察p是否在左子树。
pInleft=find(root->left,p);
//如果没有在左子树,那么就在右子树
pInright=!pInleft;
//q节点也是一样~~
qInleft=find(root->left,q);
qInright=!qInleft;
//找到这里有可能两个就在两边,直接就返回就可以~
if((pInleft&&qInright)||(qInleft&&pInright))
{
return root;
}
else if(qInleft&&pInleft)
{
return lowestCommonAncestor(root->left,p,q);
}
else if(qInright&&pInright)
{
return lowestCommonAncestor(root->right,p,q);
}
return nullptr;
}
};
思路分析:
题目要求将这个树转化为升序的双向链表~既然是升序那么这里可以考虑到中序遍历打印出来是升序~但是这里注意不能创建新的节点~
class Solution {
public:
void Inorder(TreeNode*root,TreeNode*& prev)
{
if(root==nullptr)
{
return ;
}
//中序遍历直接去找最左边的节点~为空时就开始返回~
Inorder(root->left,prev);
//将最左边节点的前驱指针指向nullptr,
root->left=prev;
//这个是防止第一次空指针时候出现问题~
//如果不是空指针那么说明已经到了中间部分的节点~
//就开始处理这个随着prev指针走向的右边或者左边
if(prev)
{
prev->right=root;
}
//因为不能创建节点就让prev递归走向原来的根节点~
prev=root;
Inorder(root->right,prev);
}
TreeNode* Convert(TreeNode* pRootOfTree) {
if(!pRootOfTree)
{
return nullptr;
}
TreeNode*prev=nullptr;
//递归去中序遍历~
Inorder(pRootOfTree,prev);
TreeNode*head=pRootOfTree;
while(head->left)
{
head=head->left;
}
return head;
}
};