学习目标:使用c++对二叉树进行递归、迭代以及Morris的便利
问题
递归
二叉树的中序遍历:按照访问左子树——根节点——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候我们按照同样的方式遍历,直到遍历完整棵树。
思路:
迭代
Morris
代码实现
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
using std::vector;
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 DiGui {
public:
void inorder(TreeNode* root, vector<int>& res) {
if (!root) {
return;
}
inorder(root->left, res);
cout << root->val << " ";
res.push_back(root->val); // 在 vector 类中作用为在 vector 尾部加入一个数据。 string中也有这个函数,作用是字符串之后插入一个字符。
inorder(root->right, res);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inorder(root, res);
return res;
}
};
// 迭代
class DieDai {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
cout << "\n" << endl;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
cout << root->val << " ";
res.push_back(root->val);
root = root->right;
}
return res;
}
};
// Morris算法
class Morris {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode* predecessor = nullptr;
cout << "\n" << endl;
while (root != nullptr) {
if (root->left != nullptr) {
// predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
predecessor = root->left;
while (predecessor->right != nullptr && predecessor->right != root) {
predecessor = predecessor->right;
}
// 让 predecessor 的右指针指向 root,继续遍历左子树
if (predecessor->right == nullptr) {
predecessor->right = root;
root = root->left;
}
// 说明左子树已经访问完了,我们需要断开链接
else {
cout << root->val << " ";
res.push_back(root->val);
predecessor->right = nullptr;
root = root->right;
}
}
// 如果没有左孩子,则直接访问右孩子
else {
cout << root->val << " ";
res.push_back(root->val);
root = root->right;
}
}
return res;
}
};
int main()
{
TreeNode* A = new TreeNode(1);
/* TreeNode* B = new TreeNode(NULL);*/ // 当子树为NULL时,打印出的值为0
TreeNode* C = new TreeNode(2);
TreeNode* D = new TreeNode(3);
/* A->left = B;*/
A->right = C;
C->left = D;
DiGui digui; // 执行递归
vector<int> V1 = digui.inorderTraversal(A);
DieDai diedai; // 执行迭代
vector<int> V2 = diedai.inorderTraversal(A);
Morris morris; // 执行morris
vector<int> V3 = diedai.inorderTraversal(A);
}