开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
深度优先搜索分为先序中序后序(中序和后序的栈操作参考先序遍历),以下作为示例:
先序遍历
先序遍历:节点遍历顺序是根节点--左节点--右节点
栈操作
** 栈中每次弹出访问的是之前最后压入栈的节点**
- 首先,先将根节点1压入栈中,将1弹出栈,访问1节点的左孩子2和右孩子3,此时,要先将右孩子3压入栈中,再将左孩子2压入栈中(因为先压入栈的后出栈后访问,如果后压入左孩子2,那么就会先访问左孩子,保证先遍历左孩子2),此时栈中是【2,3】
- 此时2节点在栈顶,先将2节点弹出栈,再将2节点的右孩子5和左孩子4入栈,此时栈中元素是【4,5,3】
- 此时4节点在栈顶,先将4节点弹出栈,再将4节点的右孩子9和左孩子8入栈,此时栈中元素是【8,9,5,3】
- 此时8节点在栈顶,弹出8节点,访问8节点的左孩子和右孩子,但是8节点的左孩子和右孩子为空,所以此时不压入,此时栈中元素为【9,5,3】
- 此时9节点在栈顶,弹出9节点,访问9节点的左孩子和右孩子,但是9节点的左孩子和右孩子为空,所以此时不压入,此时栈中元素为【5,3】
- 此时5节点在栈顶,弹出5节点,将5节点的右孩子(null)和左孩子10入栈,此时栈中元素是【10,3】
- 此时10节点在栈顶,弹出10节点,但是10节点没有左孩子和右孩子,所以此时不压栈,此时栈中的元素是【3】
- 此时3节点在栈顶,弹出3节点,将3节点的右孩子7和左孩子6入栈,此时栈中元素是【6,7】
- 此时6节点在栈顶,弹出6节点,6没有左右孩子,不压栈,此时栈中元素是【7】
- 此时7节点在栈顶,弹出7节点,7没有左右孩子,不压栈,此时栈为空,循环结束
代码实现
int preorder(TreeNode* root){
//记录节点的输出值
vector<int> res;
if(!root) return {};
else{
res.push_back(root->val);
preorder(root->left);
preorder(root->right);
}
return res;
}
中序遍历
中序遍历:节点实现顺序是左节点--根节点--右节点
代码实现
int inorder(TreeNode* root){
//记录节点的输出值
vector<int> res;
if(!root) return {};
else{
inorder(root->left);
res.push_back(root->val);
inorder(root->right);
}
return res;
}
后序遍历
后序遍历:节点实现顺序是左节点--右节点--根节点
代码实现
int postorder(TreeNode* root){
//记录节点的输出值
vector<int> res;
if(!root) return {};
else{
postorder(root->left);
postorder(root->right);
res.push_back(root->val);
}
return res;
}