1 深度优先
1.1 前序遍历
(leetcode 144题)
前序遍历即为当遍历一棵树时, 先遍历自身节点, 然后遍历其左子树, 最后是其右子树
1.1.1 递归实现
递归实现很好实现了, 不需要写了
1.1.2 非递归实现
先序遍历的非递归版本需要用到栈, 因为自身先遍历, 所以先放入自身, 每次遍历时先遍历自身, 如果有右子节点, 栈压入右子节点, 如果有左子节点, 栈压入左子节点(因为遍历顺序为自身->左子树->右子树, 后入先出, 所以先压入右节点)
代码:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> t_stack;
if (root) {
t_stack.push(root);
}
while (!t_stack.empty()) {
TreeNode* node = t_stack.top();
t_stack.pop();
res.push_back(node->val);
if (node->right)
t_stack.push(node->right);
if (node->left)
t_stack.push(node->left);
}
return res;
}
1.2 中序遍历
(leetcode 94题)
1.2.1 递归实现
1.2.2 非递归实现
二叉树中序遍历的非递归(迭代)版本, 就比较麻烦了, 首先要确定的是顺序: 左子树->节点->右子树, 所以只要左子树有子节点, 就一直让其入栈, 直到没有左子节点, 则遍历自身, 然后将其右节点入栈, 重复上述过程.
代码:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> t_stack;
while (root || !t_stack.empty()) {
while (root) {
t_stack.push(root);
root = root->left;
}
root = t_stack.top();
t_stack.pop();
res.push_back(root->val);
root = root->right;
}
return res;
}
1.3 后续遍历
(leetcode 145题)
1.3.1 递归实现
1.3.2 非递归实现
后续遍历同样可以用栈来实现, 但是会比前序遍历更复杂一些. 首先, 后续遍历的顺序为左子树->右子树->自身节点, 所以思路是, 设计一个栈, 入栈顺序为: 节点自身->节点右节点->节点左节点. 这样遍历的话就是左->右->自身了. 遍历的规则是, 如果这个节点是叶子节点, 还有一个条件, 就是子节点已经遍历过了, 那么就遍历该节点, 否则就是左右子节点入栈. 那么怎么确定每个节点的左右子节点是否遍历过呢, 可以每遍历一个节点都记录一下当前遍历的节点, 这样在检查一个节点的子节点是否遍历过时, 就看上一个遍历过的节点是不是自己的左右子节点就可以.
代码:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> t_stack;
if (root) {
t_stack.push(root);
}
TreeNode* prev = nullptr;
while (!t_stack.empty()) {
TreeNode *node = t_stack.top();
//如果是叶子节点, 或者子节点已经遍历过(prev是当前的子节点)
if ((!node->left && !node->right) || (prev && (prev == node->left || prev == node->right))) {
//遍历, prev置为当前node, 退栈
res.push_back(node->val);
prev = node;
t_stack.pop();
} else {
if (node->right)
t_stack.push(node->right);
if (node->left)
t_stack.push(node->left);
}
}
return res;
}
2 广度优先(层序遍历)
(leetcode 102题)
二叉树层序遍历, 以层为优先, 可以以队列的方式进行.
代码:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if (root) {
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int l_c = q.size();
vector<int> l_res;
for (int i = 0; i < l_c; i ++) {
TreeNode* node = q.front();
q.pop();
l_res.push_back(node->val);
if (node->left)
q.push(node->left);
if (node->right)
q.push(node->right);
}
res.push_back(l_res);
}
}
return res;
}