二叉树作为一种重要的数据结构,它的很多算法的思想在很多地方都用到了,比如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;
}

二叉树的四种遍历算法相关推荐

  1. 二叉树的四种遍历方式

    二叉树的四种遍历方式: 二叉树的遍历(traversing binary tree)是指从根结点出发,按照某种次序依次访问二叉树中所有的结点,使得每个结点被访问依次且仅被访问一次. 四种遍历方式分别为 ...

  2. 二叉树的四种遍历方法(前序遍历、中序遍历、后序遍历、层序遍历)有图有真相!!!

    文章目录 二叉树的四种遍历方式 前序遍历(Preorder Traversal) 中序遍历(Inorder Traversal) 后序遍历(Postorder Traversal) 层序遍历(Leve ...

  3. 二叉树的四种遍历方式——前序、中序、后序、层序遍历(递归+非递归实现)

    如果N代表根节点,L代表根节点的左子树,R代表根节点的右子树,则根据遍历根节点的先后次序有以下遍历方式: 1. NLR:前序遍历(Preorder Traversal 亦称先序遍历)--访问根结点-- ...

  4. 二叉树的四种遍历方式(前序遍历、中序遍历、后序遍历、测层序遍历)

    一.二叉树的遍历 遍历是数据结构中的常见的操作,把所有元素都访问一遍. 线性数据结构的遍历比较简单 ①.正序遍历 ②.逆序遍历 根据节点访问顺序的不同,二叉树的常见遍历方式用四种 ①.前序遍历(Pre ...

  5. 二叉树的四种遍历方式(递归和非递归双重实现)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  6. C++ 二叉树实现及四种遍历算法(Basic Realization of the BinaryTree Template class)

    Basic Realization of the BinaryTree 环境: Codeblocks 实现二叉树展示: 头文件 main.cpp //Written by Xuebi //本程序先构建 ...

  7. 二叉树性质 四种遍历方式

    二叉树基本概念: 每个结点最多有两棵子树,左子树和右子树(有左右之分) 性质: 二叉树的第n层上最多有2^(n-1)个元素 高度为h的二叉树最多有2^h-1个结点 设一棵二叉树的叶子节点数为a,度为2 ...

  8. 二叉树的四种遍历方法:前序、中序、后序、层次

    前/中/后序遍历也可分别称为前/中/后根遍历 #include <iostream> using namespace std;//二叉树的链式存储的结点 typedef struct Bi ...

  9. 二叉树的四种遍历(非递归)

    class treeNode:def __init__(self, val, left=None, right=None):self.val = valself.left = leftself.rig ...

  10. 二叉树的存储结构及四种遍历(C语言)

    二叉树的存储结构: typedef struct TNode *Position; typedef Position BinTree; /* 二叉树类型 */ struct TNode{ /* 树结点 ...

最新文章

  1. 近一个月的学习总结(4.8—5.12)
  2. 仓库管理常见问题及价值
  3. bat/cmd 抛出错误码和捕获错误
  4. java判断优先级代码_java运算符的优先级
  5. hugo_如何将Hugo用于教室的开源CMS
  6. 1000道Python题库系列分享八(29道)
  7. HealthKit教程 Swift版:锻炼信息
  8. java实现webservice
  9. 计算机技能测试题12答案,计算机基本技能考试选择题及答_计算机一级考试练习题及答案...
  10. android pickerview 多行,Android仿ios条件选择器pickerview
  11. android drawtext换行_Android中用StaticLayout实现文本绘制自动换行详解
  12. FastStone Capture7.0注册码
  13. 【游戏程序设计】鼠标交互
  14. MTCNN论文翻译 人脸检测
  15. 自开发数据可视化平台
  16. stm32—超声波传感器
  17. for the love,for the dream
  18. 巴菲特的获利秘诀——“5+12+8+2”
  19. 计算机老是重启进不了桌面,电脑开机反复重启怎么回事 电脑开机后进不去桌面界面全黑...
  20. PAT (Basic Level) Practise (中文)1062. 最简分数(20)

热门文章

  1. 汽车软件质量体系DIY(1)难题-价值-周期
  2. ABAQUS2018汉化
  3. 安装IBM Data Studio Client
  4. 中国湖北区域汉至现代行政区划GIS数据
  5. C# Winform 开发框架
  6. arr访问绝对地址_ECSHOP源码里的图片的相对地址改为绝对地址 (1)
  7. c语言课程设计--太空战机,基于Funcode平台的软件课程设计
  8. Funcode-贪吃蛇
  9. NPP/VIIRS逐月夜间灯光数据(2012-2020年)
  10. 计算机组成与结构学的是什么内容,计算机组成与体系结构教学大纲.doc