C++实现二叉树的递归遍历与非递归遍历

2023-11-05

基本上所有关于二叉树的操作都是基于二叉树的遍历算法来实现的,因此在这里讲一下二叉树的遍历算法,其中包括递归与非递归算法,在算法中用输出节点数据来代替对节点的操作。
首先给出这样一棵数:
这里写图片描述

1、前序遍历
所谓前序遍历就是先对节点数据进行处理,然后才对这个节点的左右子树进行处理。对这棵二叉树的前序遍历结果为:ABDCEFG。
递归:

    void _PreOrder(PNode& pRoot)
    {
        if (pRoot)
        {
            cout << pRoot->_data << " ";
            _PreOrder(pRoot->_LChild);
            _PreOrder(pRoot->_RChild);
        }
    }
    void PreOrder()
    {
        _PreOrder(_pRoot);
        cout << endl;
    }

非递归:
非递归方式需要用到栈,这里给出两种算法:
第一种:

void PreOrder_Nor1()
      {
           if(NULL == _pRoot)
               return;
           stack<pNode> s;
           s.push(_pRoot);
           pNode pTemp = NULL;
           while(!s.empty())
           {
               pTemp = s.top();
               cout<< pTemp->_data << " ";
               s.pop();
               if(NULL != pTemp->_RChild)
                   s.push(pTemp->_RChild);
               if(NULL != pTemp->_LChild)
                   s.push(pTemp->_LChild);
           }
           cout<<endl;
      }

第二种:

      void PreOrder_Nor2()
      {
           if(NULL == _pRoot)
               return;
           stack<pNode> s;
           s.push(_pRoot);
           pNode cur = NULL;
           while(!s.empty())
           {
                   cur = s.top();
                   s.pop();
                   while(cur)
                   {
                       cout<< cur->_data << " ";
                       if(cur->_RChild)
                           s.push(cur->_RChild);
                       cur = cur->_LChild;
                   }
            }
            cout<<endl;
     }

调用三种方法:
这里写图片描述

中序遍历:
中序遍历顺序为左子树->节点->右子树,这棵二叉树的遍历结果为:BDAECFG
递归:

    void _InOrder(PNode& pRoot)
    {
        if (pRoot)
        {
            _InOrder(pRoot->_LChild);
            cout << pRoot->_data << " ";
            _InOrder(pRoot->_RChild);
        }
    }
    void InOrder()
    {
        _InOrder(_pRoot);
        cout << endl;
    }

非递归:

void InOrder_Nor()
{
    if(NULL == _pRoot)
        return;
    stack<pNode> s;
    pNode cur = _pRoot;
    pNode pPre = NULL;
    while(!s.empty() || cur)
    {
        while(cur && cur != pPre)
        {
            s.push(cur);
            cur = cur->_LChild;
        }
        if(s.empty())
            return;
        cur = s.top();
        cout<< cur->_data << " ";
        pPre = cur;
        s.pop();
        cur = cur->_RChild;
    }
    cout<<endl;
}

调用两种中序遍历算法:
这里写图片描述

后序遍历
后序遍历顺序为:左子树->右子树->节点,这棵二叉树的遍历结果为DBEGFCA
递归:

    void _PostOrder(PNode& pRoot)
    {
        if (pRoot)
        {
            _PostOrder(pRoot->_LChild);
            _PostOrder(pRoot->_RChild);
            cout << pRoot->_data << " ";
        }
    }
    void PostOrder()
    {
        _PostOrder(_pRoot);
        cout << endl;
    }

非递归:

      void PostOrder_Nor()
      {
          if(NULL == _pRoot)
              return;
          stack<pNode> s;
          s.push(_pRoot);
          pNode cur = _pRoot->_LChild;
          pNode pPre = NULL;
          while(!s.empty())
          {
              while(cur && cur!= pPre)
              {
                  s.push(cur);
                  cur = cur->_LChild;
              }
              if(s.empty())
                  return;
              cur = s.top();
              if(cur->_RChild && cur->_RChild != pPre)
              {
                  cur = cur->_RChild;
              }
              else
              {
                  cout<< cur->_data << " ";
                  pPre = cur;
                  s.pop();
              }
         }
         cout<<endl;
     }

调用两种方法:
这里写图片描述

层序遍历
层序遍历算法不同于前序、中序、后序算法,层序遍历用递归方式实现比较困难,一般用队列结合循环实现比较简单。其基本思想是从根节点开始一层一层的从上向下遍历,其过程为:
这里写图片描述
因此层序遍历的结果为:ABCDEFG
其代码实现为:

    void LevelOrder()
    {
        queue<PNode> q;
        if (_pRoot)
            q.push(_pRoot);
        while (!q.empty())
        {
            PNode tmp = q.front();
            cout << tmp->_data << " ";
            if (tmp->_LChild)
                q.push(tmp->_LChild);
            if (tmp->_RChild)
                q.push(tmp->_RChild);
            q.pop();
        }
        cout << endl;
    }

遍历结果:
这里写图片描述

算法实现还有待改进,望高手斧正!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++实现二叉树的递归遍历与非递归遍历 的相关文章

  • mariadb数据库简介

    mariadb 默认端口3306 什么是数据库 白话 用来存放数据的仓库 这个仓库只不过是按照一定的数据结构来组织 数据库模型分为三种 层次式数据库 网络式数据库 关系型数据库和非关系数据库 什么是关系型数据库 由很多二维表 x横y竖 组成
  • 天鹰优化器算法(AO)优化的BP神经网络预测,AO-BP回归预测

    清空环境变量 warning off 关闭报警信息 close all 关闭开启的图窗 clear 清空变量 clc 清空命令行 导入数据 P train xlsread data training set B2 G191 T train
  • 搭建Hexo博客中遇到的那些“坑”

    目录 前言 那些 坑 1 运行后网页显示代码 2 部署后提示 ERROR Deployer not found git 3 提示hexo INFO Validating config 4 提示什么我忘记记录下来了 总之是因为版本过低 5 B

随机推荐

  • matlab 如何读入超大文本文件

    通常 简单的 importdata 被大家广泛使用 因其调用简单 使用方便 其格式如下 y importdata path file name txt 可以看出 这个封装好的函数 只要给定文件的路径及文件名就可以顺利成为我们所需的数据 但是
  • 浅谈TCP拥塞控制:慢启动和拥塞避免、快速重传和快速恢复

    目录 1 拥塞的概念 2 流量控制 滑动窗口 3 拥塞控制 3 1 慢启动 3 2 拥塞避免 3 3 快速重传 3 4 快速恢复 声明 以下图片来源于网络 1 拥塞的概念 在这里我引用百度百科上面的概念 拥塞是指到达通信子网中某一部分的分组
  • 【C++】红黑树原理与插入实现(附图解与源码)

    红黑树 一 前言 二 什么是红黑树 1 概念 2 性质 三 构建一个红黑树 1 枚举两种颜色 2 定义红黑树节点 3 搭建红黑树 四 插入 1 查找插入位置 2 调整红黑树 插入时父节点为黑 插入时父节点为红 情况一 情况二 情况三 五 源
  • 【iar编译出现 Error[Pe147]的一种特殊情况:函数返回值与函数声明不一致】

    iar编译出现 Error Pe147 的一种特殊情况 函数返回值与函数声明不一致 错误说明 错误原因 解决方案 错误说明 在实现某一个函数时 定义了一个Struct MidFunT MidFun的局部变量 编译正常 将Struct Mid
  • Python之selenium,使用webdriver模拟登录网站(含验证码)

    一 前言 前段时间做了一个小项目 其中有一段需要自动获取网站后台的数据 但是这个网站没有任何提供给开发者的API 所以只能靠自己去探索 起初想着用发送请求的方式去模拟登陆 获取cookies 从而再获取网站后台数据 但是因为自己太菜了一些原
  • Java Collection源码总结 Collection源码注释翻译和解析中英文对照版

    版本 JDK8 JDK1 8 Collection接口源码重点 1 集合层次结构中的根接口 集合表示一组对象 称为其元素 某些集合允许重复元素 而其他集合则不允许 有些是有序的 有些是无序的 2 该接口类定义了各种规范包括方法规范和抛出异常
  • 形象易懂讲解算法II——压缩感知

    作者 咚懂咚懂咚 链接 https zhuanlan zhihu com p 22445302 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 之前曾经写过一篇关于小波变换的回答 能不能通俗的讲解下傅立叶分析
  • STEAM 教育相关书籍

    一 书籍 1 神奇的逻辑思维游戏书 激活5 13岁孩子的逻辑脑 https book douban com review 9776055 2 亚马逊儿童科学工程书NO 1 STEAM KIDS 这本书提供50多个科学 技术 工程 数学和艺术
  • android 自定义图片裁剪,[Android开发]造轮子——自定义图片裁剪工具

    矩形裁剪框 裁剪结果 圆形裁剪框 裁剪结果 自适应 实现的成员比较简单 各个类的职责 ImageTouchView 负责图片的显示 单指移动图片 双指缩放图片 自适应裁剪框 最后根据ClipFrameView的接口获取裁剪框的位置和大小进行
  • Games101 Lecture16 Ray Tracing 4笔记

    直接用大佬笔记 不重复造轮子 当然我也写不出这么详细的笔记 理论 从零开始学图形学 写一个光线追踪渲染器 一 渲染方程与BxDF 从零开始学图形学 写一个光线追踪渲染器 二 微表面模型与代码实现 代码实现 GAMES101 现代计算机图形学
  • Redis 连接命令

    Redis 命令用于在 redis 服务上执行操作 要在 redis 服务上执行命令需要一个 redis 客户端 Redis 客户端在我们之前下载的的 redis 的安装包中 语法 Redis 客户端的基本语法为 启动 redis 客户端
  • ubuntu16.04安装cmake-3.8.1最靠谱的方法(ubuntu下安装指定版本cmke)

    1 问题描述 2 cmake安装五种方法 法一 下载cmake二进制安装包 配置路径 亲测有效 法二 cmake源码编译 注意和法一区别 法三 apt安装 法四 在原基础上升级版本 法五 ppa安装 1 问题描述 在配置OpenMVS时 报
  • 【vue+El-element】实现todolist

    好像拖更了很久 很抱歉 最近想了一下css和js等内容还是不总结了 本来内容就多 不是一篇博客能说完的 而且我也只学了皮毛 以后还是通过实例的方式来分享一下学过的东西 希望能帮到大家 目录 一 实现功能 二 实现方法 1 数据的传递 2 按
  • 'WebDriver' object has no attribute 'error' 问题已解决

    实例化的过程中传错参数所致 将logger的参数传给了driver 将传参的顺序调换即可
  • TensorFlow模型变量重用

    TensorFlow模型变量重用问题 加载模型及检测的 py predict py import numpy as np import tensorflow as tf from PIL import Image import time i
  • 用ST-Link V2烧录器配合arduino IDE给STM32F103C8T6烧写程序以及注意事项

    用ST Link V2烧录器配合arduinoIDE给STM32F103C8T6烧写程序以及注意事项 注意事项 使用ST Link烧录工具烧录的话 默认的串口输出是Serial1 而使用串口工具烧录的话 默认输出串口为Serial 示例程序
  • File类、Directory类、FileInfo、DirectoryInfo类的区别

    1 File 提供用于创建 复制 删除 移动和打开文件的静态方法 并协助创建FileStream对象 if textBox4 Text string Empty MessageBox Show 文件名不能为空 else if File Ex
  • Nginx反向代理可打开首页无法登陆解决

    Nginx安装部署参考 https blog csdn net weixin 45958851 article details 103736418 问题现象 浏览器访问 10 2 55 112 8080 可以打开tomcat首页 登录之后浏
  • 王佩丰excel学习笔记(五):第十五——十八讲

    目录 第十五讲 第十六讲 第十七讲 第十八讲 第十五讲 根据某些条件突出显示单元格 开始 条件格式 突出显示单元格规则 制作数据范围趋势 开始 条件格式 数据条 用于分组统计 插入 切片器 多重条件格式 同一个区域使用多次条件格式 自由度更
  • C++实现二叉树的递归遍历与非递归遍历

    基本上所有关于二叉树的操作都是基于二叉树的遍历算法来实现的 因此在这里讲一下二叉树的遍历算法 其中包括递归与非递归算法 在算法中用输出节点数据来代替对节点的操作 首先给出这样一棵数 1 前序遍历 所谓前序遍历就是先对节点数据进行处理 然后才