二叉树的四种遍历算法

article/2025/10/8 17:50:41

二叉树作为一种重要的数据结构,它的很多算法的思想在很多地方都用到了,比如STL算法模板,里面的优先队列、集合等等都用到了二叉树里面的思想,先从二叉树的遍历开始:

看二叉树长什么样子:

我们可以看到这颗二叉树一共有七个节点

0号节点是根节点

1号节点和2号节点是0号节点的子节点,1号节点为0号节点的左子节点,2号节点为0号节点的右子节点

同时1号节点和2号节点又是3号节点、四号节点和五号节点、6号节点的双亲节点

五号节点和6号节点没有子节点(子树),那么他们被称为‘叶子节点’

这就是一些基本的概念

二叉树的遍历

二叉树常用的遍历方式有:前序遍历、中序遍历、后序遍历、层序遍历四种遍历方式,不同的遍历算法,其思想略有不同,我们来看一下这四种遍历方法主要的算法思想:

1、先序遍历二叉树顺序:根节点 –> 左子树 –> 右子树,即先访问根节点,然后是左子树,最后是右子树。 
上图中二叉树的前序遍历结果为:0 -> 1 -> 3 -> 4 -> 2 -> 5 -> 6

2、中序遍历二叉树顺序:左子树 –> 根节点 –> 右子树,即先访问左子树,然后是根节点,最后是右子树。 
上图中二叉树的中序遍历结果为:3 -> 1 -> 4 -> 0 -> 5 -> 2 -> 6

3、后续遍历二叉树顺序:左子树 –> 右子树 –> 根节点,即先访问左子树,然后是右子树,最后是根节点。 
上图中二叉树的后序遍历结果为:3 -> 4 -> 1 -> 5 -> 6 -> 2 -> 0

4、层序遍历二叉树顺序:从最顶层的节点开始,从左往右依次遍历,之后转到第二层,继续从左往右遍历,持续循环,直到所有节点都遍历完成 
上图中二叉树的层序遍历结果为:0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6

下面是四种算法的伪代码:

前序遍历:

preOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束 cout << tree[n].w ; // 输出当前节点内容     preOrderParse(tree[n].leftChild); // 递归输出左子树 preOrderParse(tree[n].rightChild); // 递归输出右子树 
}

中序遍历:

inOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束 inOrderParse(tree[n].leftChild); // 递归输出左子树 cout << tree[n].w ; // 输出当前节点内容 inOrderParse(tree[n].rightChild); // 递归输出右子树 
}

后序遍历:

pastOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束 pastOrderParse(tree[n].leftChild); // 递归输出左子树 pastOrderParse(tree[n].rightChild); // 递归输出右子树 cout << tree[n].w ; // 输出当前节点内容     
}

可以看到前三种遍历都是直接通过递归来完成,用递归遍历二叉树简答方便而且好理解,接下来层序遍历就需要动点脑筋了,我们如何将二叉树一层一层的遍历输出?其实在这里我们要借助一种数据结构来完成:队列。 
我们都知道,队列是一种先进先出的数据结构,我们可以先将整颗二叉树的根节点加入队尾,然后循环出队,每次读取对头元素输出并且将队头元素出队,然后将这个输出的元素节点的的左右子树分别依次加入队尾,重复这个循环,知道队列为空的时候结束输出。那么整个二叉树就被我们采用层序遍历的思想输出来了。下面我们看一下上图的二叉树用层序遍历思想的遍历步骤:

对上面的步骤的伪代码实现

while(!que.empty())  {int n = que.front(); // 得到队头元素que.pop();  // 队头元素出队列 // 如果当前节点不为空,那么输出节点的数值,并且在队尾插入左右子节点if(tree[n] != NULL) {cout << tree[n].w;que.push(tree[n].leftChild); que.push(tree[n].rightChild); }
}

这几个遍历算法的最终实现:

/** 二叉树的四种遍历方式,这里没有采用真实的指针去做,* 而是采用数组下标去模拟指针,是一种更加方便快速的方法 */
#include <iostream>
#include <queue> 
using namespace std;
const int N = 10010;
const int INF = -1; // 我们用一个常数来表示当前二叉树节点为空的情况 struct Node {int w; // 当前树节点的值 int p; // 当前树节点的双亲所在数组下标 int l; // 当前树节点的左子节点所在数组下标 int r; // 当前树节点的右子节点所在数组下标 
}; 
Node node[N];// 按照前序遍历二叉树的顺序输入树节点 
void input(int n) {cin >> node[n].w;if(node[n].w == INF) { // 输入 -1 代表当前节点所在子二叉树停止输入 return ;}node[n].p = n / 2;node[n].l = n * 2;node[n].r = n * 2 + 1;input(n*2);input(n*2+1);
}// 前序遍历二叉树 
void preOrderParse(int n) {if(node[n].w == INF) {return ;}cout << node[n].w << " ";preOrderParse(node[n].l);preOrderParse(node[n].r);
} // 中序遍历二叉树 
void inOrderParse(int n) {if(node[n].w == INF) {return ;}inOrderParse(n*2);cout << node[n].w << " ";inOrderParse(n*2+1); 
}// 后续遍历二叉树 
void postOrderParse(int n) {if(node[n].w == INF) {return ;}postOrderParse(n*2);postOrderParse(n*2+1); cout << node[n].w << " ";
} /* * 层序遍历二叉树,这里采用的是 C++ STL 模板的提供的队列(queue),* 并没有自己去实现一个队列*/ 
void sequenceParse() {queue<int> que;int n = 1;que.push(1); // 插入根节点所在数组下标 while(!que.empty()) {n = que.front();que.pop(); // 得到队头元素并且将队头元素出队列 // 如果当前节点不为空,那么输出该节点,并且将该节点的左右子节点插入队尾 if(node[n].w != INF) { cout << node[n].w << " ";que.push(node[n].l);que.push(node[n].r);}}
}int main() {cout << "请以前序遍历的顺序输入二叉树,空节点输入 -1 :" << endl; input(1); // 从下标为 1 开始前序输入二叉树 cout << "前序遍历:" << endl; preOrderParse(1); cout << endl << "中序遍历:" << endl;inOrderParse(1);cout << endl << "后序遍历:" << endl;postOrderParse(1); cout << endl << "层序遍历:" << endl;sequenceParse();return 0;
}

 


http://chatgpt.dhexx.cn/article/2Wo37kwA.shtml

相关文章

实现二叉树各种遍历算法

目录 前言一、题目1.二叉树的各种遍历过程及遍历算法设计。2.实现二叉树各种遍历算法 总结 前言 提示&#xff1a;记得关注我哦&#xff01;&#xff01;&#xff01; 一、题目 1.二叉树的各种遍历过程及遍历算法设计。 &#xff08;1&#xff09; 先序遍历二叉树&#xff1…

算法分析之二叉树遍历

算法相关数据结构总结&#xff1a; 序号数据结构文章1动态规划动态规划之背包问题——01背包 动态规划之背包问题——完全背包 动态规划之打家劫舍系列问题 动态规划之股票买卖系列问题 动态规划之子序列问题 算法&#xff08;Java&#xff09;——动态规划2数组算法分析之数…

二叉树遍历算法总结

A. 二叉树的遍历 1.前序遍历二叉树&#xff1a; (1)若二叉树为空&#xff0c;则为空操作&#xff0c;返回空。 (2)访问根结点。 (3)前序遍历左子树。 (4)前序遍历右子树。 a.二叉树前序遍历的递归算法&#xff1a; void PreOrderTraverse(BiTree BT)…

二叉树的遍历算法

遍历是对树的一种最基本的运算&#xff0c;所谓遍历二叉树&#xff0c;就是按一定的规则和顺序走遍二叉树的所有节点&#xff0c;使每一个节点都被访问一次&#xff0c;而且只被访问一次。由于二叉树是非线性结构&#xff0c;因此&#xff0c;树的遍历实质上是将二叉树的各个节…

【算法】二叉树遍历算法总结:前序中序后序遍历

前言 二叉树遍历是非常经典的算法题&#xff0c;也是二叉树的一道基础算法题。 但是在平常的笔试面试中&#xff0c;其出现的频率其实并不是特别的高&#xff0c;我推测是这种题目相对来说比较基础&#xff0c;算是一个基础知识点。 比如剑指offer中出现的后序遍历题目&…

二叉树遍历算法的应用

目录 一、二叉树遍历算法的应用——二叉树的创建 二、二叉树遍历算法的应用——复制二叉树 三、二叉树遍历算法的应用——计算二叉树的深度 四、二叉树遍历算法的应用——计算二叉树节点总数 五、二叉树遍历算法的应用——计算二叉树叶子节点数 一、二叉树遍历算法的应用—…

一文弄懂二叉树的三种遍历方式

关注公众号【高性能架构探索】&#xff0c;后台回复【pdf】&#xff0c;免费获取计算机必备经典书籍 俗话说&#xff1a;学如逆水行舟,不进则退;心似平原走马,易放难收。这句话对程序员而言&#xff0c;体会更深。这行已经越来越卷了&#xff0c;时刻准备着&#xff0c;&#x…

二叉树遍历算法

目录 先序遍历 中序遍历 后序遍历 层序遍历 938. 二叉搜索树的范围和 110. 平衡二叉树 114. 二叉树展开为链表 117. 填充每个节点的下一个右侧节点指针 II 116. 填充每个节点的下一个右侧节点指针 1&#xff0c;三种遍历都是先把二叉树的最左结点循环入栈(DFS迭代)&am…

二叉树的四种遍历算法(结构体数组)

一、二叉树的定义 以字符串的形式定义一棵二叉树的先序序列&#xff0c;若字符是‘#’&#xff0c;表示该二叉树是空树&#xff0c;否则该字符是相应结点的数据元素。 例&#xff1a;ABDG##HI####CE#J##F## 对应的二叉树&#xff1a; 思路讲解&#xff1a; 想要遍历二叉树&am…

二叉树的四种遍历方式

概要 树本身是一种简单化的图 &#xff1b; DFS对应前中后序遍历&#xff0c;BFS对应层序遍历 二叉树结构 struct treenode {int val;treenode *left;treenode *right;treenode() : val(0), left(nullptr), right(nullptr) {}treenode(int x) : val(x), left(nullptr), right(n…

针对Linux学习,值得阅读的五本书籍,不看可能错失机会

今天为了总结一些可以帮助各位在学习过程中提供帮助的一些书籍。 一.鸟叔的私房菜&#xff1a; 本书是知名度颇高的Linux入门书《鸟哥的Linux私房菜基础学习篇》的新版,而详细地介绍了Linux操作系统。全书分为五部分;第一部分部分着重说明计算机的基础知识、Linux的学习方法&a…

从零开始学习Linux(一)关闭虚拟机系统

关闭系统&#xff0c;需要输入如下命令 poweroff然而&#xff0c;你只能得到如下反馈 -bash: poweroff:command not found此项错误是因为poweroff命令是一个系统管理命令。执行此项命令需要高级使用者特权。 因此&#xff0c;为了关闭系统&#xff0c;我们首先需要切换到root…

个人随笔/小白应该如何学习Linux,我的一些心得分享.

大家好&#xff0c;今天给大家分享一下0基础的人如何入门Linux&#xff0c;此文来源&#xff1a;我在上班的路上看到一篇文章&#xff0c;也是写的0基础的人如何学习Linux的文章。当时我在想&#xff0c;我写博文一年多&#xff0c;都是相关Linux及Python等技术的文章&#xff…

Linux学习路线

&#xfeff;&#xfeff; 关于 Linux Linux 因其开源&#xff0c;免费&#xff0c;可裁剪&#xff0c;被应用到很多领域&#xff0c;尤其是嵌入式设备上。 Android 系统内核也是基于 Linux 的。 另外还有各种服务器和工作站也是用的 Linux。 什么是嵌入式设备&#xff1f;…

为什么要学习 Linux ????

目前企业中大量的使用Linux作为服务器&#xff0c;在以后你们就业后&#xff0c;会发现web服务器Tomcat ,jobss这一类都是搭建在linux上面的&#xff0c;后面我们需要学习的数据库mysql &#xff0c; oracle &#xff0c;db2&#xff0c; 或者greenplum这一类的&#xff0c;在企…

Linux 学习路线图

1.应用场景 更加高效地学习并达到运用Linux. 2.学习/操作 linux运维学习需要分为四个阶段&#xff1a;初级入门、中级进阶、高级提升、资深方向细化。 第一阶段&#xff1a;初级入门 初级阶段需要把linux学习路线搞清楚&#xff0c;任何学习都是循序渐进的&#xff0c;所以学…

从零入门机器学习之Linux系统详解

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,科大讯飞比赛第三名,CCF比赛第四名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

为什么要学习Linux?

对于一些偶然接触到Linux的人来说&#xff0c;好奇是对于这个陌生名词的的第一印象。也许这个名字经常出现在你所使用的教科书上&#xff0c;或者是一些技术性的文章上&#xff0c;你却不知其意&#xff0c;此时这个名字再次出现&#xff0c;你就更是好奇了&#xff0c;Linux到…

Linux学习总结

课程&#xff1a;Linux操作系统与应用 参考书&#xff1a;Linux从入门到精通、unix环境高级编程 学习linux之前必须要做好心理准备&#xff1a; 第一&#xff0c;要明白学好linux不是一件一蹴而就的事&#xff0c;一定要能坚持使用它&#xff0c;特别是在使用初期&#xff0c…

你知道如何学习Linux吗?

说起Linux&#xff0c;业内人士或者经常玩电脑&#xff0c;对计算机比较精通的应该是比较熟悉的&#xff0c;Linux是一个开源的操作系统&#xff0c;由于其安全性高&#xff0c;完全免费&#xff0c;高效性&#xff0c;稳定等优点&#xff0c;越来越受大众的欢迎&#xff0c;就…