递归实现深度优先搜索

48 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

深度优先搜索分为先序中序后序(中序和后序的栈操作参考先序遍历),以下作为示例:

2020031110270347.png

先序遍历

先序遍历:节点遍历顺序是根节点--左节点--右节点

栈操作

** 栈中每次弹出访问的是之前最后压入栈的节点**

  1. 首先,先将根节点1压入栈中,将1弹出栈,访问1节点的左孩子2和右孩子3,此时,要先将右孩子3压入栈中,再将左孩子2压入栈中(因为先压入栈的后出栈后访问,如果后压入左孩子2,那么就会先访问左孩子,保证先遍历左孩子2),此时栈中是【2,3】
  2. 此时2节点在栈顶,先将2节点弹出栈,再将2节点的右孩子5和左孩子4入栈,此时栈中元素是【4,5,3】
  3. 此时4节点在栈顶,先将4节点弹出栈,再将4节点的右孩子9和左孩子8入栈,此时栈中元素是【8,9,5,3】
  4. 此时8节点在栈顶,弹出8节点,访问8节点的左孩子和右孩子,但是8节点的左孩子和右孩子为空,所以此时不压入,此时栈中元素为【9,5,3】
  5. 此时9节点在栈顶,弹出9节点,访问9节点的左孩子和右孩子,但是9节点的左孩子和右孩子为空,所以此时不压入,此时栈中元素为【5,3】
  6. 此时5节点在栈顶,弹出5节点,将5节点的右孩子(null)和左孩子10入栈,此时栈中元素是【10,3】
  7. 此时10节点在栈顶,弹出10节点,但是10节点没有左孩子和右孩子,所以此时不压栈,此时栈中的元素是【3】
  8. 此时3节点在栈顶,弹出3节点,将3节点的右孩子7和左孩子6入栈,此时栈中元素是【6,7】
  9. 此时6节点在栈顶,弹出6节点,6没有左右孩子,不压栈,此时栈中元素是【7】
  10. 此时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;
}