二叉树遍历 非递归 C++实现代码

下面我就来详细讲解一下“二叉树遍历 非递归 C++实现代码”的完整攻略。

标题

问题描述

在实现二叉树的遍历时,可以用递归方法实现。但是递归方法的缺点在于会占用过多的栈空间。因此,我们需要一种非递归的方法来遍历二叉树,以节省空间。请你给出实现这些方法的C++代码。

解答方法

在非递归方法的实现中,需要用到栈来保存节点。我们可以将树的根节点压入栈中,然后弹出根节点,将其右节点和左节点依次压入栈中。这样就能实现二叉树的前序遍历。

而中序遍历,则是先将根节点入栈,然后一路向左找到最左的节点。弹出最左节点并输出,再查找该节点的右子树。如果存在右子树,则入栈继续查找最左节点。依次重复以上步骤,直到栈为空。

后序遍历,则需要用到两个栈。第一个栈的实现方式同前序遍历。我们可以将每次弹出的节点压入第二个栈中。当第一个栈为空时,说明二叉树已经遍历完成。这时我们就可以输出第二个栈的元素。因为第二个栈中的元素是我们实际需要输出的遍历结果。

解答代码

下面是C++实现二叉树全遍历的代码。代码中Tree类型需要根据具体的情况进行修改。

// 非递归方式实现前序遍历
void preOrderTraversal(Tree *root)
{
    if (root == nullptr) return;
    stack<Tree*> s;
    s.push(root);
    Tree *cur;
    while (!s.empty()) {
        cur = s.top();
        s.pop();
        cout << cur->val << " ";
        if (cur->right) s.push(cur->right);
        if (cur->left) s.push(cur->left);
    }
}

// 非递归方式实现中序遍历
void inOrderTraversal(Tree *root)
{
    if (root == nullptr) return;
    stack<Tree*> s;
    Tree *cur = root;
    while (cur || !s.empty()) {
        if (cur) {
            s.push(cur);
            cur = cur->left;
        } else {
            cur = s.top();
            s.pop();
            cout << cur->val << " ";
            cur = cur->right;
        }
    }
}

// 非递归方式实现后序遍历
void postOrderTraversal(Tree *root)
{
    if (root == nullptr) return;
    stack<Tree*> s1;
    stack<Tree*> s2;
    s1.push(root);
    Tree *cur;
    while (!s1.empty()) {
        cur = s1.top();
        s1.pop();
        s2.push(cur);
        if (cur->left) s1.push(cur->left);
        if (cur->right) s1.push(cur->right);
    }
    while (!s2.empty()) {
        cur = s2.top();
        s2.pop();
        cout << cur->val << " ";
    }
}

示例说明

假设给定二叉树如下所示,使用上述的遍历方式,得到的结果如下:

Tree *root = new Tree(1);
root->left = new Tree(2);
root->left->left = new Tree(4);
root->left->right = new Tree(5);
root->right = new Tree(3);
root->right->left = new Tree(6);
root->right->right = new Tree(7);

preOrderTraversal(root);
// 输出结果:1 2 4 5 3 6 7

inOrderTraversal(root);
// 输出结果:4 2 5 1 6 3 7

postOrderTraversal(root);
// 输出结果:4 5 2 6 7 3 1

另外,为了进一步说明非递归遍历的实现方法,我们给出一个带注释的具体例子:

void inOrderTraversal(Tree *root)
{
    if (root == nullptr) return;
    stack<Tree*> s;
    Tree *cur = root;
    while (cur || !s.empty()) { // (1)
        if (cur) { // (2)
            s.push(cur); // 将当前节点压栈
            cur = cur->left; // 查找左子树
        } else {
            cur = s.top(); // 弹出栈中的元素
            s.pop();
            cout << cur->val << " "; // 输出当前节点
            cur = cur->right; // 查找右子树
        }
    }
}

以上代码中,注释部分标记了整个过程中的重点步骤。使用具体示例来进行理解和实践是非常有帮助的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:二叉树遍历 非递归 C++实现代码 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 批处理入门与提高

    批处理入门与提高完整攻略 什么是批处理? 批处理是一种批量处理计算机操作的方式。它可以自动化重复性任务,提高工作效率。 如何写批处理脚本? 使用记事本或其他文本编辑器编写批处理脚本,文件扩展名为”.bat”或”.cmd”。以下是一个简单的批处理脚本示例: @echo off echo Hello World! pause 运行效果为,在命令行中输入脚本名称,…

    other 2023年6月26日
    00
  • otg无法识别u盘无法弥补储存容量不足情况的解决方法

    OTG无法识别U盘及储存容量不足的解决方法 在使用移动设备时,我们经常会使用OTG功能连接U盘,然而有时会发现OTG无法识别U盘的情况,同时会遇到储存容量不足的问题。这个问题可以通过以下的方法解决。 解决OTG无法识别U盘的方法 1. 检查OTG线及U盘 首先,需要检查OTG线及U盘是否损坏或者接触不良。可以更换一个新的OTG线和U盘进行测试。 2. 更换O…

    other 2023年6月27日
    00
  • 苹果电脑的Mac系统安装应用程序(软件)的方法(图文教程)

    苹果电脑的Mac系统安装应用程序(软件)的方法(图文教程) 1. 从App Store下载安装 步骤如下: 打开App Store 在搜索框中输入软件名称或关键字 找到相应的软件,然后点击“获取”或“安装”按钮 输入Apple ID和密码进行确认 下载完成后,在“启动台”中找到并打开软件 示例说明1:下载并安装“Pages” 打开App Store 在搜索框…

    other 2023年6月25日
    00
  • securecrt(CRT)导入会话

    SecureCRT(CRT)导入会话 SecureCRT是一款非常流行的Windows SSH和Telnet客户端,使用它可以与远程服务器进行命令行交互。在使用SecureCRT时,我们通常需要导入远程服务器的会话配置,以便快速连接到远程终端。 本文将介绍如何通过SecureCRT导入会话配置文件,并讲解如何在导入过程中遇到的常见问题的解决方案。 步骤一:打…

    其他 2023年3月28日
    00
  • Android自定义流式布局/自动换行布局实例

    Android自定义流式布局/自动换行布局实例攻略 在Android开发中,有时我们需要实现一种自定义的布局,能够自动换行并适应不同的屏幕尺寸。这种布局被称为流式布局或自动换行布局。下面是一个详细的攻略,包含两个示例说明。 步骤1:创建自定义布局类 首先,我们需要创建一个自定义的布局类,继承自ViewGroup。这个类将负责管理子视图的位置和大小。 publ…

    other 2023年9月5日
    00
  • C++类与对象的详细说明2

    C++类与对象的详细说明2 1. 构造函数和析构函数 1.1 构造函数 构造函数是一种特殊的成员函数,它会在对象被创建时自动调用。构造函数可以用来初始化类的成员变量,或进行一些必要的初始化操作。在C++中,类可以拥有多个构造函数,这些构造函数的名称与类名相同,但可以拥有不同的参数列表。 下面是一个简单的示例代码,展示了如何声明和定义一个构造函数: class…

    other 2023年6月26日
    00
  • Linux系统如何安装和使用shell编写的工具supportconfig

    以下是安装和使用shell编写的工具supportconfig的详细攻略: 安装supportconfig工具 打开终端或命令行界面。 使用包管理器(如apt、yum或zypper)安装supportconfig工具。以下是几个常用Linux发行版的安装命令示例: Ubuntu/Debian: sudo apt-get install supportconf…

    other 2023年10月16日
    00
  • 详解C语言中的符号常量、变量与算术表达式

    详解C语言中的符号常量、变量与算术表达式 符号常量 在C语言中,符号常量是指在程序中使用的固定值,其值在程序运行过程中不会改变。符号常量可以通过使用#define预处理指令来定义。 示例1:定义一个表示圆周率的符号常量 #define PI 3.14159 示例2:定义一个表示年份的符号常量 #define YEAR 2023 变量 变量是在程序中用于存储和…

    other 2023年8月16日
    00
合作推广
合作推广
分享本页
返回顶部