今天主要是二叉树的遍历,之前一直写的是递归的方法,今跟着敲一下迭代的方法。
leetcode 144前序遍历
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) st.push(node->right);//注意是先加右后加左
if(node->left) st.push(node->left);
}
return result;
}
};
145.后序
引用一下卡哥的图,这里后序是可以由前序经过一些操作转化的
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
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) st.push(node->left);//这里和前序有区别这里是先左后右
if(node->right) st.push(node->right);
}
reverse(result.begin(),result.end());
return result;
}
};
94.中序
中序和上面两种都不同,中序有两个操作,他要先将节点进行存储,这个环节结束后才进行访问
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
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;
}
};
102.层序遍历
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
int size = que.size();
vector<int> vec;
// 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
result.push_back(vec);
}
return result;
}
};
统一迭代法
昨天晚上急忙写完继续看了一下统一迭代法,很有意思,今早起床将卡哥的代码拷进里面,方便日后学习
我们将访问的节点直接加入到栈中,但如果是处理的节点则后面放入一个空节点, 这样只有空节点弹出的时候,才将下一个节点放进结果集。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
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); // 添加右节点(空节点不入栈)
st.push(node); // 添加中节点
st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (node->left) st.push(node->left); // 添加左节点(空节点不入栈)
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.top(); // 重新取出栈中元素
st.pop();
result.push_back(node->val); // 加入到结果集
}
}
return result;
}
};
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
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;
}
};
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
if (root != NULL) st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
if (node != NULL) {
st.pop();
st.push(node); // 中
st.push(NULL);
if (node->right) st.push(node->right); // 右
if (node->left) st.push(node->left); // 左
} else {
st.pop();
node = st.top();
st.pop();
result.push_back(node->val);
}
}
return result;
}
};