层序遍历方式就是图论中的广度优先遍历。
leetcode 102. 二叉树的层序遍历
题目链接:二叉树的层序遍历
二叉树的层序遍历使用队列实现,队列先进先出,符合一层一层遍历的逻辑。
栈先进后出适合深度优先遍历也就是递归的逻辑。
迭代法:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
vector<vector<int>> res; //层序遍历使用vector<vector<int>>
while (!que.empty()) {
int size = que.size(); // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
vector<int> vec;
for (int i = 0; i < size; i++) {
TreeNode* cur = que.front();
que.pop();
vec.push_back(cur->val);
if (cur->left) que.push(cur->left);
if (cur->right) que.push(cur->right);
}
res.push_back(vec);
}
return res;
}
};
递归法:
class Solution {
public:
void order(TreeNode* cur, vector<vector<int>>& result, int depth)
{
if (cur == NULL) return;
if (result.size() == depth) result.push_back(vector<int>());
result[depth].push_back(cur->val);
order(cur->left, result, depth + 1);
order(cur->right, result, depth + 1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
int depth = 0; //层数
order(root, result, depth);
return result;
}
};
leetcode 226. 翻转二叉树
题目链接:翻转二叉树
递归法——前序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == NULL) return root;
swap(root->left,root->right); //处理中间节点的左右子树
invertTree(root->left);
invertTree(root->right);
return root;
}
};
迭代法——前序遍历:
标准格式的前序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == NULL) return root;
stack<TreeNode*> st;
if(root!=NULL) st.push(root);
while(!st.empty())
{
TreeNode* node=st.top(); //中
st.pop();
swap(node->left,node->right);
if(node->left) st.push(node->left); //左
if(node->right) st.push(node->right); //右
}
return root;
}
};
使用统一格式的前序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> st;
if (root != NULL) st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
if (node != NULL) {
st.pop(); //先弹出当前节点
if (node->right) st.push(node->right); // 右
if (node->left) st.push(node->left); // 左
st.push(node); // 中
st.push(NULL);
} else {
st.pop();
node = st.top();
st.pop();
swap(node->left, node->right); // 节点处理逻辑
}
}
return root;
}
};
迭代法——层序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == NULL) return root;
queue<TreeNode*> que;
if(root!=NULL) que.push(root);
while(!que.empty())
{
int size=que.size();
for(int i=0;i<size;i++)
{
TreeNode* node=que.front();
que.pop();
swap(node->left,node->right); //节点处理
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return root;
}
};
leetcode 101. 对称二叉树
题目链接:对称二叉树
- 对称二叉树要比较的不是左右节点,要比较的是两个树,即根节点的左右子树,所以在递归遍历过程中,需要同时遍历两个树。
- 本题需要比较的分别是两个子树的内侧和外侧的元素是否相等。
- 因为需要遍历两棵树,并且需要比较内侧和外侧节点,所以一个树的遍历顺序是左右中,另一个树的遍历顺序是右左中。即特殊的"后序遍历"。
递归法:
class Solution {
public:
bool compare(TreeNode* left, TreeNode* right)
{
//首先排除空节点
if(left==NULL && right==NULL) return true;
else if(left!=NULL && right==NULL) return false;
else if(left==NULL && right!=NULL) return false;
//排除空节点后,在排除数值不同的情况
else if(left->val!=right->val) return false;
bool outside= compare(left->left,right->right); //左子树->左,右子树->右
bool inside = compare(left->right,right->left);//左子树->右,右子树->左
bool issame = outside && inside; // 左子树->中、 右子树->中 (逻辑处理)
return issame;
}
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
return compare(root->left,root->right);
}
};
上述代码可以简洁为如下代码:
class Solution {
public:
bool compare(TreeNode* left, TreeNode* right)
{
//首先排除空节点
if(left==NULL && right==NULL) return true;
else if(left!=NULL && right==NULL) return false;
else if(left==NULL && right!=NULL) return false;
//排除空节点后,在排除数值不同的情况
else if(left->val!=right->val) return false;
return compare(left->left,right->right) && compare(left->right,right->left);
}
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
return compare(root->left,root->right);
}
};
迭代法:
迭代法使用队列来比较左右子树是否相等。(注意这里不是层序遍历)
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
queue<TreeNode*> que;
que.push(root->left); // 将左子树头结点加入队列
que.push(root->right); // 将右子树头结点加入队列
while(!que.empty())
{
TreeNode* leftNode = que.front();
que.pop();
TreeNode* rightNode = que.front();
que.pop();
if (!leftNode && !rightNode) //左节点为空、右节点为空,此时说明是对称的
{
continue;
}
// 左右一个节点不为空,或者都不为空但数值不相同,返回false
else if ((!leftNode || !rightNode || (leftNode->val != rightNode->val)))
{
return false;
}
que.push(leftNode->left); // 加入左节点左孩子
que.push(rightNode->right); // 加入右节点右孩子
que.push(leftNode->right); // 加入左节点右孩子
que.push(rightNode->left); // 加入右节点左孩子
}
return true;
}
};