第七节:二叉树的先序、中序、后续遍历的多种递归写法

一. 先序遍历

1. 题目分析

      根节点→左子树→右子树  (先、中、后 指的是根节点的位置,然后都是先左后右)

      leetcode:https://leetcode.cn/problems/binary-tree-preorder-traversal/

      难度:【简单】

2. 递归的几种写法

     (1). 函数内部声明递归调用的方法

     (2). 函数外部声明递归调用的方法

     (3). 函数自身递归调用了

TreeNode:

class TreeNode {
	val: number;
	left: TreeNode | null;
	right: TreeNode | null;
	constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
		this.val = val === undefined ? 0 : val;
		this.left = left === undefined ? null : left;
		this.right = right === undefined ? null : right;
	}
}

三种递归:


/**
 * 先序遍历-递归写法1
 * (在内部声明递归调用的方法)
 * @param root
 * @returns
 */
function preorderTraversal1(root: TreeNode | null): number[] {
	let result: number[] = [];

	//1. 前置判断
	if (!root) return [];

	//2.递归的方法声明在内部,可以保证result始终是一个
	function traversal(node: TreeNode | null) {
		//1. 递归结束的条件
		if (node === null) {
			return;
		}
		//2. 执行业务
		result.push(node.val);
		//3. 递归调用1
		traversal(node.left);
		//4. 递归调用2
		traversal(node.right);
	}

	//3.调用递归方法
	traversal(root);

	return result;
}

/**
 * 先序遍历-递归写法2
 * (在外部声明递归调用的方法)
 * @param root
 * @returns
 */
function preorderTraversal2(root: TreeNode | null): number[] {
	let result: number[] = [];

	//前置判断
	if (!root) return [];

	//调用递归方法
	traversal(root, result);

	return result;
}

//递归的方法声明在外部,每次都需要将result传入进去,保证是同一个result
function traversal(node: TreeNode | null, result: number[]) {
	//1. 递归结束的条件
	if (node === null) {
		return;
	}
	//2. 执行业务
	result.push(node.val);
	//3. 递归调用1
	traversal(node.left, result);
	//4. 递归调用2
	traversal(node.right, result);
}

/**
 * 先序遍历-递归写法3
 * (自身递归调用)
 * @param root
 * @returns
 */
function preorderTraversal3(root: TreeNode | null): number[] {
	if (root === null) {
		return [];
	}
	const left = preorderTraversal3(root.left);
	const right = preorderTraversal3(root.right);
	return [root.val, ...left, ...right];
}

 

 

二. 中序遍历

1. 题目分析

      左子树→根节点→右子树

      leetcode:https://leetcode.cn/problems/binary-tree-inorder-traversal/description/

      难度:【简单】

2. 递归的几种写法

      同上,下面只写了其中两种代码

2种递归:


/**
 * 中序遍历--递归1
 * (函数内部声明递归方法)
 * @param root 根节点
 * @returns 中序遍历后的数组
 */
function inorderTraversal1(root: TreeNode | null): number[] {
	//1. 前置判断
	if (root === null) return [];

	let res: number[] = [];

	//2. 声明递归方法
	function traversal(node: TreeNode | null) {
		//递归结束条件
		if (node === null) return;

		traversal(node.left);
		res.push(node.val);
		traversal(node.right);
	}

	//3. 调用递归
	traversal(root);

	return res;
}

/**
 * 中序遍历--递归2
 * (函数自身递归)
 * @param root 根节点
 * @returns 中序遍历后的数组
 */
function inorderTraversal2(root: TreeNode | null): number[] {
	//1. 前置判断
	if (root === null) return [];

	//2.递归调用
	let leftNums: number[] = inorderTraversal2(root.left);
	let rightNums: number[] = inorderTraversal2(root.right);

	return [...leftNums, root.val, ...rightNums];
}

 

 

 

 

三. 后续遍历

1. 题目分析

      左子树→右子树→根节点

      leetcode:https://leetcode.cn/problems/binary-tree-postorder-traversal/description/

      难度:【简单】

2. 递归的几种写法

      同上,下面只写了其中两种代码

2种递归:


/**
 * 后序遍历--递归1
 * (自身递归调用)
 * @param root 根节点
 * @returns 中序遍历后的数组
 */
function postorderTraversal(root: TreeNode | null): number[] {
	//1. 前置判断
	if (root === null) return [];

	//2. 递归调用
	let leftNums: number[] = postorderTraversal(root.left);
	let rightNums: number[] = postorderTraversal(root.right);

	return [...leftNums, ...rightNums, root.val];
}

/**
 * 后序遍历--递归2
 * (函数内部声明方法)
 * @param root 根节点
 * @returns 中序遍历后的数组
 */
function postorderTraversal2(root: TreeNode | null): number[] {
	//1. 前置判断
	if (root === null) return [];
	let res: number[] = [];

	//2. 声明递归方法
	function traversal(node: TreeNode | null) {
		//递归结束条件
		if (node === null) return null;

		traversal(node.left);
		traversal(node.right);
		res.push(node.val);
	}

	//3.调用递归方法
	traversal(root);

	return res;
}

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2024-03-19 10:54  Yaopengfei  阅读(7)  评论(1编辑  收藏  举报