二叉树的迭代遍历
144 二叉树的前序遍历
-
思路
递归的实现是用栈来实现的,因此二叉树的遍历也可以用栈来实现。
对于前序遍历,输出结点顺序是中左右,每次先处理中间结点,和结点访问的顺序相同,接着右节点,左节点入栈,这样可以保证先输出左节点。如果当前栈顶结点不为空,则当前结点出栈后继续入栈它的左右结点;如果当前栈顶结点为空,则将当前结点出栈,直到栈顶结点不为空。 -
代码
/**
* 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> res;
st.push(root);
while (!st.empty()) {
TreeNode* cur = st.top();
st.pop();
if (cur != nullptr) {
res.push_back(cur->val);
st.push(cur->right);
st.push(cur->left);
}
}
return res;
}
};
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:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> res;
TreeNode* cur = root;
while(cur != nullptr || !st.empty()) {
if (cur != nullptr) {
st.push(cur);
cur = cur->left;
}else {
cur = st.top();
st.pop();
res.push_back(cur->val);
cur = cur->right;
}
}
return res;
}
};
145 二叉树的后序遍历
-
思路
后序遍历顺序是左右中,可以通过直接和间接两种方法来得到结果。
直接方法:我们访问是先访问中间结点,然后才知道它的左右结点,而要处理的结点顺序是左右中,因此我们需要给要处理的结点加一个标记,当我们访问一个中间结点时,在它后面加一个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> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> res;
if(root) st.push(root);
while(!st.empty()) {
TreeNode* cur = st.top();
if(cur != nullptr) {
st.push(nullptr);
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
}else {
st.pop();
res.push_back(st.top()->val);
st.pop();
}
}
return res;
}
};
间接
/**
* 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> res;
st.push(root);
while(!st.empty()) {
TreeNode* cur = st.top();
st.pop();
if(cur != nullptr) {
res.push_back(cur->val);
st.push(cur->left);
st.push(cur->right);
}
}
reverse(res.begin(),res.end());
return res;
}
};
层序遍历
-
思路
按层输出二叉树,一层一层遍历,适合用队列来解决,队列先进先出,与一层一层遍历的逻辑吻合。 -
代码
/**
* 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<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
vector<vector<int>> res;
if(root) que.push(root);
while(!que.empty()){
int size = que.size();
vector<int> vec;
for(int i = 0;i < size;i++) {
TreeNode* cur = que.front();
if(cur->left) que.push(cur->left);
if(cur->right) que.push(cur->right);
que.pop();
vec.push_back(cur->val);
}
res.push_back(vec);
}
return res;
}
};