题目描述:
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:输入:root = []
输出:[]
示例 3:输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[2,1]
示例 5:
输入:root = [1,null,2]
输出:[1,2]提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析:
经典递归,没啥说的,几行代码的事。代码如下:
/**
* 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<int> res;
vector<int> inorderTraversal(TreeNode* root) {
// 节点为空,直接返回
if(root==NULL) return res;
// 遍历左子树
inorderTraversal(root->left);
// 根节点加入res
res.push_back(root->val);
// 遍历右子树
inorderTraversal(root->right);
// 返回结果res
return res;
}
};
ps:题目说还有迭代算法,将来可以试试。
迭代算法,就是不使用递归来完成二叉树的中序遍历。根本思路在于使用栈来模拟递归操作。
递归程序,是从上往下访问的,这一点是无法改变的。即使使用迭代,访问顺序也一定是从上往下,只是我们可以在从上往下访问的过程中,让上层节点先存入栈,等到按照顺序访问到他们时再出栈。
从根节点开始,一直沿着左节点遍历,遇到的节点全部存入栈,直到左节点为NULL。
开始循环:从栈顶拿出第一个元素,该元素就是中序遍历访问到的第一个节点,该节点存入res。按照中序遍历的顺序,该节点的左节点已经访问过了(为NULL),根节点也访问过了(它自身),只剩下右节点没有访问过了。所以,按照顺序,该访问根节点的右子树了(不是右节点,因为按照中序遍历的顺序,下个该访问的节点是该节点右子树中最左边那个节点)。访问右节点,右节点作为根节点,一直沿着左节点遍历,遇到的节点全部存入栈,直到左节点为NULL。开始下一轮循环。
代码如下:
/**
* 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<int> res;
stack<TreeNode* > s;
vector<int> inorderTraversal(TreeNode* root) {
// 从根节点开始的左节点全部入栈
while(root!=NULL)
{
s.push(root);
root=root->left;
}
// 栈不为空,就进行循环
while(!s.empty())
{
// 栈顶元素出栈
if(!s.empty())
{
root=s.top();
s.pop();
}
// 该元素进入res
res.push_back(root->val);
// 访问该元素的右节点
root=root->right;
// 右节点的左节点全部入栈
while(root!=NULL)
{
s.push(root);
root=root->left;
}
}
// 返回res
return res;
}
};
同时附上二叉树的前序遍历的迭代解法(不是基于leetcode写的,是一个完整的代码):
#include <iostream>
#include "vector"
#include "stack"
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
vector<int> res;
stack<TreeNode*> s;
void f(TreeNode * root);
int main()
{
// 构建一个二叉树
TreeNode *root=new TreeNode(1);
root->left=new TreeNode(2);
root->right=new TreeNode(3);
root->left->left=new TreeNode(4);
root->left->right=new TreeNode(5);
root->right->left=new TreeNode(6);
root->right->right=new TreeNode(7);
f(root);
for(int i=0;i<res.size();i++)
{
cout<<res[i]<<" ";
}
return 0;
}
void f(TreeNode * root)
{
// 存入根节点
s.push(root);
while(!s.empty())
{
// 取出栈顶节点
TreeNode *temp=s.top();
s.pop();
// 如果栈顶节点不为空
if(temp)
{
// 该节点加入res
res.push_back(temp->val);
// 该节点的左右子节点入栈
s.push(temp->right);
s.push(temp->left);
}
}
}