二叉树的递归遍历
三种遍历方式,使用递归实现,就是改变遍历的顺序即可。
/**
* 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 travlesal(TreeNode* Cur,vector<int>& result){
if(Cur==NULL) return;
result.push_back(Cur->val);
travlesal(Cur->left,result);
travlesal(Cur->right,result);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
travlesal(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:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root==NULL) return result;
st.push(root);
while(!st.empty()){
TreeNode* Node=st.top();
st.pop();
result.push_back(Node->val);
if(Node->right!=NULL) st.push(Node->right);
if(Node->left!=NULL) 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> inorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
TreeNode* cur=root;
while(cur!=NULL||!st.empty()){
if(cur!=NULL){
st.push(cur);
cur=cur->left;
}
else{
cur=st.top();
st.pop();
result.push_back(cur->val);
cur=cur->right;
}
}
return result;
}
};
后序
后序可以使用前序的思路前序为中左右,后序为左右中,只需要将前序改为中右左,然后翻转结果数组即可实现左右中的遍历顺序。
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root==NULL) return result;
st.push(root);
while(!st.empty()){
TreeNode* Node=st.top();
st.pop();
result.push_back(Node->val);
if(Node->left!=NULL) st.push(Node->left);
if(Node->right!=NULL) st.push(Node->right);
}
reverse(result.begin(),result.end());
return result;
}
};
统一迭代 (基础不好的录友,迭代法可以放过)
为了解决上述方法中访问节点与遍历节点顺序不一致的问题,我们采用标记法解决,也就是在要处理的节点后放入一个标记NULL,我们编程时从栈中取出NULL时就将其后面的节点也就是我们需要遍历的节点放入数组,这样我们只要保证没有遇到NULL时改变其左右孩子与该节点加入栈中的顺序就可以实现统一迭代。比如我写的是前序,遇到节点先放入右孩子,再左孩子,再节点,然后放入一个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> preorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root!=NULL) st.push(root);
while(!st.empty()){
TreeNode* Node=st.top();
if(Node!=NULL)
{
st.pop();
if(Node->right) st.push(Node->right);
if(Node->left) st.push(Node->left);
st.push(Node);
st.push(NULL);
}
else{
st.pop();
Node=st.top();
st.pop();
result.push_back(Node->val);
}
}
return result;
}
};