由于树在实际中使用较多,应该掌握树的遍历基础,本文以前序遍历为例总结了遍历二叉树的两种方法还有其他一些常见问题的解答
leetcode——二叉树遍历(前序)
方法一:递归
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector
*/
vector <int> res;
//递归方法
vector<int> preorderTraversal(TreeNode* root) {
// write code here
if(!root)
return res;
res.push_back(root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
return res;
}
};
方法二:迭代
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector
*/
vector<int> preorderTraversal(TreeNode* root) {
// write code here
vector<int>res;
if(root==nullptr)
return res;
stack<TreeNode*> stc;
TreeNode* cur = root;
stc.push(cur);
while(!stc.empty()){
cur = stc.top();
res.push_back(cur->val);
stc.pop();
if(cur->right)
stc.push(cur->right);
if(cur->left)
stc.push(cur->left);
}
return res;
}
};
用栈遍历二叉树(先序)的步骤:
第一步:根节点入栈
第二步:当栈不为空的时候弹出栈顶元素并且访问该节点,当栈为空的时候执行第五步
第三步:弹出的栈顶元素的先右后左节点入栈(如果存在的话)
第四步:继续第二步的操作
第五步:结束
后序遍历二叉树:
先序遍历时每个子树都是先遍历左子树后遍历右子树,在后序遍历时将顺序反过来,即先根结点后右子树再左子树(栈的先进后出),最终结果反过来输出即为后序遍历
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector
*/
vector<int> postorderTraversal(TreeNode* root) {
// write code here
vector<int>res;
if(root==nullptr)
return res;
stack<TreeNode*> stc;
TreeNode* cur = root;
stc.push(cur);
while(!stc.empty()){
cur = stc.top();
res.push_back(cur->val);
stc.pop();
if(cur->left)
stc.push(cur->left);//先左
if(cur->right)
stc.push(cur->right);//后右,进入栈出栈是即为先右后左
}
/*
while(root!=NULL||!s.empty())
{
while(root!=NULL)
{
s.push(root->left);
res.push_back(root->val);
root=root->right;
}
root=s.top();
s.pop();
}
*/
reverse(res.begin(), res.end());反
return res;
}
};
其他实现方式详见博客
层次遍历二叉树
层次遍历是按照二叉树的层次遍历,即一层层遍历
做法是:利用队列数据结构,数据先进先出,根节点先进入队列,接下来将其子节点按从左到右的顺序入队,每一层的遍历都是队列队首元素出队,其子节点入队,循环往复保证每一层被先后遍历
class Solution{
public:
/**
*
* @param root TreeNode类
* @return int整型
*/
vector<int> layerTrarversal(TreeNode* root) {
// write code here
vector<int>res;
queue<TreeNode*>r;
r.push(root);
TreeNode* p=root;
while(!r.empty()){
r.pop();
res.push_back(p->val);
if(p->left)
r.push(p->left);
if(p->right)
r.push(p->right);
}
return res;
}
};
求二叉树的深度
采用递归方式
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型
*/
int maxDepth(TreeNode* root) {
// write code here
int res;
if(!root)
return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
求给定二叉树的最小深度
最小深度是指树的根结点到最近叶子结点的最短路径上结点的数量
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型
*/
int run(TreeNode* root) {
// write code here
if(!root)
return 0;
if(!root->left)
return run(root->right)+1;//如果左子树为空,返回右子树最小深度+1
if(!root->right)
return run(root->left)+1;//如果右子树为空,返回左子树最小深度+1
else
return min(run(root->left),run(root->right))+1;//如果左右子树都非空,返回较小的子树深度+1
}
};
求二叉树的宽度
采用层次遍历,遍历时记录每一层节点数,返回最大值即为宽度
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution{
public:
/**
*
* @param root TreeNode类
* @return int整型
*/
int maxWidth(TreeNode* root) {
// write code here
if(!root)
return 0;
//vector<int>res;
queue<TreeNode*>r;
int layerwidth=1;
int maxwidth=1;
r.push(root);//根结点入队
TreeNode* p=root;
while(!r.empty()){
while(layerwidth!=0){//此时上一层的结点还没有出队列完成
r.pop();
//res.push_back(p->val);
if(p->left)
r.push(p->left);
if(p->right)
r.push(p->right);
layerwidth--;//减去上一层的
}
layerwidth = r.size();
maxwidth = max(maxwidth,layerwidth);
}
return maxwidth;
}
};