算法入门之二叉树遍历顺序

二叉树遍历的非递归算法 非递归的算法主要采用的是循环出栈入栈来实现对二叉树的遍历,下面是过程分析 阅读详情

二叉树遍历顺序

四种遍历方式

先/前序遍历、中序遍历、后序遍历、层序遍历

测试二叉树创建

function BinaryTree() {
	this.root = null;
	this.insert = function (key) {
		var node = new BinaryNode(key);
		if (this.root) {
			this._insertNode(node, this.root);
		} else {
			this.root = new BinaryNode(key);
		}
	}
	this._insertNode = function (node, tree) {
		if (node.key < tree.key) {
			if (tree.left) {
				this._insertNode(node, tree.left);
			} else {
				tree.left = node;
			}
		} else {
			if (tree.right) {
				this._insertNode(node, tree.right);
			} else {
				tree.right = node;
			}
		}
	}
	function BinaryNode(key) {
		this.key = key;
		this.left = null;
		this.right = null;
	}
}
var arr = [6, 3, 2, 10, 8, 12, 14];
var binaryTree = new BinaryTree();
arr.forEach(item => {
	binaryTree.insert(item);
});
// console.log(binaryTree.root);

在这里插入图片描述

先/前序遍历

根左右-先访问根节点,然后左子树,最后右子树

在这里插入图片描述

结果是:6, 3, 2, 10, 8, 12, 14

/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @param {Array} arr
 * @return {Array}
 */
function preorder(tree, arr = []) {
	if (tree) {
		arr.push(tree.key);
		preorder(tree.left, arr);
		preorder(tree.right, arr);
	}
	return arr;
}
/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @return {Array}
 */
function preorder(tree) {
	let current = tree;
	const tem = [];
	const res = [];
	while (current || tem.length) {
		while (current) {
			res.push(current.key);
			tem.push(current);
			current = current.left;
		}
        current = tem.pop().right;
	}
	return res;
}

中序遍历

左根右-先访问左子树,然后根节点,最后右子树

在这里插入图片描述

结果是:2, 3, 6, 8, 10, 12, 14

/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @param {Array} arr
 * @return {Array}
 */
function middle(tree, arr = []) {
  if (tree) {
		middle(tree.left, arr);
		arr.push(tree.key);
		middle(tree.right, arr);
	}
	return arr;
}
/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @return {Array}
 */
function middle(tree) {
  let current = tree;
  const tem = [];
  const res = [];
  while (current || tem.length) {
	while (current) {
	  tem.push(current);
	  current = current.left;
	}
    current = tem.pop();
    res.push(current.key);
    current = current.right;
  }
  return res;
}

后序遍历

左右根-先访问左子树,然后右子树,最后根节点

在这里插入图片描述

结果是:2, 3, 8, 14, 12, 10, 6

/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @param {Array} arr
 * @return {Array}
 */
function after(tree, arr = []) {
  if (tree) {
		after(tree.left, arr);
		after(tree.right, arr);
		arr.push(tree.key);
  }
  return arr;
}
/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @return {Array}
 */
function after(tree) {
  let current = tree;
  let last;
  const tem = [];
  const res = [];
  while (current || tem.length) {
    while (current) {
      tem.push(current);
      current = current.left;
    }
    current = tem[tem.length - 1];
    if (current.right && (current.right != last)) {
      current = current.right;
    } else {
      current = tem.pop();
      res.push(current.key);
      last = current;
      // 能走到这里的表示current没有左右子树或者已经放到res,所以设置为null,
      // 不设置会导致第一个while重复遍历,if判断上面赋值current可能为undefined
      current = null; 
    }
  }
  return res;
}

层序遍历

先根节点,然后从上往下每一层从左往右逐层

在这里插入图片描述

结果是:6, 3, 10, 2, 8, 12, 14

/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @param {Array} arr
 * @param {Number} floor
 * @return {Array}
 */
function level(tree, arr = [], floor = 0) {
  if (tree) {
    if (!arr[floor]) {
      arr[floor] = [];
    }
    arr[floor].push(tree.key);
    level(tree.left, arr, floor +1);
    level(tree.right, arr, floor +1);
  }
  return arr;
}
/**
 * @param {BinaryNode} tree
 * @return {Array}
 */
function levelEach(tree) {
  let res = [];
  const levelArr = level(tree);
  levelArr.forEach(item => {
    res = [ ...res, ...item ];
  });
  // res = levelArr.flat();
  return res;
}
/**
 * BinaryNode {
 *   key: <Any>
 *   left: <BinaryNode>;
 *   right: <BinaryNode>;
 * }
 * @param {BinaryNode} tree
 * @return {Array}
 */
function level(tree) {
  const res = [];
	if (!tree) return res;
	let floor = 0;
	let current = [tree];
	while (current.length) {
		let tem = [];
		res[floor] = [];
		current.forEach(item => {
			res[floor].push(item.key);
			if (item.left) {
				tem.push(item.left)
			}
			if (item.right) {
				tem.push(item.right)
			}
		});
		floor++;
		current = tem;
	}
	return res;
}
/**
 * @param {BinaryNode} tree
 * @return {Array}
 */
function levelEach(tree) {
  let res = [];
  const levelArr = level(tree);
  levelArr.forEach(item => {
    res = [ ...res, ...item ];
  });
  // res = levelArr.flat();
  return res;
}
结语:

每种遍历提供两种方法,递归和非递归。层序遍历中第二个方法只为打平结果数组。

Morris算法进行二叉树遍历 二叉树作为计算机中的一个重要数据结构,在很多领域都会涉及到,而提到二叉树,我们首先想到的就是其3种遍历方式--前序、中序和后序,对于这3种遍历方式,我们很容易通过使用递归或者迭代(http://blog.youkuaiyun.com/yangfeisc/article/details/44497429)的方式实现,时间复杂度为O(N)。但是这两种实现方式都需要使用堆栈进行节点信息的存储,即空间复杂度也是O(N 阅读详情

相关推荐

二叉树的建立、遍历及其应用(递归建立二叉树,顺序表建立二叉树)

通过二叉树的相关操作深刻理解递归算法以及二叉树的操作算法 最近已经很久没写博客主要是因为没时间,不过最近的这个二叉树我着实又很多的感悟,所以尽管要花时间,我还是想要写下来,希望对大家也有帮助,我会先从二叉树的一些性质讲起,并讲明该性质的作用,最后附上一道综合题及代码详解帮助大家理解 首先是二叉树的性质,及一些重要的算法 1.对于具有n个节点的二叉树,如果按照从上到下从左到右的顺序对所有的节点从零开始顺序编号,则对于i(0<=i<=n)的节点,有: (1)如果i>0,则序号为i的节点的双亲节

莞工杰仔的博客 1557

算法入门一

二叉树创建 function BinaryTree() { this.root = null; this.insert = function (key) { var node = new BinaryNode(key); if (this.root) { this._insertNode(node, this.root); } else { this.root = new BinaryNode(key); }

xiaojinglyd的博客 176

算法分析之二叉树遍历

二叉树的基础知识已经在上一篇文章算法分析之二叉树学习过了,这篇文章主要是二叉树的遍历方式,包括递归和迭代版本。 文章目录一、二叉树的遍历二、二叉树的递归遍历1. 二叉树的前序遍历2. 二叉树的中序遍历3. 二叉树的后序遍历三、二叉树的迭代遍历1. 二叉树的前序遍历2. 二叉树的中序遍历3. 二叉树的后序遍历四、二叉树的层序遍历1. 层序遍历的迭代实现2. leetcode关于层序遍历的算法107. 二叉树的层序遍历 II199. 二叉树的右视图 一、二叉树的遍历 二叉树的遍历方式主要有两种: 深度优先遍历

小朱小朱绝不认输的博客 3371

二叉树的各种基本运算

二叉树的各种基本运算 码文不易,如果帮助到您,希望您可以下载一个压缩包,与您无害,与我有益谢谢 支持原创 。   欢迎大家阅读我的博客,如果有错误请指正,有问题请提问,我会尽我全力改正错误回答问题。在次谢谢大家。   在计算机科学中,二叉树(英语:Binary tree)是每个节点最多只有两个分支(不存在分支度大于2的节点)的树结构。通常分支被称作“左子树”和“右子树”。二...

Paradox 1万+

从ViT到Swin Transformer:一文搞懂Transformer在CV中的进化史(附实战代码)

本文系统梳理了Transformer在计算机视觉领域的演进历程,从开创性的Vision Transformer(ViT)引入全局注意力机制,到DETR实现端到端目标检测,再到里程碑式的Swin Transformer通过滑动窗口和层次化设计高效桥接CNN与ViT。文章深入剖析了各模型的核心思想、技术突破与实战应用,并提供了可运行的代码示例,帮助读者从理论到实践全面掌握这一关键技术脉络。

cola5的博客 712

汽车级智能栅极驱动器深度解析 | 连载01:DRV871x-Q1系列产品架构与核心特性

集成度:单芯片集成多通道驱动器、电源管理、电流检测智能化:自适应控制算法,减少外部元件可靠性:多重保护机制,满足汽车级要求灵活性:SPI和硬件两种接口,适应不同应用需求。

VehSwHwDeveloper的博客 1150

二叉树的基本运算

上一讲我们已经讲了创建二叉树,所以这一讲,我们来说一下二叉树的基本运算方法,为以后二叉树的运用打下基础:(1)查找节点FindNode(*b,x):(2)找孩子节点LchildNode§和Rchild-Node§:(3)求高度BTNodeDepth(*b):(4)输出二叉树DispBTNode(*b):如上图,就是我们举的例子:我们定义的二叉树节点结构如下: (1)查找节点 FindNode(*b,x) •找到值为x的节点后返回节点指针,否则返回NULL•用递归算法,采用"根-左子树-右子树"的顺序,查找值

qq_57484399的博客 2535

Labview_DQMH框架学习1--浅析

本文主要结合一个相对容易理解的例子,阐述 DQMH 框架的工作原理,希望对初学者有一定的帮助。

hrbeuxn的博客 3048

[算法]二叉树的遍历:前序,中序与后序

二叉树的遍历是二叉树的众多算法的基础。主要有,前序,中序与后序。

绝知此事要躬行 9410

Modbus 通信协议详解

Modbus是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的,是全球第一个真正用于工业现场的总线协议。ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。为更好地普及和推动Modbus在基于以太网上的分布式应用,目前施耐德公司已将Modbus协议的所有权移交给 IDA(,分布式自动化接口)组织,并成立了 Modbus-IDA 组织。

Projectsauron 的博客 7万+

手把手教你用gym训练宇树GO2机器人模型(附完整配置文件)

本文提供了一份详细的实战指南,教你如何使用Gym框架为宇树GO2四足机器人搭建强化学习训练环境。文章深入解析了环境配置、参数调试、奖励函数设置等关键步骤,并分享了避开常见陷阱的经验,旨在帮助开发者高效完成模型训练。

oo7890的博客 322

二叉树三种遍历顺序

三.二叉树的三种遍历方式 1.先序遍历:按照根节点->左子树->右子树的顺序访问二叉树 先序遍历:(1)访问根节点;(2)采用先序递归遍历左子树;(3)采用先序递归遍历右子树; (注:每个节点的分支都遵循上述的访问顺序,体现“递归调用”) 先序遍历结果:A BDFE CGHI 思维过程:(1)先访问根节点A, (2)A分为左右两个子树,因为是递归调用,所以左子树也遵循“先根节点-再左-再右”的顺序,所以访问B节点, (3)然后访问D节点, (4)访问F节点的时候有分支.

m0_37111190的博客 6559

Python 爬虫实战:知网论文数据爬取(题录 / 摘要 / 引用提取 + Excel 结构化)

在学术研究中,获取准确且全面的文献数据是至关重要的。知网(CNKI)作为国内最大的学术文献数据库,拥有海量的论文资源。通过 Python 爬虫技术,我们可以高效地从知网爬取论文数据,包括题录、摘要和引用信息,并将这些数据结构化存储到 Excel 文件中,方便后续的学术分析和研究。

yansideyucsdn的博客 1748

算法基础11 —— 树入门(树的相关术语 + 二叉树的性质 + 顺序及链式存储 + 二叉树的遍历)

树?盆栽? 下图是一棵典型的树 数据结构中的树长这样:(不像树?倒过来看看?) 树的相关术语 一棵树是由n(n>0)个元素组成的有限集合,其中: 结点:每个元素称为结点(node) 根:每棵树有一个特定的结点,称为根结点(root),如上图的结点 ① 子树:除根结点外,其余结点能分成多个互不相交的有限集合,其中每个子集又都是一棵树,这些集合称为这棵树的子树。 性质一:一棵树中的任意两个结点有且仅有唯一的一条路径连通。 性质二:一棵树如果有n个结点,那么它一定恰好有n-1条边

smallrain6的博客 707

摩尔线程嵌入式面试题及参考答案(2万字长文)

说一下你对 drm 框架的理解。 DRM(Direct Rendering Manager)是 Linux 系统中用于管理图形显示设备的一个重要框架。 从架构层面来讲,它处于内核空间,主要目的是为用户空间的图形应用程序提供一个统一的接口来访问图形硬件。DRM 包括内核态的驱动模块和用户态的库。内核态的驱动负责和硬件进行交互,比如对显存的管理、硬件寄存器的配置等。用户态的库则方便应用程序利用内核态提供的功能进行图形渲染等操作。 在图形显示的具体流程中,DRM 可以控制显示设备的分辨率、刷

大模型大数据攻城狮的专栏 1228

头歌OpenGauss数据库-G.视图的使用

OpenGauss数据库-G.视图的使用

python一生之敌的博客 1383

二叉树的前序,中序,后序遍历的非递归写法

二叉树的前序,中序,后序遍历的非递归写法

向未来❀去探索 的博客 1229

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

算法之二叉树各种遍历

树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用。 二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;深度

落日小屋 20万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

先序遍历的顺序建立二叉链表&&中序遍历二叉树T的递归算法

【算法步骤】 扫描字符序列,读入字符ch. 如果ch是一个“#”字符,则表明该二叉树为空数,即T为NULL;否则执行以下操作。 申请一个节点空间T。 将ch赋给T->date。 递归创建T的左子数。 递归创建T的左子数。 创建二叉链表如图所示: 代码如下: #include <iostream> using namespace std; typedef struct BiNode { char date; //二叉链表的定义 struct BiNode *lchi

qq_47142993的博客 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

入门数据结构JAVADS——如何通过遍历顺序构建二叉树

入门数据结构JAVA DS——二叉树的介绍 (构建,性质,基本操作等) (1)-优快云博客在上一篇博客中,笔者讲过,如果告诉你遍历顺序,是可以通过算法构建出二叉树的,这篇博客就是补充,笔者想具体的阐述一下 "告诉遍历顺序从而构建二叉树" 算法.

cjejwe的博客 1719

C++实现二叉树链表存储结构先中后序遍历的递归算法和非递归算法和顺序存储完全二叉树

实验四 二叉树 1.实验目的 (1)掌握二叉树的结构特性和二叉链表存储结构; (2)理解二叉树、完全二叉树、满二叉树的概念和存储特点; (3)掌握二叉树遍历的递归和非递归方法。 2.实验内容 (1)假设二叉树采用链接存储方式存储,分别编写一个二叉树先序遍历的递归算法和非递归算法。 (2)一棵完全二叉树以顺序方式存储,设计一个递归算法,对该完全二叉树进 行中序遍历。 3.解题思路 (1)采用扩展二叉树的先序遍历序列来建立一棵二叉树,如图 4-1(a)所示的一棵 二叉树,其扩

呵呵哒!的博客 5599

二叉树遍历非递归算法

•三种遍历​ • 先序遍历: 根节点–>左子树–>右子树​ • 中序遍历: 左子树–>根节点–>右子树​ • 后序遍历: 左子树–>右子树–>根节点•两类算法​ • 递归算法(具体看我上一篇文章)​ ♥直观,易读​ ♥效率低下​ • 非递归算法​ ♥ 如果一个算法可以使用递归或循环来进行完成,在不影响代码阅读的情况下,可以使用循环,来降低复杂度。下面介绍二叉树的遍历,把用。

qq_57484399的博客 6183

二叉树各种遍历算法 Java 实现总结

PS: 作者是正在学习Java的小白,在这里会总结一些与Java相关知识(Java代码实现),如有不足,欢迎前来讨论指正,十分感谢 !!! 目录二叉树各种遍历算法 Java 实现总结0 二叉树简述0.0 概述0.1 分类0.2 数据结构1 二叉树的遍历1.1 前序遍历1.2 中序遍历1.3 后序遍历1.4 层序遍历1.5 小总结 二叉树各种遍历算法 Java 实现总结 0 二叉树简述 0.0 概述 二叉树是树的特殊一种,具有如下特点: 1、每个结点最多有两颗子树,结点的度最大为2。 2、左子树和右子树是有顺

qq_41866626的博客 8181

二叉树的创建和遍历

二叉树的创建可以选择顺序存储方式创建二叉树和链式存储方式创建二叉树。我们为了创建一棵完整的二叉树,需要对普通的二叉树进行拓展,如图所示:其实建立二叉树也是利用了递归的原理。只不过在原来应该是打印结点的地方,改成了生成结点,给结点赋值的操作而已。大家可以先看后面的二叉树的遍历,再来看二叉树的创建。

zuojiejie的博客 7472

二叉树的遍历的递归与非递归算法

看了以上三种方式遍历二叉树的例子,应该就能明白三种遍历方式的本质与区别,其实我们可以看出,无论以何种方式,我们只要把握好访问的顺序,并且将每一个根结点下的子树都看成一个新树,再按照某种遍历方式访问这个这个新树即可!例子:中缀表达式转后缀表达式;(前缀表达式:波兰表达式;后缀表达式:逆波兰表达式)前缀表达式:-+a*bc/de(也就是以先序遍历访问上述二叉树的顺序)中缀表达式:a+b*c-d/e(也就是以中序遍历访问上述二叉树的顺序)

cx330的博客 2380
上一篇: loadmap
下一篇: 小程序使用socket.io
xiaojinglyd
博客等级 码龄9年 6粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值