算法通关村第七关——递归和迭代实现二叉树前中后序遍历

1.递归

1.1 熟悉递归

所有的递归有两个基本特征:

  1. 执行时范围不断缩小,这样才能触底反弹。
  2. 终止判断在调用递归的前面。

写递归的步骤:

  1. 从小到大递推。
  2. 分情况讨论,明确结束条件。
  3. 组合出完整方法。
  4. 想验证就从大到小画图推演。

1.2 递归实现二叉树的前中后序遍历

js 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    const nodeArray = [];
    addNode(root, nodeArray);

    return nodeArray;   
};


function addNode(node, res) {
    if (!node) {
        return res;
    }
    // 前、中、后序遍历只需调换下面三行代码位置
    res.push(node.val);	// 中
    addNode(node.left, res); // 左
    addNode(node.right, res); // 右
}

2.迭代

2.1 迭代实现二叉树前中后序遍历

迭代主要是模拟一个系统栈出来,将节点压入栈中,再取出。前中序遍历容易理解,后序遍历较为复杂,涉及到反转操作。

前序遍历

javascript 复制代码
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
	const nodeQueue = [];

	if (!root) {
		return nodeQueue;
	}

	const nodeStack = [];
	let treeNode = root;

	while (nodeStack.length !== 0 || treeNode) {
		while (treeNode) {
			nodeQueue.push(treeNode.val);
			nodeStack.push(treeNode);
			treeNode = treeNode.left;
		}
		treeNode = nodeStack.pop();
		treeNode = treeNode.right;
	}
    return nodeQueue;  
};

中序遍历

javascript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
	const nodeQueue = [];
	const nodeStack = [];

	if (!root) {
		return nodeQueue;
	}

	let treeNode = root;
	while (nodeStack.length !== 0 || treeNode) {		
		while (treeNode) {
			nodeStack.push(treeNode);
			treeNode = treeNode.left;
		}
		treeNode = nodeStack.pop()
		nodeQueue.push(treeNode.val);
		treeNode = treeNode.right;
	}
	return nodeQueue;
};

后序遍历

分析:

观察后序遍历的结果是:1, 2, 3, 8, 9, 7, 6,如果将其反转的话就是6, 7, 9, 8, 3, 2, 1

反转后的后序遍历与前序遍历相比就是左右 反了。前序遍历是中左右 ,后序遍历是左右中,只要调整前序遍历的左右顺序就可以得到后序遍历。

javascript 复制代码
function postOrderTraversal(root) {
	const nodeQueue = [];
	const nodeStack = [];

	if (!root) {
		return nodeQueue;
	}

	let treeNode = root;

	while (nodeStack.length !== 0 || treeNode) {
		while (treeNode) {
			nodeQueue.push(treeNode.val)
			nodeStack.push(treeNode);
			treeNode = treeNode.right;
		}
		treeNode = nodeStack.pop();
		treeNode = treeNode.left();
	}
	nodeQueue.reverse();   // 将其进行反转
	return nodeQueue;
}
相关推荐
大布布将军6 分钟前
⚡️ 性能加速器:利用 Redis 实现接口高性能缓存
前端·数据库·经验分享·redis·程序人生·缓存·node.js
Change!!9 分钟前
uniapp写的h5,怎么根据页面详情,设置不同的标题
前端·uni-app·标题
聆风吟º9 分钟前
【数据结构手札】顺序表实战指南(三):扩容 | 尾插 | 尾删
数据结构·顺序表·扩容·尾插·尾删
浅箬9 分钟前
uniapp 打包之后出现shadow-grey.png去除
前端·uni-app
资深web全栈开发10 分钟前
LeetCode 2054:两个最好的不重叠活动 —— 从暴力到优化的完整思路
算法·leetcode
IT方大同10 分钟前
数组的初始化与使用
c语言·数据结构·算法
im_AMBER12 分钟前
Leetcode 84 水果成篮 | 删除子数组的最大得分
数据结构·c++·笔记·学习·算法·leetcode·哈希算法
梵得儿SHI13 分钟前
(第五篇)Spring AI 核心技术攻坚:流式响应与前端集成实现【打字机】效果
前端·webflux·springai·流式响应技术·低延迟ai交互·reactive编程原理·streamapi设计
鹏多多15 分钟前
一文搞懂柯里化:函数式编程技巧的解析和实践案例
前端·javascript·vue.js
前端码农一枚24 分钟前
前端打包性能优化全攻略
前端