通俗易懂讲解C语言与Java中二叉树的三种非递归遍历方式

yizhihongxing

通俗易懂讲解C语言与Java中二叉树的三种非递归遍历方式

本文将讲解C语言和Java中二叉树的三种非递归遍历方式:先序遍历、中序遍历和后序遍历。这三种遍历方式分别可以使用栈来实现非递归遍历。下面将详细讲解这三种遍历方式的实现过程。

先序遍历

先序遍历的遍历顺序是中->左->右。实现的过程如下:

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};
struct Stack {
    struct TreeNode** arr;
    int top;
};
struct Stack* createStack(int size) {
    struct Stack* s = (struct Stack*)malloc(sizeof(struct Stack));
    s->arr = (struct TreeNode**)malloc(size * sizeof(struct TreeNode*));
    s->top = -1;
    return s;
}
void push(struct Stack* s, struct TreeNode* node) {
    s->top++;
    s->arr[s->top] = node;
}
struct TreeNode* pop(struct Stack* s) {
    struct TreeNode* node = s->arr[s->top];
    s->top--;
    return node;
}
void preorderTraversal(struct TreeNode* root) {
    if (!root) {
        return;
    }
    struct Stack* s = createStack(1000);
    push(s, root);
    while (s->top >= 0) {
        struct TreeNode* node = pop(s);
        printf("%d->", node->val);
        if (node->right) {
            push(s, node->right);
        }
        if (node->left) {
            push(s, node->left);
        }
    }
}

该函数中的createStack函数为创建一个栈,push函数为入栈操作,pop函数为出栈操作。该函数使用了preorderTraversal函数来实现树的先序遍历。我们首先使用栈将根节点入栈,之后在循环中,每次将栈的顶部节点弹出并打印,如果弹出 node 的右子树不为空,将右节点先入栈,如果弹出 node 的左子树不为空,将左节点后入栈。需要注意的是,我们需要先将右节点入栈,该操作是由栈的特性决定的。

示例:假定创建一个二叉树,根节点为1,左子树为2和3,右子树为4和5。通过前序遍历,输出的结果为1->2->3->4->5->。

中序遍历

中序遍历的遍历顺序是左->中->右。实现的过程如下:

void inorderTraversal(struct TreeNode* root) {
    struct Stack* s = createStack(1000);
    while (root || s->top >= 0) {
        while (root) {
            push(s, root);
            root = root->left;
        }
        root = pop(s);
        printf("%d->", root->val);
        root = root->right;
    }
}

该函数使用了inorderTraversal函数来实现树的中序遍历。递归实现是先访问左子树,再访问根节点,最后访问右子树。非递归实现类似于递归,需要用到一个栈来模拟递归过程,首先将根节点入栈,之后在循环中,当树的左子树不为空时,将左子树入栈,对于每个弹出来的节点,先访问该节点,之后将该节点的右子树入栈。需要注意的是,当树的左子树为空时,需要将栈顶元素弹出并打印,之后访问该弹出元素的右子树。

示例:假定创建一个二叉树,根节点为1,左子树为2和3,右子树为4和5。通过中序遍历,输出的结果为2->1->3->4->5->。

后序遍历

后序遍历的遍历顺序是左->右->中。实现的过程如下:

void postorderTraversal(struct TreeNode* root) {
    struct Stack* s1 = createStack(1000);
    struct Stack* s2 = createStack(1000);
    push(s1, root);
    while (s1->top >= 0) {
        struct TreeNode* node = pop(s1);
        push(s2, node);
        if (node->left) {
            push(s1, node->left);
        }
        if (node->right) {
            push(s1, node->right);
        }
    }
    while (s2->top >= 0) {
        struct TreeNode* node = pop(s2);
        printf("%d->", node->val);
    }
}

该函数使用了postorderTraversal函数来实现树的后序遍历,使用了两个栈。首先将根节点入栈,之后在循环中,每次将栈的顶部节点弹出并入栈s2,如果弹出 node 的左子树不为空,将左节点先入栈,如果弹出 node 的右子树不为空,将右节点后入栈。需要注意的是,栈s2存储的是处理后的节点,所以需要存储两次。

示例:假定创建一个二叉树,根节点为1,左子树为2和3,右子树为4和5。通过后序遍历,输出的结果为2->3->5->4->1->。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:通俗易懂讲解C语言与Java中二叉树的三种非递归遍历方式 - Python技术站

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

相关文章

  • mybatis中文网

    当然,我很乐意为您提供有关“MyBatis中文网”的完整攻略。以下是详细的步骤和两个示例: 1 MyBatis中文网 MyBatis中文网是一个提供MyBatis框架学习资源的网站,包括文档、示例、教程、API等。以下是使用MyBatis中文网的步骤: 1.1 访问MyBatis中文网 首先,您需要访问MyBatis中文网。您可以在浏览器中输入“https:…

    other 2023年5月6日
    00
  • php笔记之:php数组相关函数的使用

    下面是完整攻略: 标题 PHP笔记之:PHP数组相关函数的使用 介绍 在PHP中,数组是一种非常常见的数据类型,在处理数据时使用频率极高。本篇笔记将介绍PHP中与数组相关的函数使用方法,其中包括常用的数组创建、遍历、筛选、排序等操作。 数组创建 创建索引数组 $indexArr = array("apple", "banana&…

    other 2023年6月25日
    00
  • gitstash命令及提交指定文件

    git stash命令及提交指定文件 在使用Git进行版本控制的过程中,我们会经常使用git stash命令暂时保存一些未提交的修改,以便于在后续的开发工作中恢复这些修改。 git stash命令 git stash命令的主要作用是将当前分支中的所有未提交的修改(包括已经被Git跟踪的文件和还未被跟踪的文件)暂时存储起来,并将当前工作目录恢复成上次提交的状态…

    其他 2023年3月29日
    00
  • 详解javascript中offsetleft属性的用法(转)

    详解javascript中offsetLeft属性的用法(转) 在前端开发中,我们经常需要获取页面元素在文档流中的位置信息。其中,offsetLeft属性可用于获取某个 HTML 元素相对与其父元素的左侧偏移量(即元素左边缘与其父元素左边缘之间的距离),并且不考虑边框宽度。本文将详解javascript中offsetLeft属性的用法,为大家讲解如何正确地使…

    其他 2023年3月28日
    00
  • WinHex查找下载器真实下载地址链接的方法图解

    WinHex查找下载器真实下载地址链接的方法图解攻略 WinHex是一款功能强大的十六进制编辑器和数据恢复工具。在使用WinHex查找下载器真实下载地址链接时,可以按照以下步骤进行操作: 步骤一:打开下载器文件 首先,打开下载器文件(通常是一个可执行文件或者一个安装包),在WinHex中选择“文件”菜单,然后选择“打开”选项。在弹出的对话框中,浏览并选择你要…

    other 2023年8月4日
    00
  • 《以太坊 2.0 术语库》信标链、PoS、分片…接触以太坊 2.0 得先理解这些术语

    让我来详细讲解一下以太坊 2.0 的一些关键术语。 1. 信标链 Beacon Chain 信标链(Beacon Chain)是以太坊 2.0 的核心组成部分,它是一条新的区块链,负责协调网络中的 PoS 共识算法和分片技术。在信标链上,每个验证者账户都负责验证一部分交易,并参与共识过程。信标链的引入可以提高以太坊的交易吞吐量和安全性。 例如,假设一个以太坊…

    other 2023年6月27日
    00
  • 利用redis实现聊天记录转存功能的全过程

    以下是利用Redis实现聊天记录转存功能的完整攻略,包含两个示例说明: 1. 创建Redis连接 首先,我们需要使用Redis客户端库连接到Redis服务器。可以使用Python的redis库来实现。以下是一个示例代码: import redis # 创建Redis连接 redis_client = redis.Redis(host=’localhost’,…

    other 2023年10月18日
    00
  • php图片处理函数获取类型及扩展名实例

    PHP图片处理函数获取类型及扩展名实例攻略 在PHP中,可以使用一些内置的图片处理函数来获取图片的类型和扩展名。下面是一个详细的攻略,包含了两个示例说明。 步骤1:使用getimagesize()函数获取图片信息 getimagesize()函数可以获取图片的详细信息,包括类型和扩展名。该函数接受一个参数,即图片的路径,返回一个包含图片信息的数组。 示例代码…

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