文章目录
- 一、题目
- 二、递归算法
- 三、迭代算法
- 四、完整代码
所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。
一、题目
二、递归算法
思路分析:这道题比较简单,不多说了,大家直接看代码就行。注意前中后遍历是指中间节点的遍历顺序。同时中序和后序的代码也很类似,这里给出三道题代码。
前序遍历程序如下:
class Solution {
public:
// 前序遍历
void traversal_preOrder(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
vec.push_back(cur->val); // 中
traversal_preOrder(cur->left, vec); // 左
traversal_preOrder(cur->right, vec); // 右
}
vector<int> preorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
vector<int> result;
traversal_preOrder(root, result);
return result;
}
};
复杂度分析可以参考这篇文章二叉树多种遍历的时间复杂度和空间复杂度。
- 时间复杂度: O ( n ) O(n) O(n)。
- 空间复杂度: O ( n ) O(n) O(n)。
中序遍历程序如下:
// 中序遍历
class Solution2 {
public:
void traversal_midOrder(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal_midOrder(cur->left, vec); // 左
vec.push_back(cur->val); // 中
traversal_midOrder(cur->right, vec); // 右
}
vector<int> inorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
vector<int> result;
traversal_midOrder(root, result);
return result;
}
};
后序遍历程序如下:
// 后序遍历
class Solution3 {
public:
void traversal_postOrder(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal_postOrder(cur->left, vec); // 左
traversal_postOrder(cur->right, vec); // 右
vec.push_back(cur->val); // 中
}
vector<int> postorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
vector<int> result;
traversal_postOrder(root, result);
return result;
}
};
三、迭代算法
遍历树节点的时候要注意是右节点先入栈,左节点后入栈,这样在出栈的时候就是左节点先出栈。
前序遍历程序如下:
// 前序遍历迭代法 中左右
class Solution4 {
public:
vector<int> preorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
stack<TreeNode*> st;
vector<int> 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;
}
};
中序遍历是左中右,需要一层层找到最左边的节点,在遍历的过程当中依次将遍历元素压入栈,最左边元素就在栈顶,可以首先输出,就实现左中右顺序的遍历。
中序遍历程序如下:
// 中序遍历迭代法 左中右
class Solution5 {
public:
vector<int> inorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
stack<TreeNode*> st;
vector<int> result;
TreeNode* node = root;
while (node != NULL || !st.empty()) { // 栈非空或节点非空, 每次循环更新node
if (node != NULL) {
st.push(node);
node = node->left;
}
else {
node = st.top();
st.pop();
result.push_back(node->val);
node = node->right; // 右节点
}
}
return result;
}
};
后序遍历只需要将前序遍历翻转一下就能实现。
后序遍历程序如下:
// 后序遍历迭代法 左右中
class Solution6 {
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) st.push(node->left); // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈)
if (node->right) st.push(node->right); // 空节点不入栈
}
reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了
return result;
}
};
四、完整代码
# include <iostream>
# include <vector>
# include <stack>
using namespace std;
// 树节点定义
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_preOrder(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
vec.push_back(cur->val); // 中
traversal_preOrder(cur->left, vec); // 左
traversal_preOrder(cur->right, vec); // 右
}
vector<int> preorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
vector<int> result;
traversal_preOrder(root, result);
return result;
}
};
// 中序遍历递归法
class Solution2 {
public:
void traversal_midOrder(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal_midOrder(cur->left, vec); // 左
vec.push_back(cur->val); // 中
traversal_midOrder(cur->right, vec); // 右
}
vector<int> inorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
vector<int> result;
traversal_midOrder(root, result);
return result;
}
};
// 后序遍历递归法
class Solution3 {
public:
void traversal_postOrder(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal_postOrder(cur->left, vec); // 左
traversal_postOrder(cur->right, vec); // 右
vec.push_back(cur->val); // 中
}
vector<int> postorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
vector<int> result;
traversal_postOrder(root, result);
return result;
}
};
// 前序遍历迭代法 中左右
class Solution4 {
public:
vector<int> preorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
stack<TreeNode*> st;
vector<int> 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;
}
};
// 中序遍历迭代法 左中右
class Solution5 {
public:
vector<int> inorderTraversal(TreeNode* root) {
if (root == NULL) return {};
if (root->left == NULL && root->right == NULL) return { root->val };
stack<TreeNode*> st;
vector<int> result;
TreeNode* node = root;
while (node != NULL || !st.empty()) { // 栈非空或节点非空, 每次循环更新node
if (node != NULL) {
st.push(node);
node = node->left;
}
else {
node = st.top();
st.pop();
result.push_back(node->val);
node = node->right; // 右节点
}
}
return result;
}
};
// 后序遍历迭代法 左右中
class Solution6 {
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) st.push(node->left); // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈)
if (node->right) st.push(node->right); // 空节点不入栈
}
reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了
return result;
}
};
void my_print(vector <int>& v, string msg)
{
cout << msg << endl;
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
// 构造树
TreeNode* node3 = new TreeNode(3);
TreeNode* node2 = new TreeNode(2, node3, NULL);
TreeNode* root = new TreeNode(1, NULL, node2);
Solution6 s1;
vector<int> result = s1.postorderTraversal(root);
my_print(result, "中序遍历结果:");
system("pause");
return 0;
}
end