1 先序遍历
1.1 递归
void preOrder(TreeNode* root, vector<int>& preRes) {
//根左右
if(root == nullptr) return;
preRes.push_back(root->val);
preOrder(root->left, preRes);
preOrder(root->right, preRes);
}
1.2 迭代
void preOrder(TreeNode* root, vector<int>& preRes) {
//根左右
stack<TreeNode*> stk;
stk.push(root); //根节点入栈
while(!stk.empty()) {
TreeNode *tmp = stk.top(); //当栈非空时,栈顶出栈
stk.pop();
preRes.push_back(tmp->val);
if(tmp->right) stk.push(tmp->right); //先进后出,右子节点先入栈
if(tmp->left) stk.push(tmp->left); //左子节点后入栈先出栈
}
}
1.3 引申
1.3.1 翻转二叉树
//递归
TreeNode* invertTree(TreeNode* root) {
if(root == nullptr) return nullptr;
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
//辅助栈
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> stk;
stk.push(root);
while(!stk.empty()) {
TreeNode *node = stk.top();
stk.pop();
if(root == nullptr) continue;
swap(node->left, node->right); //交换左右子节点
stk.push(node->right);
stk.push(node->left);
}
return root;
}
1.3.2 LC538 把二叉搜索树转换为累加树
题意:使每个节点node的新值等于原树中大于或等于node->val的值之和
int num = 0;
TreeNode* convertBST(TreeNode* root) {
//利用二叉搜索树的性质,右根左 -> 从大到小
if(root == nullptr) return nullptr;
if(root->right) convertBST(root->right);
num += root->val;
root->val = num;
if(root->left) convertBST(root->left);
return root;
}
1.3.3 LC617 合并二叉树
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1 == nullptr) return root2;
if(root2 == nullptr) return root1;
root1->val += root2->val;
root1->left = mergeTrees(root1->left, root2->left);
root1->right = mergeTrees(root1->right, root2->right);
return root1;
}
2 中序遍历
2.1 递归
void inOrder(TreeNode* root, vector<int>& inRes) {
//左根右
if(root == nullptr) return;
inOrder(root->left, inRes);
inRes.push_back(root->val);
inOrder(root->right, inRes);
}
2.2 迭代
void inOrder(TreeNode* root, vector<int>& inRes) {
//左根右
stack<TreeNode*> stk;
while(root != nullptr || !stk.empty()) { //当栈非空或root非nullptr时循环
while(root != nullptr) {
stk.push(root); //遍历左子节点入栈
root = root->left;
}
root = stk.top();
stk.pop();
inRes.push_back(root->val);
root = root->right;
}
}
3 后序遍历
3.1 递归
void postOrder(TreeNode* root, vector<int>& postRes) {
//左右根
if(root == nullptr) return;
postOrder(root->left, postRes);
postOrder(root->right, postRes);
postRes.push_back(root->val);
}
3.2 迭代
void postOrder(TreeNode* root, vector<int>& postRes) {
//左右根
stack<TreeNode*> stk1; //根右左
stack<TreeNode*> stk2; //stk1的倒序即为后序遍历
stk1.push(root);
while(!stk1.empty()) {
root = stk1.top();
stk1.pop();
stk2.push(root);
if(root->left) stk1.push(root->left);
if(root->right) stk1.push(root->right);
}
while(!stk2.empty()) {
postRes.push_back(stk2.top()->val);
stk2.pop();
}
}
3.3 引申
3.3.1 二叉树的最近公共祖先
最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//递归终止条件
if(root == nullptr || root == p || root == q) return root;
//自底向上遍历
TreeNode *left = lowestCommonAncestor(root->left, p, q);
TreeNode *right = lowestCommonAncestor(root->right, p, q);
if(left != nullptr && right != nullptr) return root;
return left ? left : right;
return nullptr;
}
4 层序遍历
4.1 JZ32 -2 从上到下打印二叉树
class Solution {
public:
vector<vector<int> > levelOrder(TreeNode* root) {
// write code here
vector<vector<int>> res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
vector<int> level; //局部变量
int size = q.size();
for(int i = 0; i < size; ++i) { //遍历层
TreeNode *node = q.front();
q.pop();
level.push_back(node->val);
if(node->left) q.push(node->left); //当前节点的左右子节点入队列
if(node->right) q.push(node->right);
}
res.push_back(level);
}
return res;
}
};
4.2 JZ32 -3 从上到下之字形打印二叉树
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
bool flag = true;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
int n = q.size();
vector<int> path;
for(int i = 0; i < n; ++i) {
TreeNode *node = q.front();
q.pop();
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
path.push_back(node->val);
}
if(flag) {
res.push_back(path);
}
else {
res.push_back(vector<int>(path.rbegin(), path.rend()));
}
flag = !flag;
}
return res;
}