遍历与搜索

本文详细介绍了二叉树的深度优先遍历(前序、中序、后序)和广度优先遍历的递归及非递归实现,并探讨了图的深度优先搜索与广度优先搜索。通过实例代码展示了如何利用栈和队列进行遍历操作,是理解数据结构与算法的良好参考资料。
摘要由CSDN通过智能技术生成

一、二叉树的遍历

1.深度优先遍历DFT
在先L后R的前提下:
1)前序遍历V-L-R
2)中序遍历L-V-R(递增序列)
3)后续遍历L-R-V

前序遍历递归方式:

vector<int> res;
vector<int> PreOrderDFS(TreeNode* root) 
{//先序递归遍历
  if(root==nullptr)//递归结束条件
     return;
     
  res.push_back(root->val);  //先访问当前根节点
  PreOrderDFS(root->left);   //再访问当前节点的左子节点及其子树
  PreOrderDFS(root->right);  //最后访问当前节点的右子节点及其子树
  
  return res;
}

中序遍历递归方式:

vector<int> res;
vector<int> InOrderDFS(TreeNode* root) 
{//中序递归遍历
  if(root == nullptr)//结束递归
     return;
     
  InOrderDFS(root->left);   //先访问当前节点的左子节点及其子树
  res.push_back(root->val); //再访问当前节点
  InOrderDFS(root->right);  //最后访问当前节点的右子节点及其子树
  
  return res;
}

后续遍历递归方式:

vector<int> res;
vector<int> PostOrderDFS(TreeNode* root) 
{//后序递归遍历
  if(root == nullptr) //递归结束
     return;
  PostOrderDFS(root->left); //先访问当前节点的左子节点及其子树
  PostOrderDFS(root->right);//再访问当前节点的右子节点及其子树
  res.push_back(root->val); //最后访问当前节点
  
  return res;
}

前序遍历非递归方式:
借助栈来实现,压入顺序为根、右、左
出栈顺序对应为(根、左、右

vetor<int> res;
vector PreOrderDFS(Node* root)          //先打印当前遍历的节点再入栈
{
    stack<Node *> nodeStack;  //使用C++的STL标准模板库:栈
    nodeStack.push(root);     
    while(!nodeStack.empty())
    {
        Node *node = nodeStack.top();
        res.push_back(node->val);        //访问根结点
        nodeStack.pop();
        //前序遍历一定要注意先压入当前节点的右孩子,因为栈是先进后出的结构
        if(node->right)
            nodeStack.push(node->right);  //先将右子树压栈
        if(node->left)
            nodeStack.push(node->left);  //再将左子树压栈
    }
    return res;
}

中序遍历非递归方式:
同样借助栈,需要注意的时进入循环的条件为栈是否为空或根节点是否为NULL,主要思路是首先将左节点入栈,重复该过程,直到左节点不存在,然后依次出栈,出栈的同时判断当前节点的右节点是否存在,若存在则再次进入循环。

vector<int> res;
vector<int> InOrderDFS(Node* root)          
{
     Stack<Node *> stack = nodeStack;
     Node* node = root;
     while (node != nullptr || !nodeStack.empty()) 
     {
         // 把当前节点的所有左子结点压入栈
         while(node != nullptr) 
         {
              nodeStack.push(node);
              node = node->left;
         }
         // 访问节点,处理该节点的右子树
         if(!stack.empty()) 
         {
              node = nodeStack.top();
              res.push_back(node->val);//访问节点
              node = nodeStack.pop();
              
              node = node->right;
         }
    }
    return res;
}

后续遍历非递归方式:
借助前序遍历,前序遍历为根左右,后序遍历为左右根
只需将前序遍历顺序调整为根右左,再reverse翻转一下就可以得到后序遍历

vector<int> res;
vector<int> PostOrderDFS(Node* root)          
{
     Stack<Node *> stack = nodeStack;
     Node* node = root;
     while (node != null || !nodeStack.empty()) 
     {
         Node *node = nodeStack.top();
         res.push_back(node->val);        //访问根结点
         nodeStack.pop();
         //前序遍历一定要注意先压入当前节点的左孩子,因为栈是先进后出的结构
        if(node->left)
            nodeStack.push(node->left);  //先将左子树压栈
        if(node->right)
            nodeStack.push(node->right);  //再将右子树压栈
            
        reverse(res.begin(),res.end());
    }
    return res;
}

2.广度优先遍历BFT(按层)

队列实现:

vector<int> res;
vector<int> BFT(Node* root)
{
    queue<Node *> nodeQueue;  //使用C++的STL标准模板库:队列
    nodeQueue.push(root);     //根节点入队
    while(!nodeQueue.empty())
    {
        Node *node = nodeQueue.front();
        nodeQueue.pop();
        res.push_back(node->val); //访问根节点
        
        if(node->left)
            nodeQueue.push(node->left);  //先将左子树入队
        if(node->right)
            nodeQueue.push(node->right);  //再将右子树入队
    }
    return res;
}

二、图的搜索
1.深度优先搜索DFS(基于前序遍历)
2.广度优先搜索BFS

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值