zoukankan      html  css  js  c++  java
  • 二叉搜索树的先中后序遍历非递归实现

    我们在实现二叉搜索树的先中后序遍历是一般的都是递归的来实现的,现在我们要实现其非递归的版本,核心思想是利用栈来模拟递归中的函数调用,自己来实现模拟递归
    我们先来实现先序遍历————————————
    void PreOrderNotRecursion(BinarySearchTree bst)//二叉查找数的非递归版先序遍历
    {
         std::stack<Position> s;
         s.push(bst);
         while(!s.empty())
         {
              Position pos = s.top();
              s.pop();
              std::cout<<pos->data<<"-";
              if(NULL != pos->right)//如果pos有右儿子就先将其右儿子压入栈中
                   s.push(pos->right);
              if(NULL != pos->left)//如果pos有左儿子就再将其左儿子压入栈中
                   s.push(pos->left);
         }
    }
    然后实现中序遍历————————————————
    void InOrderNotRecursion(BinarySearchTree bst)//二叉查找数的非递归版中序遍历,利用栈来模拟函数递归调用
    {
         std::stack<Position> s;
         while(NULL != bst)//沿着最左的方向将左儿子依次压入栈中
         {
              s.push(bst);
              bst = bst->left;
         }
         while(!s.empty())
         {
              Position pos = s.top();
              s.pop();
              std::cout<<pos->data<<"-";
              if(NULL != pos->right)//pos has right child
              {
                   pos = pos->right;
                   while(NULL != pos)//沿着最左的方向将左儿子依次压入栈中
                   {
                        s.push(pos);
                        pos = pos->left;
                   }
              }
         }
    }
    最后给出后序遍历,在这三个遍历中非递归后序遍历最难实现涉及到栈内的节点的二次访问控制————————
    void PostOrderNotRecursion(BinarySearchTree bst)//二叉查找数的非递归版后序遍历
    {
         std::stack<Position> s;
         std::set<Position> rchild_visited;
         while(NULL != bst)//沿着最左的方向将左儿子依次压入栈中
         {
              s.push(bst);
              bst = bst->left;
         }
         while(!s.empty())
         {
              Position pos = s.top();
              //s.pop();
              if(NULL == pos->right)//pos没有右儿子因此可以直接访问pos
              {
                   std::cout<<pos->data<<"-";
                   s.pop();
              }
              else if(rchild_visited.find(pos) == rchild_visited.end())
              {//pos有右儿子我们不可以访问pos,需要先访问完其右子树后才可访问pos
              //因此要进入其右儿子中递归访问右子树同时标记pos的右儿子已经被我们访问过了
                   rchild_visited.insert(pos);
                   pos = pos->right;
                   while(NULL != pos)//把右子树的根连同其左儿子沿着左儿子的方向依次压入栈中
                   {
                        s.push(pos);
                        pos = pos->left;
                   }
              }
              else if(rchild_visited.find(pos) != rchild_visited.end())
              {//此时pos右儿子已经被访问过了因此我们可以直接访问pos了
                   std::cout<<pos->data<<"-";
                   rchild_visited.erase(pos);
                   s.pop();
              }    
         }
    }
    

      

  • 相关阅读:
    linux---集群架构初探(14)静态、动态、流量术语
    linux---集群架构初探(13)http与www服务基础介绍
    linux---集群架构初探(12)ansible剧本模式(playbook)
    linux---集群架构初探(11) 实践:一键部署nfs
    linux---集群架构初探(10)Ansible常用模块
    试题一 讲解
    aws 试题
    linux 常用命令。
    nohub命令简单介绍。
    Linux 系统conda环境,pip文件的导出和安装。
  • 原文地址:https://www.cnblogs.com/zxh1210603696/p/3231358.html
Copyright © 2011-2022 走看看