目录
二叉树的遍历
1 递归解法
1.1前序遍历
/**
* 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:
void preorder(TreeNode* node, vector<int> &res)
//注意参数是引用,vector<int> &res
{
if(node == nullptr) //终止条件
return;
res.push_back(node->val);
preorder(node->left,res);
preorder(node->right,res);
}
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preorder(root,res);
return res;
}
};
1.2中序遍历:
class Solution {
void inorder(TreeNode* node,vector<int> &res)
{
if(node == nullptr) return;
inorder(node->left,res); //左
res.push_back(node->val); //中
inorder(node->right,res); //右
}
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inorder(root,res);
return res;
}
};
1.3后序遍历:
class Solution {
void postorder(TreeNode* node,vector<int> &res)
{
if(node == nullptr) return;
postorder(node->left,res); //左
postorder(node->right,res); //右
res.push_back(node->val); //中
}
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
postorder(root,res);
return res;
}
};
2 迭代解法:
2.1前序遍历:
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
if(root == nullptr) return res;
stk.push(root);
while(!stk.empty())
{
root = stk.top();
stk.pop();
res.push_back(root->val); //记录栈顶节点元素的值,并弹出
if(root->right) //先加入右节点,再加入左节点,因为是后进先出,前序是中左右
stk.push(root->right);
if(root->left)
stk.push(root->left);
}
return res;
}
};
2.2中序遍历:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
//当root为空指针并且栈为空时,遍历结束
while(root!=nullptr || !stk.empty())
{
while(root !=nullptr)
{
stk.push(root); //节点不为空时,至少执行一次循环,该节点加入栈中,接下来会被弹开并记录到结果中
root=root->left; //左
} //添加该节点一侧的所有左节点到栈里
root=stk.top();
stk.pop();
res.push_back(root->val); //中
//当是左叶子节点时,root->right为空,下次循环弹出栈并记录该左叶子节点的根节点,完成“左节点-根节点”的遍历
root=root->right;
//root为不是空指针的右节点时,下次循环添加进栈里,然后记录结果
}
return res;
}
};
2.3后序遍历:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
TreeNode* pre;
//当root为空指针并且栈为空时,遍历结束
while(root!=nullptr || !stk.empty())
{
while(root!=nullptr)
{
stk.push(root);
root=root->left;
}/添加该节点一侧的所有左节点到栈里
root=stk.top();
stk.pop();
if(root->right==nullptr || root->right==pre)
//当是左叶子节点时,它的右孩子节点为空,向下执行记录节点val数值,pre记录栈顶弹开节点,root指向空节点,在下次循环时,跳过上面的while循环,不添加该节点的左孩子节点。
//当根节点的右孩子节点和上次pre记录的节点相同时,说明该节点的右孩子已经弹出栈并记录在结果里,向下执行记录结果。
{
res.push_back(root->val);
pre=root;
root=nullptr;
}
else
{
//说明该节点是第一次遍历,它的右孩子(不为空指针)还没进入栈。将该根节点添加进栈,root指向它的右孩子节点,在下次循环添加进栈。
stk.push(root);
root=root->right;
}
}
return res;
}
};