概念
访问树中的所有节点,以根节点访问顺序决定是什么遍历,左子树访问顺序都是优于右子树。
深度优先遍历(DFS)
DSF就是沿着一个路径走到头去遍历,分为前序遍历、中序遍历、后续遍历三种。
前序遍历
先访问根节点,再前序遍历左子树,再前序遍历右子树。
递归
void preorderTraversal(TreeNode* root) {
if(root == nullptr)
return;
// 先访问根再访问左右
std::cout << root->iValue << std::endl;
preorderTraversal(root->pLeft);
preorderTraversal(root->pRight);
}
迭代
void preorderTraversal(TreeNode* root) {
if(root == nullptr)
return;
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
{
TreeNode* pTemp = s.top();
s.pop();
std::cout<<pTemp->iValue<<std::endl;
if(pTemp->pRight != nullptr)
{
s.push(pTemp->pRight);
}
if(pTemp->pLeft != nullptr)
{
s.push(pTemp->pLeft);
}
}
}
中序遍历
先中序遍历左子树,然后访问根节点,再中遍历右子树。代码看另一篇文章:94. 二叉树的中序遍历
后续遍历
先后续遍历左子树,后续遍历右子树,最后访问根节点。
递归
void preorderTraversal(TreeNode* root) {
if(root == nullptr)
return;
preorderTraversal(root->pLeft);
preorderTraversal(root->pRight);
std::cout << root->iValue << std::endl;
}
迭代
prev记录前一个访问节点,判断当前节点的前一个访问的节点是否是该节点的右节点,如果是则访问该节点,否则,将该节点压入栈。
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if (root == nullptr) {
return res;
}
stack<TreeNode *> stk;
TreeNode *prev = nullptr;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.emplace(root);
root = root->left;
}
root = stk.top();
stk.pop();
if (root->right == nullptr || root->right == prev) {
res.emplace_back(root->val);
prev = root;
root = nullptr;
} else {
stk.emplace(root);
root = root->right;
}
}
return res;
}
};
广度优先遍历(BFS)
广度优先遍历会把当前节点的所有子节点优先遍历,也即层次遍历。可借助队列实现。
void Traversal(TreeNode* root) {
if(root == nullptr)
return;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
TreeNode* pTemp = q.front();
q.pop();
cout<<pTemp->iValue<<endl;
if(pTemp->pLeft != nullptr)
{
q.push(pTemp->pLeft);
}
if(pTemp->pRight != nullptr)
{
q.push(pTemp->pRight);
}
}
}