二叉树的非递归遍历
cpp
/**
* 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) {}
* };
*/
python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
前序
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
stack<TreeNode*> stk;
TreeNode* node = root;
while (!stk.empty() || node != nullptr) {
while (node != nullptr) {
stk.push(node);
res.push_back(node->val);
node = node->left;
}
node = stk.top();
stk.pop();
node = node->right;
}
return res;
}
};
中序
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> st;
TreeNode* cur = root;
while(cur or !st.empty()){
while(cur){
st.push(cur);
cur = cur->left;
}
cur = st.top();
res.push_back(cur->val);
st.pop();
cur = cur->right;
}
return res;
}
};
后序
/*
1. 后序非递归遍历顺序:左右根
2. 用堆栈来存储结点时,必须分清返回根节点时 是从左子树返回还是右子树返回。
3. 所以使用辅助指针r,指向最近访问过的结点。
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if (root == nullptr) return res;
stack<TreeNode *> stk;
TreeNode *cur = root;
TreeNode *prev = nullptr; //是从左子树返回,还是右子树
while (cur != nullptr || !stk.empty()) {
while (cur != nullptr) {
stk.push(cur);
cur = cur->left;
}
cur = stk.top(); //最左边的节点
stk.pop();
if (cur->right == nullptr || cur->right == prev) { //是从右子树返回
res.push_back(cur->val);
prev = cur;
cur = nullptr;
} else {
stk.emplace(cur); //根结点
cur = cur->right;
}
}
return res;
}
};
114. 二叉树展开为链表
class Solution {
public:
//先序遍历后再连接起来
vector<TreeNode*> list;
void flatten(TreeNode* root) {
if(root==nullptr) return;
preorder(root);
int len = list.size();
for(int i=0; i<len-1; ++i){
list[i]->left = nullptr;
list[i]->right = list[i+1];
}
return;
}
void preorder(TreeNode* root){
if(root==nullptr) return;
list.push_back(root);
preorder(root->left);
preorder(root->right);
}
};
二叉树的路径问题
437. 路径总和 III
class Solution {
public:
int res = 0;
int pathSum(TreeNode* root, int targetSum) {
if(root==nullptr) return 0;
pathroot(root, targetSum);
pathSum(root->left, targetSum);
pathSum(root->right, targetSum);
return res;
}
void pathroot(TreeNode* root, int targetSum){
if(root==nullptr) return;
if(targetSum-root->val==0) res++;
pathroot(root->left, targetSum-root->val);
pathroot(root->right, targetSum-root->val);
}
};
662. 二叉树最大宽度
/**
* 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:
int widthOfBinaryTree(TreeNode* root) {
if(!root) return 0;
queue<pair<TreeNode*, int> > q;
q.push({root, 1});
int ans = 1;
while(q.size()) {
// 遍历每层的时候设置左顶点,右顶点
int n = q.size();
int l = q.front().second, r;
for(int i = 0; i < n; i ++) {
auto x = q.front();
q.pop();
auto ver = x.first;
// 将每层节点初始化从一开始计算
auto pos = x.second - l + 1;
r = x.second;
if(ver -> left) q.push({ver -> left, pos * 2});
if(ver -> right) q.push({ver -> right, pos * 2 + 1});
}
ans = max(ans, r - l + 1);
}
return ans;
}
};
剑指 Offer 26. 树的子结构
1、自顶向下:
顾名思义,就是从某一个节点(不一定是根节点),从上向下寻找路径,到某一个节点(不一定是叶节点)结束
257. 二叉树的所有路径
面试题 04.12. 求和路径
112. 路径总和
113. 路径总和 II
437. 路径总和 III
988. 从叶结点开始的最小字符串
2、非自顶向下:
就是从任意节点到任意节点的路径,不需要自顶向下
124. 二叉树中的最大路径和
687. 最长同值路径
543. 二叉树的直径