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

通俗易懂讲解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日

相关文章

  • 一步一步封装自己的HtmlHelper组件BootstrapHelper(二)

    我来为你详细讲解“一步一步封装自己的HtmlHelper组件BootstrapHelper(二)”的完整攻略。 标题 本攻略总共包含以下几个标题:- 引用相关类库- 封装组件方法- 示例1:使用BootstrapHelper生成表单- 示例2:使用BootstrapHelper生成面板 引用相关类库 在开始封装组件之前,我们需要引用Bootstrap相关类库…

    other 2023年6月25日
    00
  • C/C++中数据类型转换详解及其作用介绍

    C/C++中数据类型转换详解及其作用介绍 前言 在C/C++开发中,数据类型的转换十分普遍。正确地掌握数据类型转换的方法和规则,是写出高效且无bug的代码的重要基础。本文将详细介绍C/C++中数据类型转换的相关知识,并提供实例以加深理解。 数据类型转换方法 C/C++中的数据类型转换主要有两种方法:隐式转换和显式转换。 隐式转换 隐式转换是指在代码中不需要显…

    other 2023年6月26日
    00
  • 讲解Python中for循环下的索引变量的作用域

    讲解Python中for循环下的索引变量的作用域 在Python中,for循环是一种常用的迭代结构,用于遍历可迭代对象(如列表、元组、字符串等)。在for循环中,我们可以使用一个索引变量来追踪当前迭代的位置。然而,需要注意的是,索引变量的作用域在for循环内部。 作用域的概念 作用域是指变量在程序中可访问的范围。在Python中,变量的作用域可以是全局作用域…

    other 2023年8月20日
    00
  • 门户网站构建CSS框架的规则

    门户网站构建CSS框架的规则 1. 目标和原则 在构建门户网站的CSS框架之前,需要明确目标和遵循一些原则:- 可重用性:确保CSS框架的组件和样式能够被多个页面和不同的模块重用。- 可扩展性:使框架能够方便地添加新的组件和样式,以满足未来的需求。- 一致性:保持整个门户网站的外观和样式的一致性,提供统一的用户体验。 2. 架构和命名规则 为了保持CSS框架…

    other 2023年6月28日
    00
  • 我的世界pe0.12.1服务器 我的世界手机版0.12.1服务器大全

    我的世界PE 0.12.1服务器攻略 什么是我的世界PE 0.12.1服务器? “我的世界PE 0.12.1服务器”是指运行在“我的世界手机版”(Minecraft PE)0.12.1版本上的一个服务器环境,可以让你和其他玩家在同一个游戏世界中一起玩耍。 如何连接服务器 要连接一个“我的世界PE 0.12.1服务器”,你需要: 打开“我的世界PE”游戏 选择…

    other 2023年6月27日
    00
  • 在c#中将double转换为int

    在C#中将double转换为int的过程可以使用强制类型转换或者Math类中的Round方法来实现。下面将分别介绍这两种方法,并提供示例说明。 强制类型转换 强制类型转换是将一种数据类型转换为另一种数据类型的方法。在C#中,可以使用强制类型转换将double类型转换为int类型。强制类型转换的语法如下: int intValue = (int)doubleV…

    other 2023年5月8日
    00
  • 关于g++和gcc的相同点和区别详解

    关于g++和gcc的相同点和区别详解 相同点 g++和gcc都是GNU Compiler Collection的组成部分,是一套集成了多种编程语言的编译器。 g++和gcc都支持多种CPU架构,包括x86,ARM和PowerPC等。 g++和gcc都可以编译多种编程语言,包括C,C++,Objective-C,Fortran等。 区别 g++与gcc最大的区…

    other 2023年6月26日
    00
  • 以太坊价格今日行情走势分析_06月27日以太坊最新价格行情美元

    以太坊价格今日行情走势分析 06月27日以太坊最新价格行情美元 以太坊(Ethereum)是一种基于区块链技术的加密货币,它是比特币之后最大的加密货币之一。了解以太坊的价格行情走势对于投资者和交易者来说非常重要。以下是06月27日以太坊的最新价格行情分析。 1. 价格走势分析 以太坊的价格走势可以通过查看历史价格数据和技术指标来进行分析。以下是06月27日以…

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