先序遍历
题目描述:给定一个二叉树,返回它的前序(先序)遍历序列。 示例: 输入: [1,null,2,3]
1\2/3
输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗?
/*** @param {TreeNode} root* @return {number[]}*/const preorderTraversal = function(root) {// 定义结果数组const res = []// 处理边界条件if(!root) {return res}// 初始化栈结构const stack = []// 首先将根结点入栈stack.push(root)// 若栈不为空,则重复出栈、入栈操作while(stack.length) {// 将栈顶结点记为当前结点const cur = stack.pop()// 当前结点就是当前子树的根结点,把这个结点放在结果数组的尾部res.push(cur.val)// 若当前子树根结点有右孩子,则将右孩子入栈if(cur.right) {stack.push(cur.right)}// 若当前子树根结点有左孩子,则将左孩子入栈if(cur.left) {stack.push(cur.left)}}// 返回结果数组return res};
后序遍历
/*** @param {TreeNode} root* @return {number[]}*/const postorderTraversal = function(root) {// 定义结果数组const res = []// 处理边界条件if(!root) {return res}// 初始化栈结构const stack = []// 首先将根结点入栈stack.push(root)// 若栈不为空,则重复出栈、入栈操作while(stack.length) {// 将栈顶结点记为当前结点const cur = stack.pop()// 当前结点就是当前子树的根结点,把这个结点放在结果数组的头部res.unshift(cur.val)// 若当前子树根结点有左孩子,则将左孩子入栈if(cur.left) {stack.push(cur.left)}// 若当前子树根结点有右孩子,则将右孩子入栈if(cur.right) {stack.push(cur.right)}}// 返回结果数组return res};
中序遍历
/*** @param {TreeNode} root* @return {number[]}*/const inorderTraversal = function(root) {// 定义结果数组const res = []// 初始化栈结构const stack = []// 用一个 cur 结点充当游标let cur = root// 当 cur 不为空、或者 stack 不为空时,重复以下逻辑while(cur || stack.length) {// 这个 while 的作用是把寻找最左叶子结点的过程中,途径的所有结点都记录下来while(cur) {// 将途径的结点入栈stack.push(cur)// 继续搜索当前结点的左孩子cur = cur.left}// 取出栈顶元素cur = stack.pop()// 将栈顶元素入栈res.push(cur.val)// 尝试读取 cur 结点的右孩子cur = cur.right}// 返回结果数组return res};
层序遍历的衍生问题
题目描述:给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。 示例: 二叉树:[3,9,20,null,null,15,7],
3/ \9 20/ \15 7
返回其层次遍历结果: [ [3], [9,20], [15,7] ]
/*** @param {TreeNode} root* @return {number[][]}*/const levelOrder = function(root) {// 初始化结果数组const res = []// 处理边界条件if(!root) {return res}// 初始化队列const queue = []// 队列第一个元素是根结点queue.push(root)// 当队列不为空时,反复执行以下逻辑while(queue.length) {// level 用来存储当前层的结点const level = []// 缓存刚进入循环时的队列长度,这一步很关键,因为队列长度后面会发生改变const len = queue.length// 循环遍历当前层级的结点for(let i=0;i<len;i++) {// 取出队列的头部元素const top = queue.shift()// 将头部元素的值推入 level 数组level.push(top.val)// 如果当前结点有左孩子,则推入下一层级if(top.left) {queue.push(top.left)}// 如果当前结点有右孩子,则推入下一层级if(top.right) {queue.push(top.right)}}// 将 level 推入结果数组res.push(level)}// 返回结果数组return res};
翻转二叉树
题目描述:翻转一棵二叉树。
示例: 输入:
4/ \2 7/ \ / \1 3 6 9
输出:
4/ \7 2/ \ / \9 6 3 1
/*** @param {TreeNode} root* @return {TreeNode}*/const invertTree = function(root) {// 定义递归边界if(!root) {return root;}// 递归交换右孩子的子结点let right = invertTree(root.right);// 递归交换左孩子的子结点let left = invertTree(root.left);// 交换当前遍历到的两个左右孩子结点root.left = right;root.right = left;return root;};
