数据结构
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
层次遍历
注意一开始要判断根节点是否为 N U L L NULL NULL。
if(Root == NULL)
return;
queue<TreeNode*> q;
q.push(Root);
while(!q.empty())
{
int size = q.size(); // 当前层的结点数
while(size--)
{
TreeNode* thenode = q.front();
q.pop();
if(thenode->left != NULL)
q.push(thenode->left);
if(thenode->right != NULL)
q.push(thenode->right);
// 对结点的操作
}
}
树的深度
利用层次遍历,每一层加1。
if(pRoot == NULL)
return 0;
queue<TreeNode*> q;
q.push(pRoot);
int cnt = 0; // 层数
while(!q.empty())
{
int size = q.size(); // 当前层的结点数
while(size--)
{
TreeNode* thenode = q.front();
q.pop();
if(thenode->left != NULL)
q.push(thenode->left);
if(thenode->right != NULL)
q.push(thenode->right);
}
cnt++; // 层数加1
}
return cnt;
前/中/后序遍历
递归
根据前/中/后调整左右子树和当前结点的位置。
vector<int> res
是引用传递。
void visit(TreeNode* node, vector<int>& res)
{
if(node == NULL) return;
visit(node->left, res); // 左子树
visit(node->right, res); // 右子树
res.push_back(node->val); // 本结点
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if(root == NULL) return res;
visit(root, res);
return res;
}
非递归前序
c
u
r
cur
cur表示当前结点。
c
u
r
cur
cur一直向左下(左孩子)走,每次访问
c
u
r
cur
cur并将其入栈,直到无路可走,这时
c
u
r
cur
cur取栈顶结点的右孩子
例子:
访问A、B、D并将其入栈
D出栈
B出栈,
c
u
r
cur
cur取其左节点E
访问E、H并将其入栈
H出栈
E出栈
B出栈
A出栈,
c
u
r
cur
cur取其左节点C
访问C、F、I、K并将其入栈
K出栈
I出栈
F出栈
C出栈,
c
u
r
cur
cur取其左节点G
G出栈,
c
u
r
cur
cur取其左节点J
访问J、L并将其入栈
L出栈
J出栈
结束
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if(root == NULL) return res;
stack<TreeNode*> sta;
TreeNode* cur = root;
while(cur != NULL || !sta.empty())
{
while(cur != NULL) //一直向左下走
{
// 访问cur并将其入栈
res.push_back(cur->val);
sta.push(cur);
cur = cur->left;
}
// 无路可走,cur取栈顶元素的右孩子
cur = sta.top();
sta.pop();
cur = cur->right;
}
return res;
}
非递归后序
前序是当前结点
→
\rightarrow
→左子树
→
\rightarrow
→右子树,后序是左子树
→
\rightarrow
→右子树
→
\rightarrow
→当前结点,因此可以按照前序的方式,访问当前结点
→
\rightarrow
→右子树
→
\rightarrow
→左子树,最后把结果反转reverse(res.begin(), res.end());
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if(root == NULL) return res;
stack<TreeNode*> sta;
TreeNode* cur = root;
while(cur != NULL || !sta.empty())
{
while(cur != NULL) //一直向右下走
{
res.push_back(cur->val);
sta.push(cur);
cur = cur->right;
}
cur = sta.top();
sta.pop();
cur = cur->left;
}
reverse(res.begin(), res.end()); // 将结果反转
return res;
}
非递归中序
中序和前序类似,只是在向左下方走的时候,不访问当前结点,只有在出栈的时候才访问当前结点。
入栈出栈顺序和前序是一样的,只是访问顺序不一样,前序是入栈的时候访问,后序是出栈的时候访问。
例子:
A、B、D入栈
D出栈,访问D
B出栈,访问B,
c
u
r
cur
cur取E
E、H入栈
H出栈,访问H
E出栈,访问E
A出栈,访问A,
c
u
r
cur
cur取C
C、F、I、K入栈
K出栈,访问K
I出栈,访问I
F出栈,访问F
C出栈,访问C,
c
u
r
cur
cur取G
G出栈,访问G,
c
u
r
cur
cur取J
J、L入栈
L出栈,访问L
J出栈,访问J
结束
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if(root == NULL) return res;
stack<TreeNode*> sta;
TreeNode* cur = root;
while(cur != NULL || !sta.empty())
{
while(cur != NULL) //一直向左下走
{
sta.push(cur);
cur = cur->left;
}
cur = sta.top();
sta.pop();
res.push_back(cur->val); // 出栈时访问当前结点
cur = cur->right;
}
return res;
}```
-------------------------