二叉树的遍历
注意:不要忘记二叉树的定义(可以看成链表)!因为Leetcode都是核心代码模式
一 递归遍历
Leetcode 144,145,94
思考
递归和迭代法的原理其实是一样的。递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数。 所以我们也可以用迭代法来实现。
前序遍历
/**
* 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 traversal(TreeNode * cur, vector<int> &vec)
{
if(cur==nullptr)
{
return; // 递归终止条件-节点为空
}
//前序遍历先取中节点的值
vec.push_back(cur->val);
//递归左,右子树
traversal(cur->left,vec);
traversal(cur->right,vec);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
中序遍历
/**
* 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 traversal(TreeNode * cur, vector<int> &vec)
{ //中序遍历左中右
if(cur==nullptr) return ;
traversal(cur->left,vec);
vec.push_back(cur->val);
traversal(cur->right,vec);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
后序遍历
/**
* 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 traversal(TreeNode * cur,vector<int> &vec)
{ //后续遍历 左右中
if(cur==nullptr) return;
traversal(cur->left,vec);
traversal(cur->right,vec);
vec.push_back(cur->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int>result;
traversal(root,result);
return result;
}
};
二 迭代遍历
思考
因为前序和后序遍历中 最开始要访问和处理的元素都是一样的(后序遍历可以看成中在最前后面再reverse一下),中序遍历处理和访问的顺序不同,所以中序遍历和前俩者有很大区别。中序遍历需要先访问到左边最底部,然后再进行处理(将节点的数值放入result数组里)。那么** 在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。**
前序遍历
/**
* 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> preorderTraversal(TreeNode* root) {
//前序遍历 中左右
stack<TreeNode*> st;
vector<int> result;
if(root==nullptr) return result;
st.push(root);
while( !st.empty())
{
TreeNode * node = st.top(); //中节点
st.pop(); //从栈中弹出
//用栈的话压入 右,左,然后才能弹出左,右顺序
//空节点不入栈
result.push_back(node->val);
if(node->right) st.push(node->right);
if(node->left) st.push(node->left);
}
return result;
}
};
后序遍历
/**
* 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> postorderTraversal(TreeNode* root) {
//后续遍历 左右中
stack<TreeNode*> st;
vector<int> result;
if(root == nullptr) return result;
st.push(root);
while( !st.empty())
{
TreeNode * node = st.top();
st.pop();
result.push_back(node->val);
if(node->left) st.push(node->left);
if(node->right) st.push(node->right); //栈中压入左,右,弹出右左
}
reverse(result.begin(),result.end()); // result得到的是中右左,reverse下就是左右中
return result;
}
};
中序遍历
/**
* 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> inorderTraversal(TreeNode* root) {
//中序遍历顺序 左中右
vector<int>result;
stack<TreeNode*> st;
TreeNode * cur = root;
while( cur != nullptr || !st.empty())
{
if(cur != nullptr)
{ //用指针来访问节点一直到最底层
st.push(cur); //将访问的节点放入栈中
cur = cur->left; //左
}
else
{
cur = st.top(); //当遇到空节点时说明最后压入的是左节点 , 让cur指向top
st.pop(); //弹出
result.push_back(cur->val); //中
cur = cur->right; //右
//右节点也为空的话继续弹出
}
}
return result;
}
};